Skip to content

Commit eb817c7

Browse files
authored
[CIR] Upstream Cast kinds for ComplexType (#149717)
This change adds support for cast kinds for ComplexType #141365
1 parent e67f323 commit eb817c7

File tree

6 files changed

+708
-11
lines changed

6 files changed

+708
-11
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ def CIR_CastKind : CIR_I32EnumAttr<"CastKind", "cast kind", [
128128
// CK_BlockPointerToObjCPointerCast
129129
// CK_AnyPointerToBlockPointerCast
130130
// CK_ObjCObjectLValueCast
131-
// I32EnumAttrCase<"float_to_complex", 44>,
132-
// I32EnumAttrCase<"float_complex_to_real", 45>,
133-
// I32EnumAttrCase<"float_complex_to_bool", 46>,
131+
I32EnumAttrCase<"float_to_complex", 44>,
132+
I32EnumAttrCase<"float_complex_to_real", 45>,
133+
I32EnumAttrCase<"float_complex_to_bool", 46>,
134134
I32EnumAttrCase<"float_complex", 47>,
135-
// I32EnumAttrCase<"float_complex_to_int_complex", 48>,
136-
// I32EnumAttrCase<"int_to_complex", 49>,
135+
I32EnumAttrCase<"float_complex_to_int_complex", 48>,
136+
I32EnumAttrCase<"int_to_complex", 49>,
137137
I32EnumAttrCase<"int_complex_to_real", 50>,
138138
I32EnumAttrCase<"int_complex_to_bool", 51>,
139139
I32EnumAttrCase<"int_complex", 52>,

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 148 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,20 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
3434
}
3535

3636
mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
37+
3738
/// Store the specified real/imag parts into the
3839
/// specified value pointer.
3940
void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
4041
bool isInit);
4142

