clang 23.0.0git
CIRGenExprComplex.cpp
Go to the documentation of this file.
1#include "CIRGenBuilder.h"
3#include "CIRGenFunction.h"
4
6
7using namespace clang;
8using namespace clang::CIRGen;
9
10#ifndef NDEBUG
11/// Return the complex type that we are meant to emit.
13 type = type.getCanonicalType();
14 if (const ComplexType *comp = dyn_cast<ComplexType>(type))
15 return comp;
16 return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
17}
18#endif // NDEBUG
19
20namespace {
21class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
22 CIRGenFunction &cgf;
23 CIRGenBuilderTy &builder;
24
25public:
26 explicit ComplexExprEmitter(CIRGenFunction &cgf)
27 : cgf(cgf), builder(cgf.getBuilder()) {}
28
29 //===--------------------------------------------------------------------===//
30 // Utilities
31 //===--------------------------------------------------------------------===//
32
33 /// Given an expression with complex type that represents a value l-value,
34 /// this method emits the address of the l-value, then loads and returns the
35 /// result.
36 mlir::Value emitLoadOfLValue(const Expr *e) {
37 return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());
38 }
39
40 mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
41
42 /// Store the specified real/imag parts into the
43 /// specified value pointer.
44 void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
45 bool isInit);
46
47 /// Emit a cast from complex value Val to DestType.
48 mlir::Value emitComplexToComplexCast(mlir::Value value, QualType srcType,
49 QualType destType, SourceLocation loc);
50
51 /// Emit a cast from scalar value Val to DestType.
52 mlir::Value emitScalarToComplexCast(mlir::Value value, QualType srcType,
53 QualType destType, SourceLocation loc);
54
55 //===--------------------------------------------------------------------===//
56 // Visitor Methods
57 //===--------------------------------------------------------------------===//
58
59 mlir::Value Visit(Expr *e) {
60 return StmtVisitor<ComplexExprEmitter, mlir::Value>::Visit(e);
61 }
62
63 mlir::Value VisitStmt(Stmt *s) {
64 s->dump(llvm::errs(), cgf.getContext());
65 llvm_unreachable("Stmt can't have complex result type!");
66 }
67
68 mlir::Value VisitExpr(Expr *e);
69 mlir::Value VisitConstantExpr(ConstantExpr *e) {
70 if (mlir::Attribute result = ConstantEmitter(cgf).tryEmitConstantExpr(e))
71 return builder.getConstant(cgf.getLoc(e->getSourceRange()),
72 mlir::cast<mlir::TypedAttr>(result));
73
74 cgf.cgm.errorNYI(e->getExprLoc(),
75 "ComplexExprEmitter VisitConstantExpr non constantexpr");
76 return {};
77 }
78
79 mlir::Value VisitParenExpr(ParenExpr *pe) { return Visit(pe->getSubExpr()); }
80 mlir::Value VisitGenericSelectionExpr(GenericSelectionExpr *ge) {
81 return Visit(ge->getResultExpr());
82 }
83 mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);
84 mlir::Value
85 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *pe) {
86 return Visit(pe->getReplacement());
87 }
88 mlir::Value VisitCoawaitExpr(CoawaitExpr *s) {
89 return cgf.emitCoawaitExpr(*s).getComplexValue();
90 }
91 mlir::Value VisitCoyieldExpr(CoyieldExpr *s) {
92 cgf.cgm.errorNYI(s->getExprLoc(), "ComplexExprEmitter VisitCoyieldExpr");
93 return {};
94 }
95 mlir::Value VisitUnaryCoawait(const UnaryOperator *e) {
96 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitUnaryCoawait");
97 return {};
98 }
99
100 mlir::Value emitConstant(const CIRGenFunction::ConstantEmission &constant,
101 Expr *e) {
102 assert(constant && "not a constant");
103 if (constant.isReference())
104 return emitLoadOfLValue(constant.getReferenceLValue(cgf, e),
105 e->getExprLoc());
106
107 mlir::TypedAttr valueAttr = constant.getValue();
108 return builder.getConstant(cgf.getLoc(e->getSourceRange()), valueAttr);
109 }
110
111 // l-values.
112 mlir::Value VisitDeclRefExpr(DeclRefExpr *e) {
113 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(e))
114 return emitConstant(constant, e);
115 return emitLoadOfLValue(e);
116 }
117 mlir::Value VisitObjCIvarRefExpr(ObjCIvarRefExpr *e) {
118 cgf.cgm.errorNYI(e->getExprLoc(),
119 "ComplexExprEmitter VisitObjCIvarRefExpr");
120 return {};
121 }
122 mlir::Value VisitObjCMessageExpr(ObjCMessageExpr *e) {
123 cgf.cgm.errorNYI(e->getExprLoc(),
124 "ComplexExprEmitter VisitObjCMessageExpr");
125 return {};
126 }
127 mlir::Value VisitArraySubscriptExpr(Expr *e) { return emitLoadOfLValue(e); }
128 mlir::Value VisitMemberExpr(MemberExpr *me) {
129 if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {
130 cgf.emitIgnoredExpr(me->getBase());
131 return emitConstant(constant, me);
132 }
133 return emitLoadOfLValue(me);
134 }
135 mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {
136 if (e->isGLValue())
137 return emitLoadOfLValue(cgf.getOrCreateOpaqueLValueMapping(e),
138 e->getExprLoc());
139 return cgf.getOrCreateOpaqueRValueMapping(e).getComplexValue();
140 }
141
142 mlir::Value VisitPseudoObjectExpr(PseudoObjectExpr *e) {
143 cgf.cgm.errorNYI(e->getExprLoc(),
144 "ComplexExprEmitter VisitPseudoObjectExpr");
145 return {};
146 }
147
148 mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);
149 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e) {
150 // Unlike for scalars, we don't have to worry about function->ptr demotion
151 // here.
153 return emitLoadOfLValue(e);
154 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
155 }
156 mlir::Value VisitCastExpr(CastExpr *e) {
157 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e))
158 cgf.cgm.emitExplicitCastExprType(ece);
160 return emitLoadOfLValue(e);
161 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
162 }
163 mlir::Value VisitCallExpr(const CallExpr *e);
164 mlir::Value VisitStmtExpr(const StmtExpr *e);
165
166 // Operators.
167 mlir::Value VisitPrePostIncDec(const UnaryOperator *e) {
168 LValue lv = cgf.emitLValue(e->getSubExpr());
169 return cgf.emitComplexPrePostIncDec(e, lv);
170 }
171 mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
172 return VisitPrePostIncDec(e);
173 }
174 mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
175 return VisitPrePostIncDec(e);
176 }
177 mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
178 return VisitPrePostIncDec(e);
179 }
180 mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
181 return VisitPrePostIncDec(e);
182 }
183 mlir::Value VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); }
184
185 mlir::Value VisitUnaryPlus(const UnaryOperator *e);
186 mlir::Value VisitUnaryPlus(const UnaryOperator *e, QualType promotionType);
187 mlir::Value VisitUnaryMinus(const UnaryOperator *e);
188 mlir::Value VisitUnaryMinus(const UnaryOperator *e, QualType promotionType);
189 mlir::Value VisitUnaryNot(const UnaryOperator *e);
190 // LNot,Real,Imag never return complex.
191 mlir::Value VisitUnaryExtension(const UnaryOperator *e) {
192 return Visit(e->getSubExpr());
193 }
194 mlir::Value VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
195 CIRGenFunction::CXXDefaultArgExprScope scope(cgf, dae);
196 return Visit(dae->getExpr());
197 }
198 mlir::Value VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
199 CIRGenFunction::CXXDefaultInitExprScope scope(cgf, die);
200 return Visit(die->getExpr());
201 }
202 mlir::Value VisitExprWithCleanups(ExprWithCleanups *e) {
203 CIRGenFunction::FullExprCleanupScope scope(cgf, e->getSubExpr());
204 mlir::Value complexVal = Visit(e->getSubExpr());
205 // Defend against dominance problems caused by jumps out of expression
206 // evaluation through the shared cleanup block.
207 scope.exit({&complexVal});
208 return complexVal;
209 }
210 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
211 mlir::Location loc = cgf.getLoc(e->getExprLoc());
212 mlir::Type complexTy = cgf.convertType(e->getType());
213 return builder.getNullValue(complexTy, loc);
214 }
215 mlir::Value VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {
216 mlir::Location loc = cgf.getLoc(e->getExprLoc());
217 mlir::Type complexTy = cgf.convertType(e->getType());
218 return builder.getNullValue(complexTy, loc);
219 }
220
221 struct BinOpInfo {
222 mlir::Location loc;
223 mlir::Value lhs{};
224 mlir::Value rhs{};
225 QualType ty{}; // Computation Type.
226 FPOptions fpFeatures{};
227 };
228
229 BinOpInfo emitBinOps(const BinaryOperator *e,
230 QualType promotionTy = QualType());
231
232 mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
233 mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
234 LValue emitCompoundAssignLValue(
235 const CompoundAssignOperator *e,
236 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &),
237 RValue &value);
238 mlir::Value emitCompoundAssign(
239 const CompoundAssignOperator *e,
240 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &));
241
242 mlir::Value emitBinAdd(const BinOpInfo &op);
243 mlir::Value emitBinSub(const BinOpInfo &op);
244 mlir::Value emitBinMul(const BinOpInfo &op);
245 mlir::Value emitBinDiv(const BinOpInfo &op);
246
247 QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
248 if (auto *complexTy = ty->getAs<ComplexType>()) {
249 QualType elementTy = complexTy->getElementType();
250 if (elementTy.UseExcessPrecision(cgf.getContext()))
251 return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
252 }
253
254 if (ty.UseExcessPrecision(cgf.getContext()))
255 return cgf.getContext().FloatTy;
256 return QualType();
257 }
258
259#define HANDLEBINOP(OP) \
260 mlir::Value VisitBin##OP(const BinaryOperator *e) { \
261 QualType promotionTy = getPromotionType( \
262 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
263 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
264 if (!promotionTy.isNull()) \
265 result = cgf.emitUnPromotedValue(result, e->getType()); \
266 return result; \
267 }
268
269 HANDLEBINOP(Add)
270 HANDLEBINOP(Sub)
271 HANDLEBINOP(Mul)
272 HANDLEBINOP(Div)
273#undef HANDLEBINOP
274
275 mlir::Value VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {
276 cgf.cgm.errorNYI(e->getExprLoc(),
277 "ComplexExprEmitter VisitCXXRewrittenBinaryOperator");
278 return {};
279 }
280
281 // Compound assignments.
282 mlir::Value VisitBinAddAssign(const CompoundAssignOperator *e) {
283 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);
284 }
285 mlir::Value VisitBinSubAssign(const CompoundAssignOperator *e) {
286 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);
287 }
288 mlir::Value VisitBinMulAssign(const CompoundAssignOperator *e) {
289 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);
290 }
291 mlir::Value VisitBinDivAssign(const CompoundAssignOperator *e) {
292 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
293 }
294
295 // GCC rejects rem/and/or/xor for integer complex.
296 // Logical and/or always return int, never complex.
297
298 // No comparisons produce a complex result.
299
300 LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);
301 mlir::Value VisitBinAssign(const BinaryOperator *e);
302 mlir::Value VisitBinComma(const BinaryOperator *e);
303
304 mlir::Value
305 VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
306 mlir::Value VisitChooseExpr(ChooseExpr *e);
307
308 mlir::Value VisitInitListExpr(InitListExpr *e);
309
310 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
311 return emitLoadOfLValue(e);
312 }
313
314 mlir::Value VisitVAArgExpr(VAArgExpr *e);
315
316 mlir::Value VisitAtomicExpr(AtomicExpr *e) {
317 return cgf.emitAtomicExpr(e).getComplexValue();
318 }
319
320 mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {
321 return Visit(e->getSelectedExpr());
322 }
323};
324} // namespace
325
326//===----------------------------------------------------------------------===//
327// Utilities
328//===----------------------------------------------------------------------===//
329
330/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
331/// load the real and imaginary pieces, returning them as Real/Imag.
332mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
333 SourceLocation loc) {
334 assert(lv.isSimple() && "non-simple complex l-value?");
335 if (lv.getType()->isAtomicType())
336 cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
337
338 const Address srcAddr = lv.getAddress();
339 return builder.createLoad(cgf.getLoc(loc), srcAddr, lv.isVolatileQualified());
340}
341
342/// EmitStoreOfComplex - Store the specified real/imag parts into the
343/// specified value pointer.
344void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
345 LValue lv, bool isInit) {
346 if (lv.getType()->isAtomicType() ||
347 (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
348 return cgf.emitAtomicStore(RValue::getComplex(val), lv, isInit);
349 }
350
351 const Address destAddr = lv.getAddress();
352 builder.createStore(loc, val, destAddr, lv.isVolatileQualified());
353}
354
355//===----------------------------------------------------------------------===//
356// Visitor Methods
357//===----------------------------------------------------------------------===//
358
359mlir::Value ComplexExprEmitter::VisitExpr(Expr *e) {
360 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");
361 return {};
362}
363
364mlir::Value
365ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
366 auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));
367 mlir::Type elementTy = ty.getElementType();
368 mlir::Location loc = cgf.getLoc(il->getExprLoc());
369
370 mlir::TypedAttr realValueAttr;
371 mlir::TypedAttr imagValueAttr;
372
373 if (mlir::isa<cir::IntType>(elementTy)) {
374 llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();
375 realValueAttr = cir::IntAttr::get(elementTy, 0);
376 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
377 } else {
378 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
379 "Expected complex element type to be floating-point");
380
381 llvm::APFloat imagValue =
382 cast<FloatingLiteral>(il->getSubExpr())->getValue();
383 realValueAttr = cir::FPAttr::get(
384 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
385 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
386 }
387
388 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
389 return cir::ConstantOp::create(builder, loc, complexAttr);
390}
391
392mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
394 return emitLoadOfLValue(e);
395 return cgf.emitCallExpr(e).getComplexValue();
396}
397
398mlir::Value ComplexExprEmitter::VisitStmtExpr(const StmtExpr *e) {
399 CIRGenFunction::StmtExprEvaluation eval(cgf);
400 Address retAlloca =
401 cgf.createMemTemp(e->getType(), cgf.getLoc(e->getSourceRange()));
402 (void)cgf.emitCompoundStmt(*e->getSubStmt(), &retAlloca);
403 assert(retAlloca.isValid() && "Expected complex return value");
404 return emitLoadOfLValue(cgf.makeAddrLValue(retAlloca, e->getType()),
405 e->getExprLoc());
406}
407
408mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
409 QualType srcType,
410 QualType destType,
411 SourceLocation loc) {
412 if (srcType == destType)
413 return val;
414
415 // Get the src/dest element type.
416 QualType srcElemTy = srcType->castAs<ComplexType>()->getElementType();
417 QualType destElemTy = destType->castAs<ComplexType>()->getElementType();
418
419 cir::CastKind castOpKind;
420 if (srcElemTy->isFloatingType() && destElemTy->isFloatingType())
421 castOpKind = cir::CastKind::float_complex;
422 else if (srcElemTy->isFloatingType() && destElemTy->isIntegerType())
423 castOpKind = cir::CastKind::float_complex_to_int_complex;
424 else if (srcElemTy->isIntegerType() && destElemTy->isFloatingType())
425 castOpKind = cir::CastKind::int_complex_to_float_complex;
426 else if (srcElemTy->isIntegerType() && destElemTy->isIntegerType())
427 castOpKind = cir::CastKind::int_complex;
428 else
429 llvm_unreachable("unexpected src type or dest type");
430
431 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
432 cgf.convertType(destType));
433}
434
435mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
436 QualType srcType,
437 QualType destType,
438 SourceLocation loc) {
439 cir::CastKind castOpKind;
440 if (srcType->isFloatingType())
441 castOpKind = cir::CastKind::float_to_complex;
442 else if (srcType->isIntegerType())
443 castOpKind = cir::CastKind::int_to_complex;
444 else
445 llvm_unreachable("unexpected src type");
446
447 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
448 cgf.convertType(destType));
449}
450
451mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
452 QualType destTy) {
453 switch (ck) {
454 case CK_Dependent:
455 llvm_unreachable("dependent type must be resolved before the CIR codegen");
456
457 // Atomic to non-atomic casts may be more than a no-op for some platforms
458 // and for some types.
459 case CK_NonAtomicToAtomic:
460 case CK_NoOp:
461 case CK_LValueToRValue:
462 case CK_UserDefinedConversion:
463 return Visit(op);
464
465 case CK_AtomicToNonAtomic: {
466 cgf.cgm.errorNYI("ComplexExprEmitter::emitCast AtomicToNonAtomic");
467 return {};
468 }
469
470 case CK_LValueBitCast: {
471 LValue origLV = cgf.emitLValue(op);
472 Address addr =
473 origLV.getAddress().withElementType(builder, cgf.convertType(destTy));
474 LValue destLV = cgf.makeAddrLValue(addr, destTy);
475 return emitLoadOfLValue(destLV, op->getExprLoc());
476 }
477
478 case CK_LValueToRValueBitCast: {
479 LValue sourceLVal = cgf.emitLValue(op);
480 Address addr = sourceLVal.getAddress().withElementType(
481 builder, cgf.convertTypeForMem(destTy));
482 LValue destLV = cgf.makeAddrLValue(addr, destTy);
484 return emitLoadOfLValue(destLV, op->getExprLoc());
485 }
486
487 case CK_BitCast:
488 case CK_BaseToDerived:
489 case CK_DerivedToBase:
490 case CK_UncheckedDerivedToBase:
491 case CK_Dynamic:
492 case CK_ToUnion:
493 case CK_ArrayToPointerDecay:
494 case CK_FunctionToPointerDecay:
495 case CK_NullToPointer:
496 case CK_NullToMemberPointer:
497 case CK_BaseToDerivedMemberPointer:
498 case CK_DerivedToBaseMemberPointer:
499 case CK_MemberPointerToBoolean:
500 case CK_ReinterpretMemberPointer:
501 case CK_ConstructorConversion:
502 case CK_IntegralToPointer:
503 case CK_PointerToIntegral:
504 case CK_PointerToBoolean:
505 case CK_ToVoid:
506 case CK_VectorSplat:
507 case CK_IntegralCast:
508 case CK_BooleanToSignedIntegral:
509 case CK_IntegralToBoolean:
510 case CK_IntegralToFloating:
511 case CK_FloatingToIntegral:
512 case CK_FloatingToBoolean:
513 case CK_FloatingCast:
514 case CK_CPointerToObjCPointerCast:
515 case CK_BlockPointerToObjCPointerCast:
516 case CK_AnyPointerToBlockPointerCast:
517 case CK_ObjCObjectLValueCast:
518 case CK_FloatingComplexToReal:
519 case CK_FloatingComplexToBoolean:
520 case CK_IntegralComplexToReal:
521 case CK_IntegralComplexToBoolean:
522 case CK_ARCProduceObject:
523 case CK_ARCConsumeObject:
524 case CK_ARCReclaimReturnedObject:
525 case CK_ARCExtendBlockObject:
526 case CK_CopyAndAutoreleaseBlockObject:
527 case CK_BuiltinFnToFnPtr:
528 case CK_ZeroToOCLOpaqueType:
529 case CK_AddressSpaceConversion:
530 case CK_IntToOCLSampler:
531 case CK_FloatingToFixedPoint:
532 case CK_FixedPointToFloating:
533 case CK_FixedPointCast:
534 case CK_FixedPointToBoolean:
535 case CK_FixedPointToIntegral:
536 case CK_IntegralToFixedPoint:
537 case CK_MatrixCast:
538 case CK_HLSLVectorTruncation:
539 case CK_HLSLMatrixTruncation:
540 case CK_HLSLArrayRValue:
541 case CK_HLSLElementwiseCast:
542 case CK_HLSLAggregateSplatCast:
543 llvm_unreachable("invalid cast kind for complex value");
544
545 case CK_FloatingRealToComplex:
546 case CK_IntegralRealToComplex: {
547 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op);
548 return emitScalarToComplexCast(cgf.emitScalarExpr(op), op->getType(),
549 destTy, op->getExprLoc());
550 }
551
552 case CK_FloatingComplexCast:
553 case CK_FloatingComplexToIntegralComplex:
554 case CK_IntegralComplexCast:
555 case CK_IntegralComplexToFloatingComplex: {
556 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op);
557 return emitComplexToComplexCast(Visit(op), op->getType(), destTy,
558 op->getExprLoc());
559 }
560 }
561
562 llvm_unreachable("unknown cast resulting in complex value");
563}
564
565mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e) {
566 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
567 mlir::Value result = VisitUnaryPlus(e, promotionTy);
568 if (!promotionTy.isNull())
569 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
570 return result;
571}
572
573mlir::Value ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *e,
574 QualType promotionType) {
575 if (!promotionType.isNull())
576 return cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);
577 return Visit(e->getSubExpr());
578}
579
580mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) {
581 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
582 mlir::Value result = VisitUnaryMinus(e, promotionTy);
583 if (!promotionTy.isNull())
584 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
585 return result;
586}
587
588mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e,
589 QualType promotionType) {
590 mlir::Value op;
591 if (!promotionType.isNull())
592 op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);
593 else
594 op = Visit(e->getSubExpr());
595 return builder.createMinus(cgf.getLoc(e->getExprLoc()), op);
596}
597
598mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {
599 mlir::Value op = Visit(e->getSubExpr());
600 return builder.createNot(op);
601}
602
603mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
605 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
606
607 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
608 mlir::isa<cir::ComplexType>(op.rhs.getType()))
609 return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);
610
611 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
612 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
613 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
614 mlir::Value newReal = builder.createAdd(op.loc, real, op.rhs);
615 return builder.createComplexCreate(op.loc, newReal, imag);
616 }
617
618 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
619 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
620 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
621 mlir::Value newReal = builder.createAdd(op.loc, op.lhs, real);
622 return builder.createComplexCreate(op.loc, newReal, imag);
623}
624
625mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
627 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
628
629 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
630 mlir::isa<cir::ComplexType>(op.rhs.getType()))
631 return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);
632
633 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
634 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
635 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
636 mlir::Value newReal = builder.createSub(op.loc, real, op.rhs);
637 return builder.createComplexCreate(op.loc, newReal, imag);
638 }
639
640 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
641 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
642 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
643 mlir::Value newReal = builder.createSub(op.loc, op.lhs, real);
644 return builder.createComplexCreate(op.loc, newReal, imag);
645}
646
647static cir::ComplexRangeKind
649 switch (range) {
651 return cir::ComplexRangeKind::Full;
653 return cir::ComplexRangeKind::Improved;
655 return cir::ComplexRangeKind::Promoted;
657 return cir::ComplexRangeKind::Basic;
659 // The default value for ComplexRangeKind is Full if no option is selected
660 return cir::ComplexRangeKind::Full;
661 }
662}
663
664mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) {
666 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
667
668 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
669 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
670 cir::ComplexRangeKind rangeKind =
671 getComplexRangeAttr(op.fpFeatures.getComplexRange());
672 return cir::ComplexMulOp::create(builder, op.loc, op.lhs, op.rhs,
673 rangeKind);
674 }
675
676 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
677 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
678 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
679 mlir::Value newReal = builder.createMul(op.loc, real, op.rhs);
680 mlir::Value newImag = builder.createMul(op.loc, imag, op.rhs);
681 return builder.createComplexCreate(op.loc, newReal, newImag);
682 }
683
684 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
685 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
686 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
687 mlir::Value newReal = builder.createMul(op.loc, op.lhs, real);
688 mlir::Value newImag = builder.createMul(op.loc, op.lhs, imag);
689 return builder.createComplexCreate(op.loc, newReal, newImag);
690}
691
692mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) {
694 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, op.fpFeatures);
695
696 // Handle division between two complex values. In the case of complex integer
697 // types mixed with scalar integers, the scalar integer type will always be
698 // promoted to a complex integer value with a zero imaginary component when
699 // the AST is formed.
700 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
701 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
702 cir::ComplexRangeKind rangeKind =
703 getComplexRangeAttr(op.fpFeatures.getComplexRange());
704 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,
705 rangeKind);
706 }
707
708 // The C99 standard (G.5.1) defines division of a complex value by a real
709 // value in the following simplified form.
710 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
711 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==
712 op.rhs.getType());
713 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
714 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
715 mlir::Value newReal = builder.createFDiv(op.loc, real, op.rhs);
716 mlir::Value newImag = builder.createFDiv(op.loc, imag, op.rhs);
717 return builder.createComplexCreate(op.loc, newReal, newImag);
718 }
719
720 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
721 cir::ConstantOp nullValue = builder.getNullValue(op.lhs.getType(), op.loc);
722 mlir::Value lhs = builder.createComplexCreate(op.loc, op.lhs, nullValue);
723 cir::ComplexRangeKind rangeKind =
724 getComplexRangeAttr(op.fpFeatures.getComplexRange());
725 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);
726}
727
728mlir::Value CIRGenFunction::emitUnPromotedValue(mlir::Value result,
729 QualType unPromotionType) {
730 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
731 "integral complex will never be promoted");
732 return builder.createCast(cir::CastKind::float_complex, result,
733 convertType(unPromotionType));
734}
735
736mlir::Value CIRGenFunction::emitPromotedValue(mlir::Value result,
737 QualType promotionType) {
738 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
739 "integral complex will never be promoted");
740 return builder.createCast(cir::CastKind::float_complex, result,
741 convertType(promotionType));
742}
743
744mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
745 QualType promotionTy) {
746 e = e->IgnoreParens();
747 if (const auto *bo = dyn_cast<BinaryOperator>(e)) {
748 switch (bo->getOpcode()) {
749#define HANDLE_BINOP(OP) \
750 case BO_##OP: \
751 return emitBin##OP(emitBinOps(bo, promotionTy));
752 HANDLE_BINOP(Add)
753 HANDLE_BINOP(Sub)
754 HANDLE_BINOP(Mul)
755 HANDLE_BINOP(Div)
756#undef HANDLE_BINOP
757 default:
758 break;
759 }
760 } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {
761 switch (unaryOp->getOpcode()) {
762 case UO_Plus:
763 return VisitUnaryPlus(unaryOp, promotionTy);
764 case UO_Minus:
765 return VisitUnaryMinus(unaryOp, promotionTy);
766 default:
767 break;
768 }
769 }
770
771 mlir::Value result = Visit(const_cast<Expr *>(e));
772 if (!promotionTy.isNull())
773 return cgf.emitPromotedValue(result, promotionTy);
774
775 return result;
776}
777
779 QualType promotionType) {
780 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
781}
782
783mlir::Value
784ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,
785 QualType promotionTy) {
786 if (e->getType()->isAnyComplexType()) {
787 if (!promotionTy.isNull())
788 return cgf.emitPromotedComplexExpr(e, promotionTy);
789 return Visit(const_cast<Expr *>(e));
790 }
791
792 if (!promotionTy.isNull()) {
793 QualType complexElementTy =
794 promotionTy->castAs<ComplexType>()->getElementType();
795 return cgf.emitPromotedScalarExpr(e, complexElementTy);
796 }
797 return cgf.emitScalarExpr(e);
798}
799
800ComplexExprEmitter::BinOpInfo
801ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
802 BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};
803 binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);
804 binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);
805 binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;
806 binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
807 return binOpInfo;
808}
809
810LValue ComplexExprEmitter::emitCompoundAssignLValue(
811 const CompoundAssignOperator *e,
812 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) {
813 QualType lhsTy = e->getLHS()->getType();
814 QualType rhsTy = e->getRHS()->getType();
815 SourceLocation exprLoc = e->getExprLoc();
816 mlir::Location loc = cgf.getLoc(exprLoc);
817
818 if (lhsTy->getAs<AtomicType>()) {
819 cgf.cgm.errorNYI("emitCompoundAssignLValue AtmoicType");
820 return {};
821 }
822
823 BinOpInfo opInfo{loc};
824 opInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
825
826 CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, opInfo.fpFeatures);
827
828 // Load the RHS and LHS operands.
829 // __block variables need to have the rhs evaluated first, plus this should
830 // improve codegen a little.
831 QualType promotionTypeCR = getPromotionType(e->getComputationResultType());
832 opInfo.ty = promotionTypeCR.isNull() ? e->getComputationResultType()
833 : promotionTypeCR;
834
835 QualType complexElementTy =
836 opInfo.ty->castAs<ComplexType>()->getElementType();
837 QualType promotionTypeRHS = getPromotionType(rhsTy);
838
839 // The RHS should have been converted to the computation type.
840 if (e->getRHS()->getType()->isRealFloatingType()) {
841 if (!promotionTypeRHS.isNull()) {
842 opInfo.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS);
843 } else {
844 assert(cgf.getContext().hasSameUnqualifiedType(complexElementTy, rhsTy));
845 opInfo.rhs = cgf.emitScalarExpr(e->getRHS());
846 }
847 } else {
848 if (!promotionTypeRHS.isNull()) {
849 opInfo.rhs = cgf.emitPromotedComplexExpr(e->getRHS(), promotionTypeRHS);
850 } else {
851 assert(cgf.getContext().hasSameUnqualifiedType(opInfo.ty, rhsTy));
852 opInfo.rhs = Visit(e->getRHS());
853 }
854 }
855
856 LValue lhs = cgf.emitLValue(e->getLHS());
857
858 // Load from the l-value and convert it.
859 QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());
860 if (lhsTy->isAnyComplexType()) {
861 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
862 QualType destTy = promotionTypeLHS.isNull() ? opInfo.ty : promotionTypeLHS;
863 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
864 } else {
865 mlir::Value lhsVal = cgf.emitLoadOfScalar(lhs, exprLoc);
866 // For floating point real operands we can directly pass the scalar form
867 // to the binary operator emission and potentially get more efficient code.
868 if (lhsTy->isRealFloatingType()) {
869 QualType promotedComplexElementTy;
870 if (!promotionTypeLHS.isNull()) {
871 promotedComplexElementTy =
872 cast<ComplexType>(promotionTypeLHS)->getElementType();
873 if (!cgf.getContext().hasSameUnqualifiedType(promotedComplexElementTy,
874 promotionTypeLHS))
875 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy,
876 promotedComplexElementTy, exprLoc);
877 } else {
878 if (!cgf.getContext().hasSameUnqualifiedType(complexElementTy, lhsTy))
879 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy, complexElementTy,
880 exprLoc);
881 }
882 opInfo.lhs = lhsVal;
883 } else {
884 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);
885 }
886 }
887
888 // Expand the binary operator.
889 mlir::Value result = (this->*func)(opInfo);
890
891 // Truncate the result and store it into the LHS lvalue.
892 if (lhsTy->isAnyComplexType()) {
893 mlir::Value resultValue =
894 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
895 emitStoreOfComplex(loc, resultValue, lhs, /*isInit*/ false);
896 value = RValue::getComplex(resultValue);
897 } else {
898 mlir::Value resultValue =
899 cgf.emitComplexToScalarConversion(result, opInfo.ty, lhsTy, exprLoc);
900 cgf.emitStoreOfScalar(resultValue, lhs, /*isInit*/ false);
901 value = RValue::get(resultValue);
902 }
903
904 return lhs;
905}
906
907mlir::Value ComplexExprEmitter::emitCompoundAssign(
908 const CompoundAssignOperator *e,
909 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &)) {
910 RValue val;
911 LValue lv = emitCompoundAssignLValue(e, func, val);
912
913 // The result of an assignment in C is the assigned r-value.
914 if (!cgf.getLangOpts().CPlusPlus)
915 return val.getComplexValue();
916
917 // If the lvalue is non-volatile, return the computed value of the assignment.
918 if (!lv.isVolatileQualified())
919 return val.getComplexValue();
920
921 return emitLoadOfLValue(lv, e->getExprLoc());
922}
923
924LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
925 mlir::Value &value) {
926 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
927 e->getRHS()->getType()) &&
928 "Invalid assignment");
929
930 // Emit the RHS. __block variables need the RHS evaluated first.
931 value = Visit(e->getRHS());
932
933 // Compute the address to store into.
934 LValue lhs = cgf.emitLValue(e->getLHS());
935
936 // Store the result value into the LHS lvalue.
937 emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs,
938 /*isInit*/ false);
939 return lhs;
940}
941
942mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {
943 mlir::Value value;
944 LValue lv = emitBinAssignLValue(e, value);
945
946 // The result of an assignment in C is the assigned r-value.
947 if (!cgf.getLangOpts().CPlusPlus)
948 return value;
949
950 // If the lvalue is non-volatile, return the computed value of the
951 // assignment.
952 if (!lv.isVolatile())
953 return value;
954
955 return emitLoadOfLValue(lv, e->getExprLoc());
956}
957
958mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {
959 cgf.emitIgnoredExpr(e->getLHS());
960 return Visit(e->getRHS());
961}
962
963mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
964 const AbstractConditionalOperator *e) {
965 mlir::Location loc = cgf.getLoc(e->getSourceRange());
966
967 // Bind the common expression if necessary.
968 CIRGenFunction::OpaqueValueMapping binding(cgf, e);
969
970 CIRGenFunction::ConditionalEvaluation eval(cgf);
971
972 Expr *cond = e->getCond()->IgnoreParens();
973 mlir::Value condValue = cgf.evaluateExprAsBool(cond);
974
975 return cir::TernaryOp::create(
976 builder, loc, condValue,
977 /*thenBuilder=*/
978 [&](mlir::OpBuilder &b, mlir::Location loc) {
979 eval.beginEvaluation();
980 mlir::Value trueValue = Visit(e->getTrueExpr());
981 cir::YieldOp::create(b, loc, trueValue);
982 eval.endEvaluation();
983 },
984 /*elseBuilder=*/
985 [&](mlir::OpBuilder &b, mlir::Location loc) {
986 eval.beginEvaluation();
987 mlir::Value falseValue = Visit(e->getFalseExpr());
988 cir::YieldOp::create(b, loc, falseValue);
989 eval.endEvaluation();
990 })
991 .getResult();
992}
993
994mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
995 return Visit(e->getChosenSubExpr());
996}
997
998mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
999 mlir::Location loc = cgf.getLoc(e->getExprLoc());
1000 if (e->getNumInits() == 2) {
1001 mlir::Value real = cgf.emitScalarExpr(e->getInit(0));
1002 mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));
1003 return builder.createComplexCreate(loc, real, imag);
1004 }
1005
1006 if (e->getNumInits() == 1)
1007 return Visit(e->getInit(0));
1008
1009 assert(e->getNumInits() == 0 && "Unexpected number of inits");
1010 mlir::Type complexTy = cgf.convertType(e->getType());
1011 return builder.getNullValue(complexTy, loc);
1012}
1013
1014mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {
1015 return cgf.emitVAArg(e);
1016}
1017
1018//===----------------------------------------------------------------------===//
1019// Entry Point into this File
1020//===----------------------------------------------------------------------===//
1021
1022/// EmitComplexExpr - Emit the computation of the specified expression of
1023/// complex type, ignoring the result.
1025 assert(e && getComplexType(e->getType()) &&
1026 "Invalid complex expression to emit");
1027
1028 return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
1029}
1030
1032 bool isInit) {
1033 assert(e && getComplexType(e->getType()) &&
1034 "Invalid complex expression to emit");
1035 ComplexExprEmitter emitter(*this);
1036 mlir::Value value = emitter.Visit(const_cast<Expr *>(e));
1037 emitter.emitStoreOfComplex(getLoc(e->getExprLoc()), value, dest, isInit);
1038}
1039
1040/// EmitStoreOfComplex - Store a complex number into the specified l-value.
1041void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
1042 LValue dest, bool isInit) {
1043 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
1044}
1045
1047 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
1048}
1049
1051 assert(e->getOpcode() == BO_Assign && "Expected assign op");
1052
1053 mlir::Value value; // ignored
1054 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
1055 if (getLangOpts().OpenMP)
1056 cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
1057
1058 return lvalue;
1059}
1060
1062 mlir::Value (ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &);
1063
1065 switch (op) {
1066 case BO_MulAssign:
1067 return &ComplexExprEmitter::emitBinMul;
1068 case BO_DivAssign:
1069 return &ComplexExprEmitter::emitBinDiv;
1070 case BO_SubAssign:
1071 return &ComplexExprEmitter::emitBinSub;
1072 case BO_AddAssign:
1073 return &ComplexExprEmitter::emitBinAdd;
1074 default:
1075 llvm_unreachable("unexpected complex compound assignment");
1076 }
1077}
1078
1080 const CompoundAssignOperator *e) {
1082 RValue val;
1083 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);
1084}
1085
1087 LValue lv) {
1088 mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
1089 mlir::Location loc = getLoc(e->getExprLoc());
1090 mlir::Value incVal = e->isIncrementOp() ? builder.createInc(loc, inVal)
1091 : builder.createDec(loc, inVal);
1092
1093 // Store the updated result through the lvalue.
1094 emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
1095
1096 if (getLangOpts().OpenMP)
1097 cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
1098
1099 // If this is a postinc, return the value read from memory, otherwise use the
1100 // updated value.
1101 return e->isPrefix() ? incVal : inVal;
1102}
1103
1105 const CompoundAssignOperator *e, mlir::Value &result) {
1106 // Key Instructions: Don't need to create an atom group here; one will already
1107 // be active through scalar handling code.
1109 RValue value;
1110 LValue ret = ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, value);
1111 result = value.getValue();
1112 return ret;
1113}
#define HANDLEBINOP(OP)
static CompoundFunc getComplexOp(BinaryOperatorKind op)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc
static cir::ComplexRangeKind getComplexRangeAttr(LangOptions::ComplexRangeKind range)
#define HANDLE_BINOP(OP)
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
mlir::Value createSub(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
mlir::Value createCast(mlir::Location loc, cir::CastKind kind, mlir::Value src, mlir::Type newTy)
mlir::Value createAdd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createComplexImag(mlir::Location loc, mlir::Value operand)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
mlir::Value createMinus(mlir::Location loc, mlir::Value input, bool nsw=false)
mlir::Value createComplexCreate(mlir::Location loc, mlir::Value real, mlir::Value imag)
mlir::Value createComplexReal(mlir::Location loc, mlir::Value operand)
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Definition Expr.h:4534
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Definition Expr.h:4540
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Definition Expr.h:4546
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
Expr * getLHS() const
Definition Expr.h:4091
SourceLocation getExprLoc() const
Definition Expr.h:4082
Expr * getRHS() const
Definition Expr.h:4093
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Definition Expr.h:4254
Opcode getOpcode() const
Definition Expr.h:4086
bool isValid() const
Definition Address.h:77
mlir::Value createFDiv(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
LValue getReferenceLValue(CIRGenFunction &cgf, Expr *refExpr) const
mlir::Value emitComplexToScalarConversion(mlir::Value src, QualType srcTy, QualType dstTy, SourceLocation loc)
Emit a conversion from the specified complex type to the specified destination type,...
mlir::Type convertType(clang::QualType t)
mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType)
const clang::LangOptions & getLangOpts() const
LValue emitScalarCompoundAssignWithComplex(const CompoundAssignOperator *e, mlir::Value &result)
mlir::Value emitComplexExpr(const Expr *e)
Emit the computation of the specified expression of complex type, returning the result.
RValue emitCallExpr(const clang::CallExpr *e, ReturnValueSlot returnValue=ReturnValueSlot())
LValue emitLValue(const clang::Expr *e)
Emit code to compute a designator that specifies the location of the expression.
mlir::Value evaluateExprAsBool(const clang::Expr *e)
Perform the usual unary conversions on the specified expression and compare the result against zero,...
LValue emitComplexCompoundAssignmentLValue(const CompoundAssignOperator *e)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
mlir::Value emitScalarConversion(mlir::Value src, clang::QualType srcType, clang::QualType dstType, clang::SourceLocation loc)
Emit a conversion from the specified type to the specified destination type, both of which are CIR sc...
mlir::Value emitPromotedComplexExpr(const Expr *e, QualType promotionType)
mlir::Value emitUnPromotedValue(mlir::Value result, QualType unPromotionType)
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitComplexPrePostIncDec(const UnaryOperator *e, LValue lv)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
LValue emitComplexAssignmentLValue(const BinaryOperator *e)
mlir::Value emitScalarExpr(const clang::Expr *e, bool ignoreResultAssign=false)
Emit the computation of the specified expression of scalar type.
mlir::Value emitPromotedScalarExpr(const Expr *e, QualType promotionType)
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitAtomicStore(RValue rvalue, LValue dest, bool isInit)
clang::ASTContext & getContext() const
mlir::LogicalResult emitCompoundStmt(const clang::CompoundStmt &s, Address *lastValue=nullptr, AggValueSlot slot=AggValueSlot::ignored())
bool isLValueSuitableForInlineAtomic(LValue lv)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
void emitIgnoredExpr(const clang::Expr *e)
Emit code to compute the specified expression, ignoring the result.
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
mlir::Value emitVAArg(VAArgExpr *ve)
Generate code to get an argument from the passed in pointer and update it accordingly.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
This trivial value class is used to represent the result of an expression that is evaluated.
Definition CIRGenValue.h:33
static RValue get(mlir::Value v)
Definition CIRGenValue.h:83
static RValue getComplex(mlir::Value v)
Definition CIRGenValue.h:91
mlir::Value getValue() const
Return the value of this scalar value.
Definition CIRGenValue.h:57
mlir::Value getComplexValue() const
Return the value of this complex value.
Definition CIRGenValue.h:63
Expr * getExpr()
Get the initialization expression that will be used.
Definition ExprCXX.cpp:1112
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
SourceLocation getExprLoc() const LLVM_READONLY
Definition ExprCXX.h:345
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition Expr.cpp:1608
CastKind getCastKind() const
Definition Expr.h:3723
bool changesVolatileQualification() const
Return.
Definition Expr.h:3813
Expr * getSubExpr()
Definition Expr.h:3729
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition Expr.h:4887
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3337
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4303
QualType getComputationLHSType() const
Definition Expr.h:4337
QualType getComputationResultType() const
Definition Expr.h:4340
This represents one expression.
Definition Expr.h:112
bool isGLValue() const
Definition Expr.h:287
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition Expr.cpp:3093
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:282
QualType getType() const
Definition Expr.h:144
const Expr * getSubExpr() const
Definition Expr.h:1065
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6468
const Expr * getSubExpr() const
Definition Expr.h:1746
unsigned getNumInits() const
Definition Expr.h:5335
const Expr * getInit(unsigned Init) const
Definition Expr.h:5357
ComplexRangeKind
Controls the various implementations for complex multiplication and.
@ CX_Full
Implementation of complex division and multiplication using a call to runtime library functions(gener...
@ CX_Basic
Implementation of complex division and multiplication using algebraic formulas at source precision.
@ CX_Promoted
Implementation of complex division using algebraic formulas at higher precision.
@ CX_None
No range rule is enabled.
@ CX_Improved
Implementation of complex division offering an improved handling for overflow in intermediate calcula...
Expr * getBase() const
Definition Expr.h:3444
SourceLocation getExprLoc() const LLVM_READONLY
Definition Expr.h:1211
Expr * getSelectedExpr() const
Definition ExprCXX.h:4639
const Expr * getSubExpr() const
Definition Expr.h:2202
SourceLocation getExprLoc() const LLVM_READONLY
Definition Expr.h:6890
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
bool UseExcessPrecision(const ASTContext &Ctx)
Definition Type.cpp:1661
Encodes a location in the source.
CompoundStmt * getSubStmt()
Definition Expr.h:4615
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9092
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9342
bool isReferenceType() const
Definition TypeBase.h:8706
bool isAnyComplexType() const
Definition TypeBase.h:8817
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2405
bool isFloatingType() const
Definition Type.cpp:2389
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9275
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
SourceLocation getExprLoc() const
Definition Expr.h:2371
Expr * getSubExpr() const
Definition Expr.h:2288
static bool isIncrementOp(Opcode Op)
Definition Expr.h:2329
static bool isPrefix(Opcode Op)
isPrefix - Return true if this is a prefix operation, like –x.
Definition Expr.h:2322
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
@ Address
A pointer to a ValueDecl.
Definition Primitives.h:28
The JSON file list parser is used to communicate input to InstallAPI.
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Definition Address.h:327
static bool fastMathFlags()