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) {
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) {
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) {
125 cgf.emitIgnoredExpr(me->getBase());
126 return emitConstant(constant, me);
127 }
128 return emitLoadOfLValue(me);
129 }
130 mlir::Value VisitOpaqueValueExpr(OpaqueValueExpr *e) {
131 cgf.cgm.errorNYI(e->getExprLoc(),
132 "ComplexExprEmitter VisitOpaqueValueExpr");
133 return {};
134 }
135
136 mlir::Value VisitPseudoObjectExpr(PseudoObjectExpr *e) {
137 cgf.cgm.errorNYI(e->getExprLoc(),
138 "ComplexExprEmitter VisitPseudoObjectExpr");
139 return {};
140 }
141
142 mlir::Value emitCast(CastKind ck, Expr *op, QualType destTy);
143 mlir::Value VisitImplicitCastExpr(ImplicitCastExpr *e) {
144 // Unlike for scalars, we don't have to worry about function->ptr demotion
145 // here.
147 return emitLoadOfLValue(e);
148 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
149 }
150 mlir::Value VisitCastExpr(CastExpr *e) {
151 if (const auto *ece = dyn_cast<ExplicitCastExpr>(e)) {
152 // Bind VLAs in the cast type.
153 if (ece->getType()->isVariablyModifiedType()) {
154 cgf.cgm.errorNYI(e->getExprLoc(),
155 "VisitCastExpr Bind VLAs in the cast type");
156 return {};
157 }
158 }
159
161 return emitLoadOfLValue(e);
162
163 return emitCast(e->getCastKind(), e->getSubExpr(), e->getType());
164 }
165 mlir::Value VisitCallExpr(const CallExpr *e);
166 mlir::Value VisitStmtExpr(const StmtExpr *e);
167
168 // Operators.
169 mlir::Value VisitPrePostIncDec(const UnaryOperator *e, cir::UnaryOpKind op,
170 bool isPre) {
171 LValue lv = cgf.emitLValue(e->getSubExpr());
172 return cgf.emitComplexPrePostIncDec(e, lv, op, isPre);
173 }
174 mlir::Value VisitUnaryPostDec(const UnaryOperator *e) {
175 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, false);
176 }
177 mlir::Value VisitUnaryPostInc(const UnaryOperator *e) {
178 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, false);
179 }
180 mlir::Value VisitUnaryPreDec(const UnaryOperator *e) {
181 return VisitPrePostIncDec(e, cir::UnaryOpKind::Dec, true);
182 }
183 mlir::Value VisitUnaryPreInc(const UnaryOperator *e) {
184 return VisitPrePostIncDec(e, cir::UnaryOpKind::Inc, true);
185 }
186 mlir::Value VisitUnaryDeref(const Expr *e) { return emitLoadOfLValue(e); }
187
188 mlir::Value VisitUnaryPlus(const UnaryOperator *e);
189 mlir::Value VisitUnaryMinus(const UnaryOperator *e);
190 mlir::Value VisitPlusMinus(const UnaryOperator *e, cir::UnaryOpKind kind,
191 QualType promotionType);
192 mlir::Value VisitUnaryNot(const UnaryOperator *e);
193 // LNot,Real,Imag never return complex.
194 mlir::Value VisitUnaryExtension(const UnaryOperator *e) {
195 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitUnaryExtension");
196 return {};
197 }
198 mlir::Value VisitCXXDefaultArgExpr(CXXDefaultArgExpr *dae) {
199 cgf.cgm.errorNYI(dae->getExprLoc(),
200 "ComplexExprEmitter VisitCXXDefaultArgExpr");
201 return {};
202 }
203 mlir::Value VisitCXXDefaultInitExpr(CXXDefaultInitExpr *die) {
204 cgf.cgm.errorNYI(die->getExprLoc(),
205 "ComplexExprEmitter VisitCXXDefaultInitExpr");
206 return {};
207 }
208 mlir::Value VisitExprWithCleanups(ExprWithCleanups *e) {
209 cgf.cgm.errorNYI(e->getExprLoc(),
210 "ComplexExprEmitter VisitExprWithCleanups");
211 return {};
212 }
213 mlir::Value VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) {
214 mlir::Location loc = cgf.getLoc(e->getExprLoc());
215 mlir::Type complexTy = cgf.convertType(e->getType());
216 return builder.getNullValue(complexTy, loc);
217 }
218 mlir::Value VisitImplicitValueInitExpr(ImplicitValueInitExpr *e) {
219 cgf.cgm.errorNYI(e->getExprLoc(),
220 "ComplexExprEmitter VisitImplicitValueInitExpr");
221 return {};
222 }
223
224 struct BinOpInfo {
225 mlir::Location loc;
226 mlir::Value lhs{};
227 mlir::Value rhs{};
228 QualType ty{}; // Computation Type.
229 FPOptions fpFeatures{};
230 };
231
232 BinOpInfo emitBinOps(const BinaryOperator *e,
233 QualType promotionTy = QualType());
234
235 mlir::Value emitPromoted(const Expr *e, QualType promotionTy);
236 mlir::Value emitPromotedComplexOperand(const Expr *e, QualType promotionTy);
237 LValue emitCompoundAssignLValue(
238 const CompoundAssignOperator *e,
239 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &),
240 RValue &value);
241 mlir::Value emitCompoundAssign(
242 const CompoundAssignOperator *e,
243 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &));
244
245 mlir::Value emitBinAdd(const BinOpInfo &op);
246 mlir::Value emitBinSub(const BinOpInfo &op);
247 mlir::Value emitBinMul(const BinOpInfo &op);
248 mlir::Value emitBinDiv(const BinOpInfo &op);
249
250 QualType getPromotionType(QualType ty, bool isDivOpCode = false) {
251 if (auto *complexTy = ty->getAs<ComplexType>()) {
252 QualType elementTy = complexTy->getElementType();
253 if (elementTy.UseExcessPrecision(cgf.getContext()))
254 return cgf.getContext().getComplexType(cgf.getContext().FloatTy);
255 }
256
257 if (ty.UseExcessPrecision(cgf.getContext()))
258 return cgf.getContext().FloatTy;
259 return QualType();
260 }
261
262#define HANDLEBINOP(OP) \
263 mlir::Value VisitBin##OP(const BinaryOperator *e) { \
264 QualType promotionTy = getPromotionType( \
265 e->getType(), e->getOpcode() == BinaryOperatorKind::BO_Div); \
266 mlir::Value result = emitBin##OP(emitBinOps(e, promotionTy)); \
267 if (!promotionTy.isNull()) \
268 result = cgf.emitUnPromotedValue(result, e->getType()); \
269 return result; \
270 }
271
272 HANDLEBINOP(Add)
273 HANDLEBINOP(Sub)
274 HANDLEBINOP(Mul)
275 HANDLEBINOP(Div)
276#undef HANDLEBINOP
277
278 mlir::Value VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *e) {
279 cgf.cgm.errorNYI(e->getExprLoc(),
280 "ComplexExprEmitter VisitCXXRewrittenBinaryOperator");
281 return {};
282 }
283
284 // Compound assignments.
285 mlir::Value VisitBinAddAssign(const CompoundAssignOperator *e) {
286 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinAdd);
287 }
288 mlir::Value VisitBinSubAssign(const CompoundAssignOperator *e) {
289 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinSub);
290 }
291 mlir::Value VisitBinMulAssign(const CompoundAssignOperator *e) {
292 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinMul);
293 }
294 mlir::Value VisitBinDivAssign(const CompoundAssignOperator *e) {
295 return emitCompoundAssign(e, &ComplexExprEmitter::emitBinDiv);
296 }
297
298 // GCC rejects rem/and/or/xor for integer complex.
299 // Logical and/or always return int, never complex.
300
301 // No comparisons produce a complex result.
302
303 LValue emitBinAssignLValue(const BinaryOperator *e, mlir::Value &val);
304 mlir::Value VisitBinAssign(const BinaryOperator *e);
305 mlir::Value VisitBinComma(const BinaryOperator *e);
306
307 mlir::Value
308 VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
309 mlir::Value VisitChooseExpr(ChooseExpr *e);
310
311 mlir::Value VisitInitListExpr(InitListExpr *e);
312
313 mlir::Value VisitCompoundLiteralExpr(CompoundLiteralExpr *e) {
314 return emitLoadOfLValue(e);
315 }
316
317 mlir::Value VisitVAArgExpr(VAArgExpr *e);
318
319 mlir::Value VisitAtomicExpr(AtomicExpr *e) {
320 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitAtomicExpr");
321 return {};
322 }
323
324 mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {
325 cgf.cgm.errorNYI(e->getExprLoc(),
326 "ComplexExprEmitter VisitPackIndexingExpr");
327 return {};
328 }
329};
330} // namespace
331
332//===----------------------------------------------------------------------===//
333// Utilities
334//===----------------------------------------------------------------------===//
335
336/// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
337/// load the real and imaginary pieces, returning them as Real/Imag.
338mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
339 SourceLocation loc) {
340 assert(lv.isSimple() && "non-simple complex l-value?");
341 if (lv.getType()->isAtomicType())
342 cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
343
344 const Address srcAddr = lv.getAddress();
345 return builder.createLoad(cgf.getLoc(loc), srcAddr);
346}
347
348/// EmitStoreOfComplex - Store the specified real/imag parts into the
349/// specified value pointer.
350void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
351 LValue lv, bool isInit) {
352 if (lv.getType()->isAtomicType() ||
353 (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
354 cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
355 return;
356 }
357
358 const Address destAddr = lv.getAddress();
359 builder.createStore(loc, val, destAddr);
360}
361
362//===----------------------------------------------------------------------===//
363// Visitor Methods
364//===----------------------------------------------------------------------===//
365
366mlir::Value ComplexExprEmitter::VisitExpr(Expr *e) {
367 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");
368 return {};
369}
370
371mlir::Value
372ComplexExprEmitter::VisitImaginaryLiteral(const ImaginaryLiteral *il) {
373 auto ty = mlir::cast<cir::ComplexType>(cgf.convertType(il->getType()));
374 mlir::Type elementTy = ty.getElementType();
375 mlir::Location loc = cgf.getLoc(il->getExprLoc());
376
377 mlir::TypedAttr realValueAttr;
378 mlir::TypedAttr imagValueAttr;
379
380 if (mlir::isa<cir::IntType>(elementTy)) {
381 llvm::APInt imagValue = cast<IntegerLiteral>(il->getSubExpr())->getValue();
382 realValueAttr = cir::IntAttr::get(elementTy, 0);
383 imagValueAttr = cir::IntAttr::get(elementTy, imagValue);
384 } else {
385 assert(mlir::isa<cir::FPTypeInterface>(elementTy) &&
386 "Expected complex element type to be floating-point");
387
388 llvm::APFloat imagValue =
389 cast<FloatingLiteral>(il->getSubExpr())->getValue();
390 realValueAttr = cir::FPAttr::get(
391 elementTy, llvm::APFloat::getZero(imagValue.getSemantics()));
392 imagValueAttr = cir::FPAttr::get(elementTy, imagValue);
393 }
394
395 auto complexAttr = cir::ConstComplexAttr::get(realValueAttr, imagValueAttr);
396 return builder.create<cir::ConstantOp>(loc, complexAttr);
397}
398
399mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
401 return emitLoadOfLValue(e);
402 return cgf.emitCallExpr(e).getComplexValue();
403}
404
405mlir::Value ComplexExprEmitter::VisitStmtExpr(const StmtExpr *e) {
406 cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitExpr");
407 return {};
408}
409
410mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
411 QualType srcType,
412 QualType destType,
413 SourceLocation loc) {
414 if (srcType == destType)
415 return val;
416
417 // Get the src/dest element type.
418 QualType srcElemTy = srcType->castAs<ComplexType>()->getElementType();
419 QualType destElemTy = destType->castAs<ComplexType>()->getElementType();
420
421 cir::CastKind castOpKind;
422 if (srcElemTy->isFloatingType() && destElemTy->isFloatingType())
423 castOpKind = cir::CastKind::float_complex;
424 else if (srcElemTy->isFloatingType() && destElemTy->isIntegerType())
425 castOpKind = cir::CastKind::float_complex_to_int_complex;
426 else if (srcElemTy->isIntegerType() && destElemTy->isFloatingType())
427 castOpKind = cir::CastKind::int_complex_to_float_complex;
428 else if (srcElemTy->isIntegerType() && destElemTy->isIntegerType())
429 castOpKind = cir::CastKind::int_complex;
430 else
431 llvm_unreachable("unexpected src type or dest type");
432
433 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
434 cgf.convertType(destType));
435}
436
437mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
438 QualType srcType,
439 QualType destType,
440 SourceLocation loc) {
441 cir::CastKind castOpKind;
442 if (srcType->isFloatingType())
443 castOpKind = cir::CastKind::float_to_complex;
444 else if (srcType->isIntegerType())
445 castOpKind = cir::CastKind::int_to_complex;
446 else
447 llvm_unreachable("unexpected src type");
448
449 return builder.createCast(cgf.getLoc(loc), castOpKind, val,
450 cgf.convertType(destType));
451}
452
453mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
454 QualType destTy) {
455 switch (ck) {
456 case CK_Dependent:
457 llvm_unreachable("dependent type must be resolved before the CIR codegen");
458
459 case CK_NoOp:
460 case CK_LValueToRValue:
461 return Visit(op);
462
463 case CK_AtomicToNonAtomic:
464 case CK_NonAtomicToAtomic:
465 case CK_UserDefinedConversion: {
466 cgf.cgm.errorNYI(
467 "ComplexExprEmitter::emitCast Atmoic & UserDefinedConversion");
468 return {};
469 }
470
471 case CK_LValueBitCast: {
472 LValue origLV = cgf.emitLValue(op);
473 Address addr =
474 origLV.getAddress().withElementType(builder, cgf.convertType(destTy));
475 LValue destLV = cgf.makeAddrLValue(addr, destTy);
476 return emitLoadOfLValue(destLV, op->getExprLoc());
477 }
478
479 case CK_LValueToRValueBitCast: {
480 LValue sourceLVal = cgf.emitLValue(op);
481 Address addr = sourceLVal.getAddress().withElementType(
482 builder, cgf.convertTypeForMem(destTy));
483 LValue destLV = cgf.makeAddrLValue(addr, destTy);
485 return emitLoadOfLValue(destLV, op->getExprLoc());
486 }
487
488 case CK_BitCast:
489 case CK_BaseToDerived:
490 case CK_DerivedToBase:
491 case CK_UncheckedDerivedToBase:
492 case CK_Dynamic:
493 case CK_ToUnion:
494 case CK_ArrayToPointerDecay:
495 case CK_FunctionToPointerDecay:
496 case CK_NullToPointer:
497 case CK_NullToMemberPointer:
498 case CK_BaseToDerivedMemberPointer:
499 case CK_DerivedToBaseMemberPointer:
500 case CK_MemberPointerToBoolean:
501 case CK_ReinterpretMemberPointer:
502 case CK_ConstructorConversion:
503 case CK_IntegralToPointer:
504 case CK_PointerToIntegral:
505 case CK_PointerToBoolean:
506 case CK_ToVoid:
507 case CK_VectorSplat:
508 case CK_IntegralCast:
509 case CK_BooleanToSignedIntegral:
510 case CK_IntegralToBoolean:
511 case CK_IntegralToFloating:
512 case CK_FloatingToIntegral:
513 case CK_FloatingToBoolean:
514 case CK_FloatingCast:
515 case CK_CPointerToObjCPointerCast:
516 case CK_BlockPointerToObjCPointerCast:
517 case CK_AnyPointerToBlockPointerCast:
518 case CK_ObjCObjectLValueCast:
519 case CK_FloatingComplexToReal:
520 case CK_FloatingComplexToBoolean:
521 case CK_IntegralComplexToReal:
522 case CK_IntegralComplexToBoolean:
523 case CK_ARCProduceObject:
524 case CK_ARCConsumeObject:
525 case CK_ARCReclaimReturnedObject:
526 case CK_ARCExtendBlockObject:
527 case CK_CopyAndAutoreleaseBlockObject:
528 case CK_BuiltinFnToFnPtr:
529 case CK_ZeroToOCLOpaqueType:
530 case CK_AddressSpaceConversion:
531 case CK_IntToOCLSampler:
532 case CK_FloatingToFixedPoint:
533 case CK_FixedPointToFloating:
534 case CK_FixedPointCast:
535 case CK_FixedPointToBoolean:
536 case CK_FixedPointToIntegral:
537 case CK_IntegralToFixedPoint:
538 case CK_MatrixCast:
539 case CK_HLSLVectorTruncation:
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: {
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: {
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 = VisitPlusMinus(e, cir::UnaryOpKind::Plus, promotionTy);
568 if (!promotionTy.isNull())
569 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
570 return result;
571}
572
573mlir::Value ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *e) {
574 QualType promotionTy = getPromotionType(e->getSubExpr()->getType());
575 mlir::Value result = VisitPlusMinus(e, cir::UnaryOpKind::Minus, promotionTy);
576 if (!promotionTy.isNull())
577 return cgf.emitUnPromotedValue(result, e->getSubExpr()->getType());
578 return result;
579}
580
581mlir::Value ComplexExprEmitter::VisitPlusMinus(const UnaryOperator *e,
582 cir::UnaryOpKind kind,
583 QualType promotionType) {
584 assert(kind == cir::UnaryOpKind::Plus ||
585 kind == cir::UnaryOpKind::Minus &&
586 "Invalid UnaryOp kind for ComplexType Plus or Minus");
587
588 mlir::Value op;
589 if (!promotionType.isNull())
590 op = cgf.emitPromotedComplexExpr(e->getSubExpr(), promotionType);
591 else
592 op = Visit(e->getSubExpr());
593 return builder.createUnaryOp(cgf.getLoc(e->getExprLoc()), kind, op);
594}
595
596mlir::Value ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *e) {
597 mlir::Value op = Visit(e->getSubExpr());
598 return builder.createNot(op);
599}
600
601mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo &op) {
604
605 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
606 mlir::isa<cir::ComplexType>(op.rhs.getType()))
607 return builder.create<cir::ComplexAddOp>(op.loc, op.lhs, op.rhs);
608
609 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
610 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
611 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
612 mlir::Value newReal = builder.createAdd(op.loc, real, op.rhs);
613 return builder.createComplexCreate(op.loc, newReal, imag);
614 }
615
616 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
617 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
618 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
619 mlir::Value newReal = builder.createAdd(op.loc, op.lhs, real);
620 return builder.createComplexCreate(op.loc, newReal, imag);
621}
622
623mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo &op) {
626
627 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
628 mlir::isa<cir::ComplexType>(op.rhs.getType()))
629 return builder.create<cir::ComplexSubOp>(op.loc, op.lhs, op.rhs);
630
631 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
632 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
633 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
634 mlir::Value newReal = builder.createSub(op.loc, real, op.rhs);
635 return builder.createComplexCreate(op.loc, newReal, imag);
636 }
637
638 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
639 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
640 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
641 mlir::Value newReal = builder.createSub(op.loc, op.lhs, real);
642 return builder.createComplexCreate(op.loc, newReal, imag);
643}
644
645static cir::ComplexRangeKind
647 switch (range) {
648 case LangOptions::CX_Full:
649 return cir::ComplexRangeKind::Full;
650 case LangOptions::CX_Improved:
651 return cir::ComplexRangeKind::Improved;
652 case LangOptions::CX_Promoted:
653 return cir::ComplexRangeKind::Promoted;
654 case LangOptions::CX_Basic:
655 return cir::ComplexRangeKind::Basic;
656 case LangOptions::CX_None:
657 // The default value for ComplexRangeKind is Full if no option is selected
658 return cir::ComplexRangeKind::Full;
659 }
660}
661
662mlir::Value ComplexExprEmitter::emitBinMul(const BinOpInfo &op) {
665
666 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
667 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
668 cir::ComplexRangeKind rangeKind =
669 getComplexRangeAttr(op.fpFeatures.getComplexRange());
670 return builder.create<cir::ComplexMulOp>(op.loc, op.lhs, op.rhs, rangeKind);
671 }
672
673 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
674 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
675 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
676 mlir::Value newReal = builder.createMul(op.loc, real, op.rhs);
677 mlir::Value newImag = builder.createMul(op.loc, imag, op.rhs);
678 return builder.createComplexCreate(op.loc, newReal, newImag);
679 }
680
681 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
682 mlir::Value real = builder.createComplexReal(op.loc, op.rhs);
683 mlir::Value imag = builder.createComplexImag(op.loc, op.rhs);
684 mlir::Value newReal = builder.createMul(op.loc, op.lhs, real);
685 mlir::Value newImag = builder.createMul(op.loc, op.lhs, imag);
686 return builder.createComplexCreate(op.loc, newReal, newImag);
687}
688
689mlir::Value ComplexExprEmitter::emitBinDiv(const BinOpInfo &op) {
692
693 // Handle division between two complex values. In the case of complex integer
694 // types mixed with scalar integers, the scalar integer type will always be
695 // promoted to a complex integer value with a zero imaginary component when
696 // the AST is formed.
697 if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
698 mlir::isa<cir::ComplexType>(op.rhs.getType())) {
699 cir::ComplexRangeKind rangeKind =
700 getComplexRangeAttr(op.fpFeatures.getComplexRange());
701 return cir::ComplexDivOp::create(builder, op.loc, op.lhs, op.rhs,
702 rangeKind);
703 }
704
705 // The C99 standard (G.5.1) defines division of a complex value by a real
706 // value in the following simplified form.
707 if (mlir::isa<cir::ComplexType>(op.lhs.getType())) {
708 assert(mlir::cast<cir::ComplexType>(op.lhs.getType()).getElementType() ==
709 op.rhs.getType());
710 mlir::Value real = builder.createComplexReal(op.loc, op.lhs);
711 mlir::Value imag = builder.createComplexImag(op.loc, op.lhs);
712 mlir::Value newReal = builder.createFDiv(op.loc, real, op.rhs);
713 mlir::Value newImag = builder.createFDiv(op.loc, imag, op.rhs);
714 return builder.createComplexCreate(op.loc, newReal, newImag);
715 }
716
717 assert(mlir::isa<cir::ComplexType>(op.rhs.getType()));
718 cir::ConstantOp nullValue = builder.getNullValue(op.lhs.getType(), op.loc);
719 mlir::Value lhs = builder.createComplexCreate(op.loc, op.lhs, nullValue);
720 cir::ComplexRangeKind rangeKind =
721 getComplexRangeAttr(op.fpFeatures.getComplexRange());
722 return cir::ComplexDivOp::create(builder, op.loc, lhs, op.rhs, rangeKind);
723}
724
725mlir::Value CIRGenFunction::emitUnPromotedValue(mlir::Value result,
726 QualType unPromotionType) {
727 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
728 "integral complex will never be promoted");
729 return builder.createCast(cir::CastKind::float_complex, result,
730 convertType(unPromotionType));
731}
732
733mlir::Value CIRGenFunction::emitPromotedValue(mlir::Value result,
734 QualType promotionType) {
735 assert(!mlir::cast<cir::ComplexType>(result.getType()).isIntegerComplex() &&
736 "integral complex will never be promoted");
737 return builder.createCast(cir::CastKind::float_complex, result,
738 convertType(promotionType));
739}
740
741mlir::Value ComplexExprEmitter::emitPromoted(const Expr *e,
742 QualType promotionTy) {
743 e = e->IgnoreParens();
744 if (const auto *bo = dyn_cast<BinaryOperator>(e)) {
745 switch (bo->getOpcode()) {
746#define HANDLE_BINOP(OP) \
747 case BO_##OP: \
748 return emitBin##OP(emitBinOps(bo, promotionTy));
749 HANDLE_BINOP(Add)
750 HANDLE_BINOP(Sub)
751 HANDLE_BINOP(Mul)
752#undef HANDLE_BINOP
753 default:
754 break;
755 }
756 } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(e)) {
757 switch (unaryOp->getOpcode()) {
758 case UO_Minus:
759 case UO_Plus: {
760 auto kind = unaryOp->getOpcode() == UO_Plus ? cir::UnaryOpKind::Plus
761 : cir::UnaryOpKind::Minus;
762 return VisitPlusMinus(unaryOp, kind, promotionTy);
763 }
764 default:
765 break;
766 }
767 }
768
769 mlir::Value result = Visit(const_cast<Expr *>(e));
770 if (!promotionTy.isNull())
771 return cgf.emitPromotedValue(result, promotionTy);
772
773 return result;
774}
775
777 QualType promotionType) {
778 return ComplexExprEmitter(*this).emitPromoted(e, promotionType);
779}
780
781mlir::Value
782ComplexExprEmitter::emitPromotedComplexOperand(const Expr *e,
783 QualType promotionTy) {
784 if (e->getType()->isAnyComplexType()) {
785 if (!promotionTy.isNull())
786 return cgf.emitPromotedComplexExpr(e, promotionTy);
787 return Visit(const_cast<Expr *>(e));
788 }
789
790 if (!promotionTy.isNull()) {
791 QualType complexElementTy =
792 promotionTy->castAs<ComplexType>()->getElementType();
793 return cgf.emitPromotedScalarExpr(e, complexElementTy);
794 }
795 return cgf.emitScalarExpr(e);
796}
797
798ComplexExprEmitter::BinOpInfo
799ComplexExprEmitter::emitBinOps(const BinaryOperator *e, QualType promotionTy) {
800 BinOpInfo binOpInfo{cgf.getLoc(e->getExprLoc())};
801 binOpInfo.lhs = emitPromotedComplexOperand(e->getLHS(), promotionTy);
802 binOpInfo.rhs = emitPromotedComplexOperand(e->getRHS(), promotionTy);
803 binOpInfo.ty = promotionTy.isNull() ? e->getType() : promotionTy;
804 binOpInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
805 return binOpInfo;
806}
807
808LValue ComplexExprEmitter::emitCompoundAssignLValue(
809 const CompoundAssignOperator *e,
810 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &), RValue &value) {
811 QualType lhsTy = e->getLHS()->getType();
812 QualType rhsTy = e->getRHS()->getType();
813 SourceLocation exprLoc = e->getExprLoc();
814 mlir::Location loc = cgf.getLoc(exprLoc);
815
816 if (lhsTy->getAs<AtomicType>()) {
817 cgf.cgm.errorNYI("emitCompoundAssignLValue AtmoicType");
818 return {};
819 }
820
821 BinOpInfo opInfo{loc};
822 opInfo.fpFeatures = e->getFPFeaturesInEffect(cgf.getLangOpts());
823
825
826 // Load the RHS and LHS operands.
827 // __block variables need to have the rhs evaluated first, plus this should
828 // improve codegen a little.
829 QualType promotionTypeCR = getPromotionType(e->getComputationResultType());
830 opInfo.ty = promotionTypeCR.isNull() ? e->getComputationResultType()
831 : promotionTypeCR;
832
833 QualType complexElementTy =
834 opInfo.ty->castAs<ComplexType>()->getElementType();
835 QualType promotionTypeRHS = getPromotionType(rhsTy);
836
837 // The RHS should have been converted to the computation type.
838 if (e->getRHS()->getType()->isRealFloatingType()) {
839 if (!promotionTypeRHS.isNull()) {
840 opInfo.rhs = cgf.emitPromotedScalarExpr(e->getRHS(), promotionTypeRHS);
841 } else {
842 assert(cgf.getContext().hasSameUnqualifiedType(complexElementTy, rhsTy));
843 opInfo.rhs = cgf.emitScalarExpr(e->getRHS());
844 }
845 } else {
846 if (!promotionTypeRHS.isNull()) {
847 opInfo.rhs = cgf.emitPromotedComplexExpr(e->getRHS(), promotionTypeRHS);
848 } else {
849 assert(cgf.getContext().hasSameUnqualifiedType(opInfo.ty, rhsTy));
850 opInfo.rhs = Visit(e->getRHS());
851 }
852 }
853
854 LValue lhs = cgf.emitLValue(e->getLHS());
855
856 // Load from the l-value and convert it.
857 QualType promotionTypeLHS = getPromotionType(e->getComputationLHSType());
858 if (lhsTy->isAnyComplexType()) {
859 mlir::Value lhsValue = emitLoadOfLValue(lhs, exprLoc);
860 QualType destTy = promotionTypeLHS.isNull() ? opInfo.ty : promotionTypeLHS;
861 opInfo.lhs = emitComplexToComplexCast(lhsValue, lhsTy, destTy, exprLoc);
862 } else {
863 mlir::Value lhsVal = cgf.emitLoadOfScalar(lhs, exprLoc);
864 // For floating point real operands we can directly pass the scalar form
865 // to the binary operator emission and potentially get more efficient code.
866 if (lhsTy->isRealFloatingType()) {
867 QualType promotedComplexElementTy;
868 if (!promotionTypeLHS.isNull()) {
869 promotedComplexElementTy =
870 cast<ComplexType>(promotionTypeLHS)->getElementType();
871 if (!cgf.getContext().hasSameUnqualifiedType(promotedComplexElementTy,
872 promotionTypeLHS))
873 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy,
874 promotedComplexElementTy, exprLoc);
875 } else {
876 if (!cgf.getContext().hasSameUnqualifiedType(complexElementTy, lhsTy))
877 lhsVal = cgf.emitScalarConversion(lhsVal, lhsTy, complexElementTy,
878 exprLoc);
879 }
880 opInfo.lhs = lhsVal;
881 } else {
882 opInfo.lhs = emitScalarToComplexCast(lhsVal, lhsTy, opInfo.ty, exprLoc);
883 }
884 }
885
886 // Expand the binary operator.
887 mlir::Value result = (this->*func)(opInfo);
888
889 // Truncate the result and store it into the LHS lvalue.
890 if (lhsTy->isAnyComplexType()) {
891 mlir::Value resultValue =
892 emitComplexToComplexCast(result, opInfo.ty, lhsTy, exprLoc);
893 emitStoreOfComplex(loc, resultValue, lhs, /*isInit*/ false);
894 value = RValue::getComplex(resultValue);
895 } else {
896 mlir::Value resultValue =
897 cgf.emitComplexToScalarConversion(result, opInfo.ty, lhsTy, exprLoc);
898 cgf.emitStoreOfScalar(resultValue, lhs, /*isInit*/ false);
899 value = RValue::get(resultValue);
900 }
901
902 return lhs;
903}
904
905mlir::Value ComplexExprEmitter::emitCompoundAssign(
906 const CompoundAssignOperator *e,
907 mlir::Value (ComplexExprEmitter::*func)(const BinOpInfo &)) {
908 RValue val;
909 LValue lv = emitCompoundAssignLValue(e, func, val);
910
911 // The result of an assignment in C is the assigned r-value.
912 if (!cgf.getLangOpts().CPlusPlus)
913 return val.getComplexValue();
914
915 // If the lvalue is non-volatile, return the computed value of the assignment.
916 if (!lv.isVolatileQualified())
917 return val.getComplexValue();
918
919 return emitLoadOfLValue(lv, e->getExprLoc());
920}
921
922LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
923 mlir::Value &value) {
924 assert(cgf.getContext().hasSameUnqualifiedType(e->getLHS()->getType(),
925 e->getRHS()->getType()) &&
926 "Invalid assignment");
927
928 // Emit the RHS. __block variables need the RHS evaluated first.
929 value = Visit(e->getRHS());
930
931 // Compute the address to store into.
932 LValue lhs = cgf.emitLValue(e->getLHS());
933
934 // Store the result value into the LHS lvalue.
935 emitStoreOfComplex(cgf.getLoc(e->getExprLoc()), value, lhs,
936 /*isInit*/ false);
937 return lhs;
938}
939
940mlir::Value ComplexExprEmitter::VisitBinAssign(const BinaryOperator *e) {
941 mlir::Value value;
942 LValue lv = emitBinAssignLValue(e, value);
943
944 // The result of an assignment in C is the assigned r-value.
945 if (!cgf.getLangOpts().CPlusPlus)
946 return value;
947
948 // If the lvalue is non-volatile, return the computed value of the
949 // assignment.
950 if (!lv.isVolatile())
951 return value;
952
953 return emitLoadOfLValue(lv, e->getExprLoc());
954}
955
956mlir::Value ComplexExprEmitter::VisitBinComma(const BinaryOperator *e) {
957 cgf.emitIgnoredExpr(e->getLHS());
958 return Visit(e->getRHS());
959}
960
961mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
963 mlir::Value condValue = Visit(e->getCond());
964 mlir::Location loc = cgf.getLoc(e->getSourceRange());
965
966 return builder
967 .create<cir::TernaryOp>(
968 loc, condValue,
969 /*thenBuilder=*/
970 [&](mlir::OpBuilder &b, mlir::Location loc) {
971 mlir::Value trueValue = Visit(e->getTrueExpr());
972 b.create<cir::YieldOp>(loc, trueValue);
973 },
974 /*elseBuilder=*/
975 [&](mlir::OpBuilder &b, mlir::Location loc) {
976 mlir::Value falseValue = Visit(e->getFalseExpr());
977 b.create<cir::YieldOp>(loc, falseValue);
978 })
979 .getResult();
980}
981
982mlir::Value ComplexExprEmitter::VisitChooseExpr(ChooseExpr *e) {
983 return Visit(e->getChosenSubExpr());
984}
985
986mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
987 mlir::Location loc = cgf.getLoc(e->getExprLoc());
988 if (e->getNumInits() == 2) {
989 mlir::Value real = cgf.emitScalarExpr(e->getInit(0));
990 mlir::Value imag = cgf.emitScalarExpr(e->getInit(1));
991 return builder.createComplexCreate(loc, real, imag);
992 }
993
994 if (e->getNumInits() == 1)
995 return Visit(e->getInit(0));
996
997 assert(e->getNumInits() == 0 && "Unexpected number of inits");
998 mlir::Type complexTy = cgf.convertType(e->getType());
999 return builder.getNullValue(complexTy, loc);
1000}
1001
1002mlir::Value ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *e) {
1003 return cgf.emitVAArg(e);
1004}
1005
1006//===----------------------------------------------------------------------===//
1007// Entry Point into this File
1008//===----------------------------------------------------------------------===//
1009
1010/// EmitComplexExpr - Emit the computation of the specified expression of
1011/// complex type, ignoring the result.
1013 assert(e && getComplexType(e->getType()) &&
1014 "Invalid complex expression to emit");
1015
1016 return ComplexExprEmitter(*this).Visit(const_cast<Expr *>(e));
1017}
1018
1020 bool isInit) {
1021 assert(e && getComplexType(e->getType()) &&
1022 "Invalid complex expression to emit");
1023 ComplexExprEmitter emitter(*this);
1024 mlir::Value value = emitter.Visit(const_cast<Expr *>(e));
1025 emitter.emitStoreOfComplex(getLoc(e->getExprLoc()), value, dest, isInit);
1026}
1027
1028/// EmitStoreOfComplex - Store a complex number into the specified l-value.
1029void CIRGenFunction::emitStoreOfComplex(mlir::Location loc, mlir::Value v,
1030 LValue dest, bool isInit) {
1031 ComplexExprEmitter(*this).emitStoreOfComplex(loc, v, dest, isInit);
1032}
1033
1035 return ComplexExprEmitter(*this).emitLoadOfLValue(src, loc);
1036}
1037
1039 assert(e->getOpcode() == BO_Assign && "Expected assign op");
1040
1041 mlir::Value value; // ignored
1042 LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
1043 if (getLangOpts().OpenMP)
1044 cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
1045
1046 return lvalue;
1047}
1048
1050 mlir::Value (ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &);
1051
1053 switch (op) {
1054 case BO_MulAssign:
1055 return &ComplexExprEmitter::emitBinMul;
1056 case BO_DivAssign:
1057 return &ComplexExprEmitter::emitBinDiv;
1058 case BO_SubAssign:
1059 return &ComplexExprEmitter::emitBinSub;
1060 case BO_AddAssign:
1061 return &ComplexExprEmitter::emitBinAdd;
1062 default:
1063 llvm_unreachable("unexpected complex compound assignment");
1064 }
1065}
1066
1068 const CompoundAssignOperator *e) {
1070 RValue val;
1071 return ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, val);
1072}
1073
1075 LValue lv,
1076 cir::UnaryOpKind op,
1077 bool isPre) {
1078 assert(op == cir::UnaryOpKind::Inc ||
1079 op == cir::UnaryOpKind::Dec && "Invalid UnaryOp kind for ComplexType");
1080
1081 mlir::Value inVal = emitLoadOfComplex(lv, e->getExprLoc());
1082 mlir::Location loc = getLoc(e->getExprLoc());
1083 mlir::Value incVal = builder.createUnaryOp(loc, op, inVal);
1084
1085 // Store the updated result through the lvalue.
1086 emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
1087
1088 if (getLangOpts().OpenMP)
1089 cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
1090
1091 // If this is a postinc, return the value read from memory, otherwise use the
1092 // updated value.
1093 return isPre ? incVal : inVal;
1094}
1095
1097 const CompoundAssignOperator *e, mlir::Value &result) {
1098 // Key Instructions: Don't need to create an atom group here; one will already
1099 // be active through scalar handling code.
1101 RValue value;
1102 LValue ret = ComplexExprEmitter(*this).emitCompoundAssignLValue(e, op, value);
1103 result = value.getValue();
1104 return ret;
1105}
#define HANDLEBINOP(OP)
static CompoundFunc getComplexOp(BinaryOperatorKind op)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
static cir::ComplexRangeKind getComplexRangeAttr(LangOptions::ComplexRangeKind range)
mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc
#define HANDLE_BINOP(OP)
__device__ __2f16 b
__device__ __2f16 float __ockl_bool s
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
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)
CanQualType FloatTy
Definition: ASTContext.h:1234
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2898
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Definition: Expr.h:4289
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
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
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition: Expr.h:6816
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
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
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.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, bool isInit=false, bool isNontemporal=false)
Definition: CIRGenExpr.cpp:312
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...
Definition: CIRGenExpr.cpp:585
void emitComplexExprIntoLValue(const Expr *e, LValue dest, bool isInit)
ConstantEmission tryEmitAsConstant(const DeclRefExpr *refExpr)
Try to emit a reference to the given value without producing it as an l-value.
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.
Address getAddress() const
Definition: CIRGenValue.h:211
clang::QualType getType() const
Definition: CIRGenValue.h:202
bool isVolatileQualified() const
Definition: CIRGenValue.h:196
bool isVolatile() const
Definition: CIRGenValue.h:194
bool isSimple() const
Definition: CIRGenValue.h:190
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
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1271
SourceLocation getExprLoc() const
Definition: ExprCXX.h:1352
A use of a default initializer in a constructor or in aggregate initialization.
Definition: ExprCXX.h:1378
A rewritten comparison expression that was originally written using operator syntax.
Definition: ExprCXX.h:286
SourceLocation getExprLoc() const LLVM_READONLY
Definition: ExprCXX.h:341
An expression "T()" which creates an rvalue of a non-class type T.
Definition: ExprCXX.h:2198
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
Definition: Expr.cpp:1599
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:3612
CastKind getCastKind() const
Definition: Expr.h:3656
bool changesVolatileQualification() const
Return.
Definition: Expr.h:3746
Expr * getSubExpr()
Definition: Expr.h:3662
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition: Expr.h:4784
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Definition: Expr.h:4820
Represents a 'co_await' expression.
Definition: ExprCXX.h:5363
Complex values, per C99 6.2.5p11.
Definition: TypeBase.h:3293
CompoundAssignOperator - For compound assignments (e.g.
Definition: Expr.h:4236
QualType getComputationLHSType() const
Definition: Expr.h:4270
QualType getComputationResultType() const
Definition: Expr.h:4273
CompoundLiteralExpr - [C99 6.5.2.5].
Definition: Expr.h:3541
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition: Expr.h:1084
Represents a 'co_yield' expression.
Definition: ExprCXX.h:5444
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3655
This represents one expression.
Definition: Expr.h:112
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
Represents a C11 generic selection.
Definition: Expr.h:6114
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition: Expr.h:6398
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition: Expr.h:1733
const Expr * getSubExpr() const
Definition: Expr.h:1745
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3789
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5993
Describes an C or C++ initializer list.
Definition: Expr.h:5235
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.
Definition: LangOptions.h:375
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3300
Expr * getBase() const
Definition: Expr.h:3377
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:548
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1180
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:1210
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2184
const Expr * getSubExpr() const
Definition: Expr.h:2201
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6692
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.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition: Expr.h:4531
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Definition: StmtVisitor.h:45
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
Stmt - This represents one statement.
Definition: Stmt.h:85
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition: ExprCXX.h:4658
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: TypeBase.h:8980
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isReferenceType() const
Definition: TypeBase.h:8604
bool isAnyComplexType() const
Definition: TypeBase.h:8715
bool isAtomicType() const
Definition: TypeBase.h:8762
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2324
bool isFloatingType() const
Definition: Type.cpp:2308
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
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
Represents a call to the builtin function __builtin_va_arg.
Definition: Expr.h:4893
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
BinaryOperatorKind
CastKind
CastKind - The kind of operation required for a conversion.
static bool cgFPOptionsRAII()
static bool fastMathFlags()