43+
/// Emit a cast from complex value Val to DestType.
44+
mlir::Value emitComplexToComplexCast(mlir::Value value, QualType srcType,
45+
QualType destType, SourceLocation loc);
46+
47+
/// Emit a cast from scalar value Val to DestType.
48+
mlir::Value emitScalarToComplexCast(mlir::Value value, QualType srcType,
49+
QualType destType, SourceLocation loc);
50+
4251
mlir::Value
4352
VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
4453
mlir::Value VisitArraySubscriptExpr(Expr *e);
@@ -164,14 +173,106 @@ LValue ComplexExprEmitter::emitBinAssignLValue(const BinaryOperator *e,
164173
mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op,
165174
QualType destTy) {
166175
switch (ck) {
176+
case CK_Dependent:
177+
llvm_unreachable("dependent type must be resolved before the CIR codegen");
178+
167179
case CK_NoOp:
168180
case CK_LValueToRValue:
169181
return Visit(op);
170-
default:
171-
break;
182+
183+
case CK_AtomicToNonAtomic:
184+
case CK_NonAtomicToAtomic:
185+
case CK_UserDefinedConversion: {
186+
cgf.cgm.errorNYI(
187+
"ComplexExprEmitter::emitCast Atmoic & UserDefinedConversion");
188+
return {};
172189
}
173-
cgf.cgm.errorNYI("ComplexType Cast");
174-
return {};
190+
191+
case CK_LValueBitCast: {
192+
cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueBitCast");
193+
return {};
194+
}
195+
196+
case CK_LValueToRValueBitCast: {
197+
cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueToRValueBitCast");
198+
return {};
199+
}
200+
201+
case CK_BitCast:
202+
case CK_BaseToDerived:
203+
case CK_DerivedToBase:
204+
case CK_UncheckedDerivedToBase:
205+
case CK_Dynamic:
206+
case CK_ToUnion:
207+
case CK_ArrayToPointerDecay:
208+
case CK_FunctionToPointerDecay:
209+
case CK_NullToPointer:
210+
case CK_NullToMemberPointer:
211+
case CK_BaseToDerivedMemberPointer:
212+
case CK_DerivedToBaseMemberPointer:
213+
case CK_MemberPointerToBoolean:
214+
case CK_ReinterpretMemberPointer:
215+
case CK_ConstructorConversion:
216+
case CK_IntegralToPointer:
217+
case CK_PointerToIntegral:
218+
case CK_PointerToBoolean:
219+
case CK_ToVoid:
220+
case CK_VectorSplat:
221+
case CK_IntegralCast:
222+
case CK_BooleanToSignedIntegral:
223+
case CK_IntegralToBoolean:
224+
case CK_IntegralToFloating:
225+
case CK_FloatingToIntegral:
226+
case CK_FloatingToBoolean:
227+
case CK_FloatingCast:
228+
case CK_CPointerToObjCPointerCast:
229+
case CK_BlockPointerToObjCPointerCast:
230+
case CK_AnyPointerToBlockPointerCast:
231+
case CK_ObjCObjectLValueCast:
232+
case CK_FloatingComplexToReal:
233+
case CK_FloatingComplexToBoolean:
234+
case CK_IntegralComplexToReal:
235+
case CK_IntegralComplexToBoolean:
236+
case CK_ARCProduceObject:
237+
case CK_ARCConsumeObject:
238+
case CK_ARCReclaimReturnedObject:
239+
case CK_ARCExtendBlockObject:
240+
case CK_CopyAndAutoreleaseBlockObject:
241+
case CK_BuiltinFnToFnPtr:
242+
case CK_ZeroToOCLOpaqueType:
243+
case CK_AddressSpaceConversion:
244+
case CK_IntToOCLSampler:
245+
case CK_FloatingToFixedPoint:
246+
case CK_FixedPointToFloating:
247+
case CK_FixedPointCast:
248+
case CK_FixedPointToBoolean:
249+
case CK_FixedPointToIntegral:
250+
case CK_IntegralToFixedPoint:
251+
case CK_MatrixCast:
252+
case CK_HLSLVectorTruncation:
253+
case CK_HLSLArrayRValue:
254+
case CK_HLSLElementwiseCast:
255+
case CK_HLSLAggregateSplatCast:
256+
llvm_unreachable("invalid cast kind for complex value");
257+
258+
case CK_FloatingRealToComplex:
259+
case CK_IntegralRealToComplex: {
260+
assert(!cir::MissingFeatures::cgFPOptionsRAII());
261+
return emitScalarToComplexCast(cgf.emitScalarExpr(op), op->getType(),
262+
destTy, op->getExprLoc());
263+
}
264+
265+
case CK_FloatingComplexCast:
266+
case CK_FloatingComplexToIntegralComplex:
267+
case CK_IntegralComplexCast:
268+
case CK_IntegralComplexToFloatingComplex: {
269+
assert(!cir::MissingFeatures::cgFPOptionsRAII());
270+
return emitComplexToComplexCast(Visit(op), op->getType(), destTy,
271+
op->getExprLoc());
272+
}
273+
}
274+
275+
llvm_unreachable("unknown cast resulting in complex value");
175276
}
176277

177278
mlir::Value ComplexExprEmitter::emitConstant(
@@ -207,6 +308,49 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
207308
builder.createStore(loc, val, destAddr);
208309
}
209310

