llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Amr Hesham (AmrDeveloper)

<details>
<summary>Changes</summary>

Fix Codegen for Comparison between two Complex bin ops

---
Full diff: https://github.com/llvm/llvm-project/pull/185316.diff


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+17-11) 
- (modified) clang/test/CIR/CodeGen/complex.cpp (+84-4) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 1b5ba5ee6783f..4a2973d3824ee 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1196,19 +1196,25 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
         result = builder.createCompare(loc, kind, lhs, rhs);
       }
     } else {
-      // Complex Comparison: can only be an equality comparison.
-      assert(e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE);
-      BinOpInfo boInfo = emitBinOps(e);
-      mlir::Value lhs = boInfo.lhs;
-      if (!lhsTy->isAnyComplexType()) {
-        lhs = builder.createComplexCreate(
-            loc, lhs, builder.getNullValue(lhs.getType(), loc));
+      assert((e->getOpcode() == BO_EQ || e->getOpcode() == BO_NE) &&
+             "Complex Comparison: can only be an equality comparison");
+
+      mlir::Value lhs;
+      if (lhsTy->isAnyComplexType()) {
+        lhs = cgf.emitComplexExpr(e->getLHS());
+      } else {
+        mlir::Value lhsReal = Visit(e->getLHS());
+        mlir::Value lhsImag = builder.getNullValue(convertType(lhsTy), loc);
+        lhs = builder.createComplexCreate(loc, lhsReal, lhsImag);
       }
 
-      mlir::Value rhs = boInfo.rhs;
-      if (!rhsTy->isAnyComplexType()) {
-        rhs = builder.createComplexCreate(
-            loc, rhs, builder.getNullValue(rhs.getType(), loc));
+      mlir::Value rhs;
+      if (rhsTy->isAnyComplexType()) {
+        rhs = cgf.emitComplexExpr(e->getRHS());
+      } else {
+        mlir::Value rhsReal = Visit(e->getRHS());
+        mlir::Value rhsImag = builder.getNullValue(convertType(rhsTy), loc);
+        rhs = builder.createComplexCreate(loc, rhsReal, rhsImag);
       }
 
       result = builder.createCompare(loc, kind, lhs, rhs);
diff --git a/clang/test/CIR/CodeGen/complex.cpp 
b/clang/test/CIR/CodeGen/complex.cpp
index 48b7dd72ae661..421ef6735db7d 100644
--- a/clang/test/CIR/CodeGen/complex.cpp
+++ b/clang/test/CIR/CodeGen/complex.cpp
@@ -1734,9 +1734,9 @@ bool eq_float_and_float_complex(float a, float _Complex 
b) {
 // CIR: cir.store %[[ARG_0:.*]], %[[A_ADDR]] : !cir.float, !cir.ptr<!cir.float>
 // CIR: cir.store %[[ARG_1:.*]], %[[B_ADDR]] : !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>
 // CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.float>, 
!cir.float
-// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
 // CIR: %[[CONST_0F:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.float
 // CIR: %[[COMPLEX_A:.*]] = cir.complex.create %[[TMP_A]], %[[CONST_0F]] : 
!cir.float -> !cir.complex<!cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
 // CIR: %[[RESULT:.*]] = cir.cmp(eq, %[[COMPLEX_A]], %[[TMP_B]]) : 
!cir.complex<!cir.float>, !cir.bool
 // CIR: cir.store %[[RESULT]], %[[RET_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
 
@@ -1746,9 +1746,9 @@ bool eq_float_and_float_complex(float a, float _Complex 
b) {
 // LLVM: store float %[[ARG_0:.*]], ptr %[[A_ADDR]], align 4
 // LLVM: store { float, float } %[[ARG_1:.*]], ptr %[[B_ADDR]], align 4
 // LLVM: %[[TMP_A:.*]] = load float, ptr %[[A_ADDR]], align 4
-// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
 // LLVM: %[[TMP_COMPLEX_A:.*]] = insertvalue { float, float } {{.*}}, float 
%[[TMP_A]], 0
 // LLVM: %[[COMPLEX_A:.*]] = insertvalue { float, float } %[[TMP_COMPLEX_A]], 
float 0.000000e+00, 1
+// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
 // LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[COMPLEX_A]], 0
 // LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[COMPLEX_A]], 1
 // LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0
@@ -1830,9 +1830,9 @@ bool ne_float_and_float_complex(float a, float _Complex 
b) {
 // CIR: cir.store %[[ARG_0:.*]], %[[A_ADDR]] : !cir.float, !cir.ptr<!cir.float>
 // CIR: cir.store %[[ARG_1:.*]], %[[B_ADDR]] : !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>
 // CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.float>, 
!cir.float
-// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
 // CIR: %[[CONST_0F:.*]] = cir.const #cir.fp<0.000000e+00> : !cir.float
 // CIR: %[[COMPLEX_A:.*]] = cir.complex.create %[[TMP_A]], %[[CONST_0F]] : 
!cir.float -> !cir.complex<!cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
 // CIR: %[[RESULT:.*]] = cir.cmp(ne, %[[COMPLEX_A]], %[[TMP_B]]) : 
!cir.complex<!cir.float>, !cir.bool
 // CIR: cir.store %[[RESULT]], %[[RET_ADDR]] : !cir.bool, !cir.ptr<!cir.bool>
 
@@ -1842,9 +1842,9 @@ bool ne_float_and_float_complex(float a, float _Complex 
b) {
 // LLVM: store float %[[ARG_0:.*]], ptr %[[A_ADDR]], align 4
 // LLVM: store { float, float } %[[ARG_1:.*]], ptr %[[B_ADDR]], align 4
 // LLVM: %[[TMP_A:.*]] = load float, ptr %[[A_ADDR]], align 4
-// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
 // LLVM: %[[TMP_COMPLEX_A:.*]] = insertvalue { float, float } {{.*}}, float 
%[[TMP_A]], 0
 // LLVM: %[[COMPLEX_A:.*]] = insertvalue { float, float } %[[TMP_COMPLEX_A]], 
float 0.000000e+00, 1
+// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
 // LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[COMPLEX_A]], 0
 // LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[COMPLEX_A]], 1
 // LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0
@@ -1867,3 +1867,83 @@ bool ne_float_and_float_complex(float a, float _Complex 
b) {
 // OGCG: %[[REAL_CMP:.*]] = fcmp une float %[[TMP_A]], %[[B_REAL]]
 // OGCG: %[[IMAG_CMP:.*]] = fcmp une float 0.000000e+00, %[[B_IMAG]]
 // OGCG: %[[RESULT:.*]] = or i1 %[[REAL_CMP]], %[[IMAG_CMP]]
+
+void compare_two_complex_bin_ops() {
+  double _Complex a;
+  double _Complex b;
+  bool c = a + b != b + a;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, 
!cir.ptr<!cir.complex<!cir.double>>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.double>, 
!cir.ptr<!cir.complex<!cir.double>>, ["b"]
+// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["c", init]
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[COMPLEX_AB:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : 
!cir.complex<!cir.double>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!cir.double>>, !cir.complex<!cir.double>
+// CIR: %[[COMPLEX_BA:.*]] = cir.complex.add %[[TMP_B]], %[[TMP_A]] : 
!cir.complex<!cir.double>
+// CIR: %[[RESULT:.*]] = cir.cmp(ne, %[[COMPLEX_AB]], %[[COMPLEX_BA]]) : 
!cir.complex<!cir.double>, !cir.bool
+// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.bool, 
!cir.ptr<!cir.bool>
+
+// LLVM: %[[A_ADDR:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[B_ADDR:.*]] = alloca { double, double }, i64 1, align 8
+// LLVM: %[[C_ADDR:.*]] = alloca i8, i64 1, align 1
+// LLVM: %[[TMP_A:.*]] = load { double, double }, ptr %[[A_ADDR]], align 8
+// LLVM: %[[TMP_B:.*]] = load { double, double }, ptr %[[B_ADDR]], align 8
+// LLVM: %[[A_REAL:.*]] = extractvalue { double, double } %[[TMP_A]], 0
+// LLVM: %[[A_IMAG:.*]] = extractvalue { double, double } %[[TMP_A]], 1
+// LLVM: %[[B_REAL:.*]] = extractvalue { double, double } %[[TMP_B]], 0
+// LLVM: %[[B_IMAG:.*]] = extractvalue { double, double } %[[TMP_B]], 1
+// LLVM: %[[ADD_AB_REAL:.*]] = fadd double %[[A_REAL]], %[[B_REAL]]
+// LLVM: %[[ADD_AB_IMAG:.*]] = fadd double %[[A_IMAG]], %[[B_IMAG]]
+// LLVM: %[[TMP_COMPLEX_AB:.*]] = insertvalue { double, double } poison, 
double %[[ADD_AB_REAL]], 0
+// LLVM: %[[COMPLEX_AB:.*]] = insertvalue { double, double } 
%[[TMP_COMPLEX_AB]], double %[[ADD_AB_IMAG]], 1
+// LLVM: %[[TMP_B:.*]] = load { double, double }, ptr %[[B_ADDR]], align 8
+// LLVM: %[[TMP_A:.*]] = load { double, double }, ptr %[[A_ADDR]], align 8
+// LLVM: %[[B_REAL:.*]] = extractvalue { double, double } %[[TMP_B]], 0
+// LLVM: %[[B_IMAG:.*]] = extractvalue { double, double } %[[TMP_B]], 1
+// LLVM: %[[A_REAL:.*]] = extractvalue { double, double } %[[TMP_A]], 0
+// LLVM: %[[A_IMAG:.*]] = extractvalue { double, double } %[[TMP_A]], 1
+// LLVM: %[[ADD_BA_REAL:.*]] = fadd double %[[B_REAL]], %[[A_REAL]]
+// LLVM: %[[ADD_BA_IMAG:.*]] = fadd double %[[B_IMAG]], %[[A_IMAG]]
+// LLVM: %[[TMP_COMPLEX_BA:.*]] = insertvalue { double, double } poison, 
double %[[ADD_BA_REAL]], 0
+// LLVM: %[[COMPLEX_BA:.*]] = insertvalue { double, double } 
%[[TMP_COMPLEX_BA]], double %[[ADD_BA_IMAG]], 1
+// LLVM: %[[AB_REAL:.*]] = extractvalue { double, double } %[[COMPLEX_AB]], 0
+// LLVM: %[[AB_IMAG:.*]] = extractvalue { double, double } %[[COMPLEX_AB]], 1
+// LLVM: %[[BA_REAL:.*]] = extractvalue { double, double } %[[COMPLEX_BA]], 0
+// LLVM: %[[BA_IMAG:.*]] = extractvalue { double, double } %[[COMPLEX_BA]], 1
+// LLVM: %[[CMP_NE_REAL:.*]] = fcmp une double %[[AB_REAL]], %[[BA_REAL]]
+// LLVM: %[[CMP_NE_IMAG:.*]] = fcmp une double %[[AB_IMAG]], %[[BA_IMAG]]
+// LLVM: %[[RESULT:.*]] = or i1 %[[CMP_NE_REAL]], %[[CMP_NE_IMAG]]
+// LLVM: %[[RESULT_I8:.*]] = zext i1 %[[RESULT]] to i8
+// LLVM: store i8 %[[RESULT_I8]], ptr %[[C_ADDR]], align 1
+
+// OGCG: %[[A_ADDR:.*]] = alloca { double, double }, align 8
+// OGCG: %[[B_ADDR:.*]] = alloca { double, double }, align 8
+// OGCG: %[[C_ADDR:.*]] = alloca i8, align 1
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[A_ADDR]], 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 %[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_REAL:.*]] = load double, ptr %[[B_REAL_PTR]], align 8
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[B_ADDR]], i32 0, i32 1
+// OGCG: %[[B_IMAG:.*]] = load double, ptr %[[B_IMAG_PTR]], align 8
+// OGCG: %[[ADD_AB_REAL:.*]] = fadd double %[[A_REAL]], %[[B_REAL]]
+// OGCG: %[[ADD_AB_IMAG:.*]] = fadd double %[[A_IMAG]], %[[B_IMAG]]
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_REAL:.*]] = load double, ptr %[[B_REAL_PTR]], align 8
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[B_ADDR]], i32 0, i32 1
+// OGCG: %[[B_IMAG:.*]] = load double, ptr %[[B_IMAG_PTR]], align 8
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { double, double }, 
ptr %[[A_ADDR]], 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 %[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load double, ptr %[[A_IMAG_PTR]], align 8
+// OGCG: %[[ADD_BA_REAL:.*]] = fadd double %[[B_REAL]], %[[A_REAL]]
+// OGCG: %[[ADD_BA_IMAG:.*]] = fadd double %[[B_IMAG]], %[[A_IMAG]]
+// OGCG: %[[CMP_NE_REAL:.*]] = fcmp une double %[[ADD_AB_REAL]], 
%[[ADD_BA_REAL]]
+// OGCG: %[[CMP_NE_IMAG:.*]] = fcmp une double %[[ADD_AB_IMAG]], 
%[[ADD_BA_IMAG]]
+// OGCG: %[[RESULT:.*]] = or i1 %[[CMP_NE_REAL]], %[[CMP_NE_IMAG]]
+// OGCG: %[[RESULT_I8:.*]] = zext i1 %[[RESULT]] to i8
+// OGCG: store i8 %[[RESULT_I8]], ptr %[[C_ADDR]], align 1

``````````

</details>


https://github.com/llvm/llvm-project/pull/185316
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to