https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/144225

>From d5c7a04815acee8b792e95fcd376fc492bcadb58 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sat, 14 Jun 2025 16:21:20 +0200
Subject: [PATCH 1/4] [CIR] Upstream ComplexType builtin_complex

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp     |  6 ++++
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 33 +++++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenValue.h         |  1 -
 clang/test/CIR/CodeGen/complex.cpp          | 25 ++++++++++++++++
 4 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 83825f0835a1e..3ae7a5e660572 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -91,6 +91,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
     builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue);
     return RValue::get(nullptr);
   }
+  case Builtin::BI__builtin_complex: {
+    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);
+  }
   }
 
   cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 26070a6ca307a..fea069fc07356 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -15,11 +15,25 @@ class ComplexExprEmitter : public 
StmtVisitor<ComplexExprEmitter, mlir::Value> {
   explicit ComplexExprEmitter(CIRGenFunction &cgf)
       : cgf(cgf), builder(cgf.getBuilder()) {}
 
+  
//===--------------------------------------------------------------------===//
+  //                               Utilities
+  
//===--------------------------------------------------------------------===//
+
+  /// Given an expression with complex type that represents a value l-value,
+  /// this method emits the address of the l-value, then loads and returns the
+  /// result.
+  mlir::Value emitLoadOfLValue(const Expr *e) {
+    return emitLoadOfLValue(cgf.emitLValue(e), e->getExprLoc());
+  }
+
+  mlir::Value emitLoadOfLValue(LValue lv, SourceLocation loc);
+
   /// Store the specified real/imag parts into the
   /// specified value pointer.
   void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
                           bool isInit);
 
+  mlir::Value VisitCallExpr(const CallExpr *e);
   mlir::Value VisitInitListExpr(InitListExpr *e);
 
   mlir::Value VisitImaginaryLiteral(const ImaginaryLiteral *il);
@@ -34,6 +48,16 @@ static const ComplexType *getComplexType(QualType type) {
   return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
 }
 
+mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
+                                                 SourceLocation loc) {
+  assert(lv.isSimple() && "non-simple complex l-value?");
+  if (lv.getType()->isAtomicType())
+    cgf.cgm.errorNYI("emitLoadOfLValue with Atomic LV");
+
+  const Address srcAddr = lv.getAddress();
+  return builder.createLoad(cgf.getLoc(loc), srcAddr);
+}
+
 void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value 
val,
                                             LValue lv, bool isInit) {
   if (lv.getType()->isAtomicType() ||
@@ -46,6 +70,15 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location 
loc, mlir::Value val,
   builder.createStore(loc, val, destAddr);
 }
 
+mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr *e) {
+  if (e->getCallReturnType(cgf.getContext())->isReferenceType())
+    return emitLoadOfLValue(e);
+
+  mlir::Location loc = cgf.getLoc(e->getExprLoc());
+  auto complex = cgf.emitCallExpr(e).getComplexVal();
+  return builder.createComplexCreate(loc, complex.first, complex.second);
+}
+
 mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {
   mlir::Location loc = cgf.getLoc(e->getExprLoc());
   if (e->getNumInits() == 2) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h 
b/clang/lib/CIR/CodeGen/CIRGenValue.h
index 84972fc7f9118..7180d92f8c314 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -88,7 +88,6 @@ class RValue {
     return er;
   }
 
-  // FIXME: Aggregate rvalues need to retain information about whether they are
   // volatile or not.  Remove default to find all places that probably get this
   // wrong.
 
diff --git a/clang/test/CIR/CodeGen/complex.cpp 
b/clang/test/CIR/CodeGen/complex.cpp
index db0b9111ab4fb..8b3c43709484d 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -191,6 +191,31 @@ void foo8() {
 // OGCG: store double 0.000000e+00, ptr %[[C_REAL_PTR]], align 8
 // OGCG: store double 2.000000e+00, ptr %[[C_IMAG_PTR]], align 8
 
+void foo9(double r, double i) {
+  double _Complex c = __builtin_complex(r, i);
+}
+
+// CIR: %[[INIT:.*]] = cir.alloca !cir.complex<!cir.double>, 
!cir.ptr<!cir.complex<!cir.double>>, ["c", init]
+// CIR: %[[TMP_A:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.double>, 
!cir.double
+// CIR: %[[TMP_B:.*]] = cir.load{{.*}} {{.*}} : !cir.ptr<!cir.double>, 
!cir.double
+// CIR: %[[COMPLEX:.*]] = cir.complex.create %[[TMP_A]], %[[TMP_B]] : 
!cir.double -> !cir.complex<!cir.double>
+// CIR: cir.store{{.*}} %[[COMPLEX]], %[[INIT]] : !cir.complex<!cir.double>, 
!cir.ptr<!cir.complex<!cir.double>>
+
+// LLVM: %[[COMPLEX:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8
+// LLVM: %[[TMP_B:.*]] = load double, ptr {{.*}}, align 8
+// LLVM: %[[TMP:.*]] = insertvalue { double, double } undef, double 
%[[TMP_A]], 0
+// LLVM: %[[TMP_2:.*]] = insertvalue { double, double } %[[TMP]], double 
%[[TMP_B]], 1
+// LLVM: store { double, double } %[[TMP_2]], ptr %[[COMPLEX]], align 8
+
+// OGCG: %[[COMPLEX]] = alloca { double, double }, align 8
+// OGCG: %[[TMP_A:.*]] = load double, ptr {{.*}}, align 8
+// OGCG: %[[TMP_B:.*]] = load double, ptr {{.*}}, align 8
+// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[COMPLEX]], i32 0, i32 0
+// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[COMPLEX]], i32 0, i32 1
+// OGCG: store double %[[TMP_A]], ptr %[[C_REAL_PTR]], align 8
+// OGCG: store double %[[TMP_B]], ptr %[[C_IMAG_PTR]], align 8
+
 void foo14() {
   int _Complex c = 2i;
 }

>From 35c060297ecc3811d604193e8bd055dcb6d4be6e Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Mon, 16 Jun 2025 21:15:12 +0200
Subject: [PATCH 2/4] Address code review comments

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp     | 1 +
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 ++--
 clang/test/CIR/CodeGen/complex.cpp          | 4 ++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 3ae7a5e660572..b723c884ea68d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -91,6 +91,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
     builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue);
     return RValue::get(nullptr);
   }