311+
mlir::Value ComplexExprEmitter::emitComplexToComplexCast(mlir::Value val,
312+
QualType srcType,
313+
QualType destType,
314+
SourceLocation loc) {
315+
if (srcType == destType)
316+
return val;
317+
318+
// Get the src/dest element type.
319+
QualType srcElemTy = srcType->castAs<ComplexType>()->getElementType();
320+
QualType destElemTy = destType->castAs<ComplexType>()->getElementType();
321+
322+
cir::CastKind castOpKind;
323+
if (srcElemTy->isFloatingType() && destElemTy->isFloatingType())
324+
castOpKind = cir::CastKind::float_complex;
325+
else if (srcElemTy->isFloatingType() && destElemTy->isIntegerType())
326+
castOpKind = cir::CastKind::float_complex_to_int_complex;
327+
else if (srcElemTy->isIntegerType() && destElemTy->isFloatingType())
328+
castOpKind = cir::CastKind::int_complex_to_float_complex;
329+
else if (srcElemTy->isIntegerType() && destElemTy->isIntegerType())
330+
castOpKind = cir::CastKind::int_complex;
331+
else
332+
llvm_unreachable("unexpected src type or dest type");
333+
334+
return builder.createCast(cgf.getLoc(loc), castOpKind, val,
335+
cgf.convertType(destType));
336+
}
337+
338+
mlir::Value ComplexExprEmitter::emitScalarToComplexCast(mlir::Value val,
339+
QualType srcType,
340+
QualType destType,
341+
SourceLocation loc) {
342+
cir::CastKind castOpKind;
343+
if (srcType->isFloatingType())
344+
castOpKind = cir::CastKind::float_to_complex;
345+
else if (srcType->isIntegerType())
346+
castOpKind = cir::CastKind::int_to_complex;
347+
else
348+
llvm_unreachable("unexpected src type");
349+
350+
return builder.createCast(cgf.getLoc(loc), castOpKind, val,
351+
cgf.convertType(destType));
352+
}
353+
210354
mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
211355
const AbstractConditionalOperator *e) {
212356
mlir::Value condValue = Visit(e->getCond());

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
8888
// Utilities
8989
//===--------------------------------------------------------------------===//
9090

91+
mlir::Value emitComplexToScalarConversion(mlir::Location loc,
92+
mlir::Value value, CastKind kind,
93+
QualType destTy);
94+
9195
mlir::Value emitPromotedValue(mlir::Value result, QualType promotionType) {
9296
return builder.createFloatingCast(result, cgf.convertType(promotionType));
9397
}
@@ -1135,6 +1139,31 @@ LValue ScalarExprEmitter::emitCompoundAssignLValue(
11351139
return lhsLV;
11361140
}
11371141

1142+
mlir::Value ScalarExprEmitter::emitComplexToScalarConversion(mlir::Location lov,
1143+
mlir::Value value,
1144+
CastKind kind,
1145+
QualType destTy) {
1146+
cir::CastKind castOpKind;
1147+
switch (kind) {
1148+
case CK_FloatingComplexToReal:
1149+
castOpKind = cir::CastKind::float_complex_to_real;
1150+
break;
1151+
case CK_IntegralComplexToReal:
1152+
castOpKind = cir::CastKind::int_complex_to_real;
1153+
break;
1154+
case CK_FloatingComplexToBoolean:
1155+
castOpKind = cir::CastKind::float_complex_to_bool;
1156+
break;
1157+
case CK_IntegralComplexToBoolean:
1158+
castOpKind = cir::CastKind::int_complex_to_bool;
1159+
break;
1160+
default:
1161+
llvm_unreachable("invalid complex-to-scalar cast kind");
1162+
}
1163+
1164+
return builder.createCast(lov, castOpKind, value, cgf.convertType(destTy));
1165+
}
1166+
11381167
mlir::Value ScalarExprEmitter::emitPromoted(const Expr *e,
11391168
QualType promotionType) {
11401169
e = e->IgnoreParens();
@@ -1758,6 +1787,15 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
17581787
ce->getExprLoc(), opts);
17591788
}
17601789

