-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[CIR] Upstream __builtin_creal for ComplexType #146927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesUpstream Full diff: https://github.com/llvm/llvm-project/pull/146927.diff 3 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..1e56ea4d9bd8e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -83,13 +83,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
const FunctionDecl *fd = gd.getDecl()->getAsFunction();
- // If this is an alias for a lib function (e.g. __builtin_sin), emit
- // the call using the normal call path, but using the unmangled
- // version of the function name.
- if (getContext().BuiltinInfo.isLibFunction(builtinID))
- return emitLibraryCall(*this, fd, e,
- cgm.getBuiltinLibFunction(fd, builtinID));
-
assert(!cir::MissingFeatures::builtinCallF128());
// If the builtin has been declared explicitly with an assembler label,
@@ -124,6 +117,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(complex);
}
+ case Builtin::BI__builtin_creal:
+ case Builtin::BI__builtin_crealf:
+ case Builtin::BI__builtin_creall:
+ case Builtin::BIcreal:
+ case Builtin::BIcrealf:
+ case Builtin::BIcreall: {
+ mlir::Value complex = emitComplexExpr(e->getArg(0));
+ mlir::Value real = builder.createComplexReal(loc, complex);
+ return RValue::get(real);
+ }
+
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
@@ -192,6 +196,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
}
}
+ // If this is an alias for a lib function (e.g. __builtin_sin), emit
+ // the call using the normal call path, but using the unmangled
+ // version of the function name.
+ if (getContext().BuiltinInfo.isLibFunction(builtinID))
+ return emitLibraryCall(*this, fd, e,
+ cgm.getBuiltinLibFunction(fd, builtinID));
+
cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
return getUndefRValue(e->getType());
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 68d7f1f5bca48..300ba7a456e4b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1094,8 +1094,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
case cir::TEK_Scalar:
return RValue::get(emitScalarExpr(e));
case cir::TEK_Complex:
- cgm.errorNYI(e->getSourceRange(), "emitAnyExpr: complex type");
- return RValue::get(nullptr);
+ return RValue::getComplex(emitComplexExpr(e));
case cir::TEK_Aggregate: {
if (aggSlot.isIgnored())
aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
diff --git a/clang/test/CIR/CodeGen/complex-builtins.cpp b/clang/test/CIR/CodeGen/complex-builtins.cpp
index 2372ab571e533..fdda5eb707fb7 100644
--- a/clang/test/CIR/CodeGen/complex-builtins.cpp
+++ b/clang/test/CIR/CodeGen/complex-builtins.cpp
@@ -33,3 +33,28 @@ void foo() {
// OGCG: %[[R_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_R]], i32 0, i32 1
// OGCG: store i32 %[[A_REAL]], ptr %[[R_REAL_PTR]], align 4
// OGCG: store i32 %[[A_IMAG]], ptr %[[R_IMAG_PTR]], align 4
+
+void foo2() {
+ double _Complex a;
+ double real = __builtin_creal(a);
+}
+
+// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["a"]
+// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["real", init]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.double> -> !cir.double
+// CIR: cir.store{{.*}} %[[REAL]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
+// LLVM: %[[TMP:.*]] = load { double, double }, ptr %[[COMPLEX]], align 8
+// LLVM: %[[REAL:.*]] = extractvalue { double, double } %[[TMP]], 0
+// LLVM: store double %[[REAL]], ptr %[[INIT]], align 8
+
+// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
+// OGCG: %[[INIT:.*]] = alloca double, align 8
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
+// OGCG: store double %[[A_REAL]], ptr %[[INIT]], align 8
|
@llvm/pr-subscribers-clangir Author: Amr Hesham (AmrDeveloper) ChangesUpstream Full diff: https://github.com/llvm/llvm-project/pull/146927.diff 3 Files Affected:
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index fb046533a91b8..1e56ea4d9bd8e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -83,13 +83,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
const FunctionDecl *fd = gd.getDecl()->getAsFunction();
- // If this is an alias for a lib function (e.g. __builtin_sin), emit
- // the call using the normal call path, but using the unmangled
- // version of the function name.
- if (getContext().BuiltinInfo.isLibFunction(builtinID))
- return emitLibraryCall(*this, fd, e,
- cgm.getBuiltinLibFunction(fd, builtinID));
-
assert(!cir::MissingFeatures::builtinCallF128());
// If the builtin has been declared explicitly with an assembler label,
@@ -124,6 +117,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
return RValue::get(complex);
}
+ case Builtin::BI__builtin_creal:
+ case Builtin::BI__builtin_crealf:
+ case Builtin::BI__builtin_creall:
+ case Builtin::BIcreal:
+ case Builtin::BIcrealf:
+ case Builtin::BIcreall: {
+ mlir::Value complex = emitComplexExpr(e->getArg(0));
+ mlir::Value real = builder.createComplexReal(loc, complex);
+ return RValue::get(real);
+ }
+
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
@@ -192,6 +196,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID,
}
}
+ // If this is an alias for a lib function (e.g. __builtin_sin), emit
+ // the call using the normal call path, but using the unmangled
+ // version of the function name.
+ if (getContext().BuiltinInfo.isLibFunction(builtinID))
+ return emitLibraryCall(*this, fd, e,
+ cgm.getBuiltinLibFunction(fd, builtinID));
+
cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
return getUndefRValue(e->getType());
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 68d7f1f5bca48..300ba7a456e4b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1094,8 +1094,7 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
case cir::TEK_Scalar:
return RValue::get(emitScalarExpr(e));
case cir::TEK_Complex:
- cgm.errorNYI(e->getSourceRange(), "emitAnyExpr: complex type");
- return RValue::get(nullptr);
+ return RValue::getComplex(emitComplexExpr(e));
case cir::TEK_Aggregate: {
if (aggSlot.isIgnored())
aggSlot = createAggTemp(e->getType(), getLoc(e->getSourceRange()),
diff --git a/clang/test/CIR/CodeGen/complex-builtins.cpp b/clang/test/CIR/CodeGen/complex-builtins.cpp
index 2372ab571e533..fdda5eb707fb7 100644
--- a/clang/test/CIR/CodeGen/complex-builtins.cpp
+++ b/clang/test/CIR/CodeGen/complex-builtins.cpp
@@ -33,3 +33,28 @@ void foo() {
// OGCG: %[[R_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_R]], i32 0, i32 1
// OGCG: store i32 %[[A_REAL]], ptr %[[R_REAL_PTR]], align 4
// OGCG: store i32 %[[A_IMAG]], ptr %[[R_IMAG_PTR]], align 4
+
+void foo2() {
+ double _Complex a;
+ double real = __builtin_creal(a);
+}
+
+// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex<!cir.double>, !cir.ptr<!cir.complex<!cir.double>>, ["a"]
+// CIR: %[[INIT:.*]] = cir.alloca !cir.double, !cir.ptr<!cir.double>, ["real", init]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] : !cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex<!cir.double> -> !cir.double
+// CIR: cir.store{{.*}} %[[REAL]], %[[INIT]] : !cir.double, !cir.ptr<!cir.double>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[INIT:.*]] = alloca double, i64 1, align 8
+// LLVM: %[[TMP:.*]] = load { double, double }, ptr %[[COMPLEX]], align 8
+// LLVM: %[[REAL:.*]] = extractvalue { double, double } %[[TMP]], 0
+// LLVM: store double %[[REAL]], ptr %[[INIT]], align 8
+
+// OGCG: %[[COMPLEX:.*]] = alloca { double, double }, align 8
+// OGCG: %[[INIT:.*]] = alloca double, align 8
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load double, ptr %[[A_REAL_PTR]], align 8
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, ptr %[[COMPLEX]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
+// OGCG: store double %[[A_REAL]], ptr %[[INIT]], align 8
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, but Andy needs to take a look when he gets back monday.
@@ -192,6 +196,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, | |||
} | |||
} | |||
|
|||
// If this is an alias for a lib function (e.g. __builtin_sin), emit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have @andykaylor take a look at this, this was a good way to get a bunch of stuff passing by ignoring the above code for most of these, so I don't know how much this will harm us. But overall it looks reasonable to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I will wait for him to take a look too
Thanks
Upstream
__builtin_creal
support for ComplexType#141365