[clang] [CIR] Upstream builtin_conj for ComplexType (PR #149170)
https://github.com/AmrDeveloper closed https://github.com/llvm/llvm-project/pull/149170 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream builtin_conj for ComplexType (PR #149170)
https://github.com/xlauko approved this pull request. lgtm https://github.com/llvm/llvm-project/pull/149170 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Upstream builtin_conj for ComplexType (PR #149170)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Amr Hesham (AmrDeveloper)
Changes
This change adds support for builtin_conj for ComplexType
https://github.com/llvm/llvm-project/issues/141365
---
Full diff: https://github.com/llvm/llvm-project/pull/149170.diff
4 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+13-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp (+1-2)
- (modified) clang/lib/CIR/CodeGen/CIRGenValue.h (+6)
- (modified) clang/test/CIR/CodeGen/complex-builtins.cpp (+36)
``diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 476f994959285..61d1c54ee9ec9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -125,7 +125,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl
&gd, unsigned builtinID,
mlir::Value real = emitScalarExpr(e->getArg(0));
mlir::Value imag = emitScalarExpr(e->getArg(1));
mlir::Value complex = builder.createComplexCreate(loc, real, imag);
-return RValue::get(complex);
+return RValue::getComplex(complex);
}
case Builtin::BI__builtin_creal:
@@ -150,6 +150,18 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl
&gd, unsigned builtinID,
return RValue::get(imag);
}
+ case Builtin::BI__builtin_conj:
+ case Builtin::BI__builtin_conjf:
+ case Builtin::BI__builtin_conjl:
+ case Builtin::BIconj:
+ case Builtin::BIconjf:
+ case Builtin::BIconjl: {
+mlir::Value complex = emitComplexExpr(e->getArg(0));
+mlir::Value conj = builder.createUnaryOp(getLoc(e->getExprLoc()),
+ cir::UnaryOpKind::Not, complex);
+return RValue::getComplex(conj);
+ }
+
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 6663f5ea1e758..9f36be5397ad8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -231,8 +231,7 @@ mlir::Value ComplexExprEmitter::VisitBinComma(const
BinaryOperator *e) {
mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
if (e->getCallReturnType(cgf.getContext())->isReferenceType())
return emitLoadOfLValue(e);
-
- return cgf.emitCallExpr(e).getValue();
+ return cgf.emitCallExpr(e).getComplexValue();
}
mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 0a6dba5e80a62..0832c4141a10f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -58,6 +58,12 @@ class RValue {
return value;
}
+ /// Return the value of this complex value.
+ mlir::Value getComplexValue() const {
+assert(isComplex() && "Not a complex!");
+return value;
+ }
+
/// Return the value of the address of the aggregate.
Address getAggregateAddress() const {
assert(isAggregate() && "Not an aggregate!");
diff --git a/clang/test/CIR/CodeGen/complex-builtins.cpp
b/clang/test/CIR/CodeGen/complex-builtins.cpp
index f0d12d0ef6663..811af47a704f5 100644
--- a/clang/test/CIR/CodeGen/complex-builtins.cpp
+++ b/clang/test/CIR/CodeGen/complex-builtins.cpp
@@ -83,3 +83,39 @@ void foo3() {
// 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_IMAG]], ptr %[[INIT]], align 8
+
+void foo4() {
+ float _Complex a;
+ float _Complex b = __builtin_conjf(a);
+}
+
+// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex,
!cir.ptr>, ["a"]
+// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex,
!cir.ptr>, ["b", init]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] :
!cir.ptr>, !cir.complex
+// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex ->
!cir.float
+// CIR: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex ->
!cir.float
+// CIR: %[[IMAG_MINUS:.*]] = cir.unary(minus, %[[IMAG]]) : !cir.float,
!cir.float
+// CIR: %[[RESULT_VAL:.*]] = cir.complex.create %[[REAL]], %[[IMAG_MINUS]] :
!cir.float -> !cir.complex
+// CIR: cir.store{{.*}} %[[RESULT_VAL]], %[[RESULT]] :
!cir.complex, !cir.ptr>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
+// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
+// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
+// LLVM: %[[IMAG_MINUS:.*]] = fneg float %[[IMAG]]
+// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float
%[[REAL]], 0
+// LLVM: %[[RESULT_VAL:.*]] = insertvalue { float, float } %[[RESULT_TMP]],
float %[[IMAG_MINUS]], 1
+// LLVM: store { float, fl
[clang] [CIR] Upstream builtin_conj for ComplexType (PR #149170)
https://github.com/AmrDeveloper created
https://github.com/llvm/llvm-project/pull/149170
This change adds support for builtin_conj for ComplexType
https://github.com/llvm/llvm-project/issues/141365
>From 2965c5b9f3684b321aa654105e2854d1711f8274 Mon Sep 17 00:00:00 2001
From: AmrDeveloper
Date: Wed, 16 Jul 2025 21:11:38 +0200
Subject: [PATCH] [CIR] Upstream builtin_conj for ComplexType
---
clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 14 +++-
clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 3 +-
clang/lib/CIR/CodeGen/CIRGenValue.h | 6
clang/test/CIR/CodeGen/complex-builtins.cpp | 36 +
4 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 476f994959285..61d1c54ee9ec9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -125,7 +125,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl
&gd, unsigned builtinID,
mlir::Value real = emitScalarExpr(e->getArg(0));
mlir::Value imag = emitScalarExpr(e->getArg(1));
mlir::Value complex = builder.createComplexCreate(loc, real, imag);
-return RValue::get(complex);
+return RValue::getComplex(complex);
}
case Builtin::BI__builtin_creal:
@@ -150,6 +150,18 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl
&gd, unsigned builtinID,
return RValue::get(imag);
}
+ case Builtin::BI__builtin_conj:
+ case Builtin::BI__builtin_conjf:
+ case Builtin::BI__builtin_conjl:
+ case Builtin::BIconj:
+ case Builtin::BIconjf:
+ case Builtin::BIconjl: {
+mlir::Value complex = emitComplexExpr(e->getArg(0));
+mlir::Value conj = builder.createUnaryOp(getLoc(e->getExprLoc()),
+ cir::UnaryOpKind::Not, complex);
+return RValue::getComplex(conj);
+ }
+
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 6663f5ea1e758..9f36be5397ad8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -231,8 +231,7 @@ mlir::Value ComplexExprEmitter::VisitBinComma(const
BinaryOperator *e) {
mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
if (e->getCallReturnType(cgf.getContext())->isReferenceType())
return emitLoadOfLValue(e);
-
- return cgf.emitCallExpr(e).getValue();
+ return cgf.emitCallExpr(e).getComplexValue();
}
mlir::Value ComplexExprEmitter::VisitCastExpr(CastExpr *e) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 0a6dba5e80a62..0832c4141a10f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -58,6 +58,12 @@ class RValue {
return value;
}
+ /// Return the value of this complex value.
+ mlir::Value getComplexValue() const {
+assert(isComplex() && "Not a complex!");
+return value;
+ }
+
/// Return the value of the address of the aggregate.
Address getAggregateAddress() const {
assert(isAggregate() && "Not an aggregate!");
diff --git a/clang/test/CIR/CodeGen/complex-builtins.cpp
b/clang/test/CIR/CodeGen/complex-builtins.cpp
index f0d12d0ef6663..811af47a704f5 100644
--- a/clang/test/CIR/CodeGen/complex-builtins.cpp
+++ b/clang/test/CIR/CodeGen/complex-builtins.cpp
@@ -83,3 +83,39 @@ void foo3() {
// 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_IMAG]], ptr %[[INIT]], align 8
+
+void foo4() {
+ float _Complex a;
+ float _Complex b = __builtin_conjf(a);
+}
+
+// CIR: %[[COMPLEX:.*]] = cir.alloca !cir.complex,
!cir.ptr>, ["a"]
+// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex,
!cir.ptr>, ["b", init]
+// CIR: %[[TMP:.*]] = cir.load{{.*}} %[[COMPLEX]] :
!cir.ptr>, !cir.complex
+// CIR: %[[REAL:.*]] = cir.complex.real %[[TMP]] : !cir.complex ->
!cir.float
+// CIR: %[[IMAG:.*]] = cir.complex.imag %[[TMP]] : !cir.complex ->
!cir.float
+// CIR: %[[IMAG_MINUS:.*]] = cir.unary(minus, %[[IMAG]]) : !cir.float,
!cir.float
+// CIR: %[[RESULT_VAL:.*]] = cir.complex.create %[[REAL]], %[[IMAG_MINUS]] :
!cir.float -> !cir.complex
+// CIR: cir.store{{.*}} %[[RESULT_VAL]], %[[RESULT]] :
!cir.complex, !cir.ptr>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM: %[[RESULT:.*]] = alloca { float, float }, i64 1, align 4
+// LLVM: %[[TMP:.*]] = load { float, float }, ptr %[[COMPLEX]], align 4
+// LLVM: %[[REAL:.*]] = extractvalue { float, float } %[[TMP]], 0
+// LLVM: %[[IMAG:.*]] = extractvalue { float, float } %[[TMP]], 1
+// LLVM: %[[IMAG_MINUS:.*]] = fneg float %[[IMAG]]
+// LLVM: %[[RESULT_TMP:.*]] = insertvalue { float, float } {{.*}}, float
%[[REAL]],