1790+
case CK_FloatingComplexToReal:
1791+
case CK_IntegralComplexToReal:
1792+
case CK_FloatingComplexToBoolean:
1793+
case CK_IntegralComplexToBoolean: {
1794+
mlir::Value value = cgf.emitComplexExpr(subExpr);
1795+
return emitComplexToScalarConversion(cgf.getLoc(ce->getExprLoc()), value,
1796+
kind, destTy);
1797+
}
1798+
17611799
case CK_FloatingRealToComplex:
17621800
case CK_FloatingComplexCast:
17631801
case CK_IntegralRealToComplex:

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,104 @@ LogicalResult cir::CastOp::verify() {
489489
return emitOpError() << "requires two types differ in addrspace only";
490490
return success();
491491
}
492+
case cir::CastKind::float_to_complex: {
493+
if (!mlir::isa<cir::FPTypeInterface>(srcType))
494+
return emitOpError() << "requires !cir.float type for source";
495+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
496+
if (!resComplexTy)
497+
return emitOpError() << "requires !cir.complex type for result";
498+
if (srcType != resComplexTy.getElementType())
499+
return emitOpError() << "requires source type match result element type";
500+
return success();
501+
}
502+
case cir::CastKind::int_to_complex: {
503+
if (!mlir::isa<cir::IntType>(srcType))
504+
return emitOpError() << "requires !cir.int type for source";
505+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
506+
if (!resComplexTy)
507+
return emitOpError() << "requires !cir.complex type for result";
508+
if (srcType != resComplexTy.getElementType())
509+
return emitOpError() << "requires source type match result element type";
510+
return success();
511+
}
512+
case cir::CastKind::float_complex_to_real: {
513+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
514+
if (!srcComplexTy)
515+
return emitOpError() << "requires !cir.complex type for source";
516+
if (!mlir::isa<cir::FPTypeInterface>(resType))
517+
return emitOpError() << "requires !cir.float type for result";
518+
if (srcComplexTy.getElementType() != resType)
519+
return emitOpError() << "requires source element type match result type";
520+
return success();
521+
}
522+
case cir::CastKind::int_complex_to_real: {
523+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
524+
if (!srcComplexTy)
525+
return emitOpError() << "requires !cir.complex type for source";
526+
if (!mlir::isa<cir::IntType>(resType))
527+
return emitOpError() << "requires !cir.int type for result";
528+
if (srcComplexTy.getElementType() != resType)
529+
return emitOpError() << "requires source element type match result type";
530+
return success();
531+
}
532+
case cir::CastKind::float_complex_to_bool: {
533+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
534+
if (!srcComplexTy || !srcComplexTy.isFloatingPointComplex())
535+
return emitOpError()
536+
<< "requires floating point !cir.complex type for source";
537+
if (!mlir::isa<cir::BoolType>(resType))
538+
return emitOpError() << "requires !cir.bool type for result";
539+
return success();
540+
}
541+
case cir::CastKind::int_complex_to_bool: {
542+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
543+
if (!srcComplexTy || !srcComplexTy.isIntegerComplex())
544+
return emitOpError()
545+
<< "requires floating point !cir.complex type for source";
546+
if (!mlir::isa<cir::BoolType>(resType))
547+
return emitOpError() << "requires !cir.bool type for result";
548+
return success();
549+
}
550+
case cir::CastKind::float_complex: {
551+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
552+
if (!srcComplexTy || !srcComplexTy.isFloatingPointComplex())
553+
return emitOpError()
554+
<< "requires floating point !cir.complex type for source";
555+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
556+
if (!resComplexTy || !resComplexTy.isFloatingPointComplex())
557+
return emitOpError()
558+
<< "requires floating point !cir.complex type for result";
559+
return success();
560+
}
561+
case cir::CastKind::float_complex_to_int_complex: {
562+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
563+
if (!srcComplexTy || !srcComplexTy.isFloatingPointComplex())
564+
return emitOpError()
565+
<< "requires floating point !cir.complex type for source";
566+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
567+
if (!resComplexTy || !resComplexTy.isIntegerComplex())
568+
return emitOpError() << "requires integer !cir.complex type for result";
569+
return success();
570+
}
571+
case cir::CastKind::int_complex: {
572+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
573+
if (!srcComplexTy || !srcComplexTy.isIntegerComplex())
574+
return emitOpError() << "requires integer !cir.complex type for source";
575+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
576+
if (!resComplexTy || !resComplexTy.isIntegerComplex())
577+
return emitOpError() << "requires integer !cir.complex type for result";
578+
return success();
579+
}
580+
case cir::CastKind::int_complex_to_float_complex: {
581+
auto srcComplexTy = mlir::dyn_cast<cir::ComplexType>(srcType);
582+
if (!srcComplexTy || !srcComplexTy.isIntegerComplex())
583+
return emitOpError() << "requires integer !cir.complex type for source";
584+
auto resComplexTy = mlir::dyn_cast<cir::ComplexType>(resType);
585+
if (!resComplexTy || !resComplexTy.isFloatingPointComplex())
586+
return emitOpError()
587+
<< "requires floating point !cir.complex type for result";
588+
return success();
589+
}
492590
default:
493591
llvm_unreachable("Unknown CastOp kind?");
494592
}

0 commit comments

Comments
 (0)