+
   case Builtin::BI__builtin_complex: {
     mlir::Value real = emitScalarExpr(e->getArg(0));
     mlir::Value imag = emitScalarExpr(e->getArg(1));
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index fea069fc07356..44fd6d29941ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -52,7 +52,7 @@ mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv,
                                                  SourceLocation loc) {
   assert(lv.isSimple() && "non-simple complex l-value?");
   if (lv.getType()->isAtomicType())
-    cgf.cgm.errorNYI("emitLoadOfLValue with Atomic LV");
+    cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV");
 
   const Address srcAddr = lv.getAddress();
   return builder.createLoad(cgf.getLoc(loc), srcAddr);
@@ -62,7 +62,7 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location 
loc, mlir::Value val,
                                             LValue lv, bool isInit) {
   if (lv.getType()->isAtomicType() ||
       (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
-    cgf.cgm.errorNYI("StoreOfComplex with Atomic LV");
+    cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
     return;
   }
 
diff --git a/clang/test/CIR/CodeGen/complex.cpp 
b/clang/test/CIR/CodeGen/complex.cpp
index 8b3c43709484d..721db235b37de 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -191,8 +191,8 @@ void foo8() {
 // OGCG: store double 0.000000e+00, ptr %[[C_REAL_PTR]], align 8
 // OGCG: store double 2.000000e+00, ptr %[[C_IMAG_PTR]], align 8
 
-void foo9(double r, double i) {
-  double _Complex c = __builtin_complex(r, i);
+void foo9(double a, double b) {
+  double _Complex c = __builtin_complex(a, b);
 }
 
 // CIR: %[[INIT:.*]] = cir.alloca !cir.complex<!cir.double>, 
!cir.ptr<!cir.complex<!cir.double>>, ["c", init]

>From 801e871692141e8f59d74f29ba2dd67c83d7fed7 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Tue, 17 Jun 2025 20:46:30 +0200
Subject: [PATCH 3/4] Address code review comments

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp     | 2 ++
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 +---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index b723c884ea68d..b86a41d8b4e87 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -98,6 +98,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
     mlir::Value complex = builder.createComplexCreate(loc, real, imag);
     return RValue::get(complex);
   }
+    default:
+    break;
   }
 
   cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 44fd6d29941ad..12e8e27948cf7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -74,9 +74,7 @@ mlir::Value ComplexExprEmitter::VisitCallExpr(const CallExpr 
*e) {
   if (e->getCallReturnType(cgf.getContext())->isReferenceType())
     return emitLoadOfLValue(e);
 
-  mlir::Location loc = cgf.getLoc(e->getExprLoc());
-  auto complex = cgf.emitCallExpr(e).getComplexVal();
-  return builder.createComplexCreate(loc, complex.first, complex.second);
+  return cgf.emitCallExpr(e).getValue();
 }
 
 mlir::Value ComplexExprEmitter::VisitInitListExpr(InitListExpr *e) {

>From 17f205410a0cb4754697b5af5f628f356a68d83b Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Tue, 17 Jun 2025 20:51:51 +0200
Subject: [PATCH 4/4] Fix code review comments

---
 clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index b86a41d8b4e87..cff139a7802df 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -78,6 +78,8 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
   assert(!cir::MissingFeatures::builtinCallMathErrno());
   assert(!cir::MissingFeatures::builtinCall());
 
+  mlir::Location loc = getLoc(e->getExprLoc());
+
   switch (builtinIDIfNoAsmLabel) {
   default:
     break;
@@ -88,7 +90,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
       return RValue::get(nullptr);
 
     mlir::Value argValue = emitCheckedArgForAssume(e->getArg(0));
-    builder.create<cir::AssumeOp>(getLoc(e->getExprLoc()), argValue);
+    builder.create<cir::AssumeOp>(loc, argValue);
     return RValue::get(nullptr);
   }
 
@@ -98,8 +100,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, 
unsigned builtinID,
     mlir::Value complex = builder.createComplexCreate(loc, real, imag);
     return RValue::get(complex);
   }
-    default:
-    break;
   }
 
   cgm.errorNYI(e->getSourceRange(), "unimplemented builtin call");

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to