Skip to content

Commit ddfc13c

Browse files
authored
[CIR] Upstream __builtin_creal for ComplexType (#146927)
Upstream `__builtin_creal` support for ComplexType #141365
1 parent 9b5959d commit ddfc13c

File tree

3 files changed

+44
-9
lines changed

3 files changed

+44
-9
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
8383

8484
const FunctionDecl *fd = gd.getDecl()->getAsFunction();
8585

86-
// If this is an alias for a lib function (e.g. __builtin_sin), emit
87-
// the call using the normal call path, but using the unmangled
88-
// version of the function name.
89-
if (getContext().BuiltinInfo.isLibFunction(builtinID))
90-
return emitLibraryCall(*this, fd, e,
91-
cgm.getBuiltinLibFunction(fd, builtinID));
92-
9386
assert(!cir::MissingFeatures::builtinCallF128());
9487

9588
// If the builtin has been declared explicitly with an assembler label,
@@ -124,6 +117,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
124117
return RValue::get(complex);
125118
}
126119

120+
case Builtin::BI__builtin_creal:
121+
case Builtin::BI__builtin_crealf:
122+
case Builtin::BI__builtin_creall:
123+
case Builtin::BIcreal:
124+
case Builtin::BIcrealf:
125+
case Builtin::BIcreall: {
126+
mlir::Value complex = emitComplexExpr(e->getArg(0));
127+
mlir::Value real = builder.createComplexReal(loc, complex);
128+
return RValue::get(real);
129+
}
130+
127131
case Builtin::BI__builtin_clrsb:
128132
case Builtin::BI__builtin_clrsbl:
129133
case Builtin::BI__builtin_clrsbll:
@@ -192,6 +196,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
192196
}
193197
}
194198

199+
// If this is an alias for a lib function (e.g. __builtin_sin), emit
200+
// the call using the normal call path, but using the unmangled
201+
// version of the function name.
202+
if (getContext().BuiltinInfo.isLibFunction(builtinID))
203+
return emitLibraryCall(*this, fd, e,
204+
cgm.getBuiltinLibFunction(fd, builtinID));
205+
195206
cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
196207
return getUndefRValue(e->getType());
197208
}

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,8 +1094,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
10941094
case cir::TEK_Scalar:
10951095
return RValue::get(emitScalarExpr(e));
10961096
case cir::TEK_Complex:
1097-
cgm.errorNYI(e->getSourceRange(), "emitAnyExpr: complex type");
1098-
return RValue::get(nullptr);
1097+
return RValue::getComplex(emitComplexExpr(e));
10991098
case cir::TEK_Aggregate: {
11001099
if (aggSlot.isIgnored())
11011100
aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),

clang/test/CIR/CodeGen/complex-builtins.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,28 @@ void foo() {
3333
// OGCG: %[[R_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_R]], i32 0, i32 1
3434
// OGCG: store i32 %[[A_REAL]], ptr %[[R_REAL_PTR]], align 4
3535
// OGCG: store i32 %[[A_IMAG]], ptr %[[R_IMAG_PTR]], align 4
36+
37+
void foo2() {
38+
double _Complex a;
39+
double real = __builtin_creal(a);
40+
}
41+
42+
// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["a"]
43+
// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["real", init]
44+
// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
45+
// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.double> -> !cir.double
46+
// CIR: cir.store{{.*}} %[[REAL]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double>
47+
48+
// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
49+
// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
50+
// LLVM: %[[TMP:.*]] = load { double, double }, ptr %[[COMPLEX]], align 8
51+
// LLVM: %[[REAL:.*]] = extractvalue { double, double } %[[TMP]], 0
52+
// LLVM: store double %[[REAL]], ptr %[[INIT]], align 8
53+
54+
// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
55+
// OGCG: %[[INIT:.*]] = alloca double, align 8
56+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
57+
// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
58+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
59+
// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
60+
// OGCG: store double %[[A_REAL]], ptr %[[INIT]], align 8

0 commit comments

Comments
 (0)