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