From 498bdee001eadb8be68af44315a060f004f998d9 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Thu, 14 Aug 2025 20:25:36 +0200 Subject: [PATCH] [CIR] Backport AbstractConditionalOperator for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 20 ++++++++++-- clang/test/CIR/CodeGen/complex.cpp | 35 +++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 87a6cf28965d..5ca62be01d71 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -310,8 +310,24 @@ class ComplexExprEmitter : public StmtVisitor { } mlir::Value - VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO) { - llvm_unreachable("NYI"); + VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { + mlir::Value condValue = Visit(E->getCond()); + mlir::Location loc = CGF.getLoc(E->getSourceRange()); + + return Builder + .create( + loc, condValue, + /*thenBuilder=*/ + [&](mlir::OpBuilder &b, mlir::Location loc) { + mlir::Value trueValue = Visit(E->getTrueExpr()); + b.create(loc, trueValue); + }, + /*elseBuilder=*/ + [&](mlir::OpBuilder &b, mlir::Location loc) { + mlir::Value falseValue = Visit(E->getFalseExpr()); + b.create(loc, falseValue); + }) + .getResult(); } mlir::Value VisitChooseExpr(ChooseExpr *CE) { diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index 3f41a5a99cc0..2b782ee15faf 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -14,3 +14,38 @@ void complex_functional_cast() { // LLVM: %[[INIT:.*]] = alloca { i32, i32 }, i64 1, align 4 // LLVM: store { i32, i32 } zeroinitializer, ptr %[[INIT]], align 4 + +void complex_abstract_condition(bool cond, int _Complex a, int _Complex b) { + int _Complex c = cond ? a : b; +} + +// CIR: %[[COND:.*]] = cir.alloca !cir.bool, !cir.ptr, ["cond", init] +// CIR: %[[COMPLEX_A:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a", init] +// CIR: %[[COMPLEX_B:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["b", init] +// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["c", init] +// CIR: %[[TMP_COND:.*]] = cir.load{{.*}} %[[COND]] : !cir.ptr, !cir.bool +// CIR: %[[RESULT_VAL:.*]] = cir.ternary(%[[TMP_COND]], true { +// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[COMPLEX_A]] : !cir.ptr>, !cir.complex +// CIR: cir.yield %[[TMP_A]] : !cir.complex +// CIR: }, false { +// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[COMPLEX_B]] : !cir.ptr>, !cir.complex +// CIR: cir.yield %[[TMP_B]] : !cir.complex +// CIR: }) : (!cir.bool) -> !cir.complex +// CIR: cir.store{{.*}} %[[RESULT_VAL]], %[[RESULT]] : !cir.complex, !cir.ptr> + +// LLVM: %[[COND:.*]] = alloca i8, i64 1, align 1 +// LLVM: %[[COMPLEX_A:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[COMPLEX_B:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[RESULT:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[TMP_COND:.*]] = load i8, ptr %[[COND]], align 1 +// LLVM: %[[COND_VAL:.*]] = trunc i8 %[[TMP_COND]] to i1 +// LLVM: br i1 %[[COND_VAL]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]] +// LLVM: [[TRUE_BB]]: +// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[COMPLEX_A]], align 4 +// LLVM: br label %[[END_BB:.*]] +// LLVM: [[FALSE_BB]]: +// LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[COMPLEX_B]], align 4 +// LLVM: br label %[[END_BB]] +// LLVM: [[END_BB]]: +// LLVM: %[[RESULT_VAL:.*]] = phi { i32, i32 } [ %[[TMP_B]], %[[FALSE_BB]] ], [ %[[TMP_A]], %[[TRUE_BB]] ] +// LLVM: store { i32, i32 } %[[RESULT_VAL]], ptr %[[RESULT]], align 4