Skip to content

Commit 1aa6b99

Browse files
authored
[CIR] Implement AbstractConditionalOperator for ComplexType (#147090)
Implement AbstractConditionalOperator support for ComplexType #141365
1 parent 463b3cb commit 1aa6b99

File tree

2 files changed

+90
-5
lines changed

2 files changed

+90
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
3939
void emitStoreOfComplex(mlir::Location loc, mlir::Value val, LValue lv,
4040
bool isInit);
4141

42+
mlir::Value
43+
VisitAbstractConditionalOperator(const AbstractConditionalOperator *e);
4244
mlir::Value VisitArraySubscriptExpr(Expr *e);
4345
mlir::Value VisitBinAssign(const BinaryOperator *e);
4446
mlir::Value VisitBinComma(const BinaryOperator *e);
@@ -127,6 +129,27 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location loc, mlir::Value val,
127129
builder.createStore(loc, val, destAddr);
128130
}
129131

132+
mlir::Value ComplexExprEmitter::VisitAbstractConditionalOperator(
133+
const AbstractConditionalOperator *e) {
134+
mlir::Value condValue = Visit(e->getCond());
135+
mlir::Location loc = cgf.getLoc(e->getSourceRange());
136+
137+
return builder
138+
.create<cir::TernaryOp>(
139+
loc, condValue,
140+
/*thenBuilder=*/
141+
[&](mlir::OpBuilder &b, mlir::Location loc) {
142+
mlir::Value trueValue = Visit(e->getTrueExpr());
143+
b.create<cir::YieldOp>(loc, trueValue);
144+
},
145+
/*elseBuilder=*/
146+
[&](mlir::OpBuilder &b, mlir::Location loc) {
147+
mlir::Value falseValue = Visit(e->getFalseExpr());
148+
b.create<cir::YieldOp>(loc, falseValue);
149+
})
150+
.getResult();
151+
}
152+
130153
mlir::Value ComplexExprEmitter::VisitArraySubscriptExpr(Expr *e) {
131154
return emitLoadOfLValue(e);
132155
}

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -571,10 +571,10 @@ void foo23(int _Complex a, int _Complex b) {
571571
// OGCG: %[[B_REAL:.*]] = load i32, ptr %[[B_REAL_PTR]], align 4
572572
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_B]], i32 0, i32 1
573573
// OGCG: %[[B_IMAG:.*]] = load i32, ptr %[[B_IMAG_PTR]], align 4
574-
// OGCG: %[[RESULT_REAL_PT:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 0
575-
// OGCG: %[[RESULT_IMAG_PT:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 1
576-
// OGCG: store i32 %[[B_REAL]], ptr %[[RESULT_REAL_PT]], align 4
577-
// OGCG: store i32 %[[B_IMAG]], ptr %[[RESULT_IMAG_PT]], align 4
574+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 0
575+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 1
576+
// OGCG: store i32 %[[B_REAL]], ptr %[[RESULT_REAL_PTR]], align 4
577+
// OGCG: store i32 %[[B_IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4
578578

579579
void foo24() {
580580
int _Complex arr[2];
@@ -655,6 +655,68 @@ void foo26(int _Complex* a) {
655655
// OGCG: store i32 %[[A_REAL]], ptr %[[B_REAL_PTR]], align 4
656656
// OGCG: store i32 %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 4
657657

658+
void foo27(bool cond, int _Complex a, int _Complex b) {
659+
int _Complex c = cond ? a : b;
660+
}
661+
662+
// CIR: %[[COND:.*]] = cir.alloca !cir.bool, !cir.ptr<!cir.bool>, ["cond", init]
663+
// CIR: %[[COMPLEX_A:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["a", init]
664+
// CIR: %[[COMPLEX_B:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["b", init]
665+
// CIR: %[[RESULT:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["c", init]
666+
// CIR: %[[TMP_COND:.*]] = cir.load{{.*}} %[[COND]] : !cir.ptr<!cir.bool>, !cir.bool
667+
// CIR: %[[RESULT_VAL:.*]] = cir.ternary(%[[TMP_COND]], true {
668+
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[COMPLEX_A]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
669+
// CIR: cir.yield %[[TMP_A]] : !cir.complex<!s32i>
670+
// CIR: }, false {
671+
// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[COMPLEX_B]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
672+
// CIR: cir.yield %[[TMP_B]] : !cir.complex<!s32i>
673+
// CIR: }) : (!cir.bool) -> !cir.complex<!s32i>
674+
// CIR: cir.store{{.*}} %[[RESULT_VAL]], %[[RESULT]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>
675+
676+
// LLVM: %[[COND:.*]] = alloca i8, i64 1, align 1
677+
// LLVM: %[[COMPLEX_A:.*]] = alloca { i32, i32 }, i64 1, align 4
678+
// LLVM: %[[COMPLEX_B:.*]] = alloca { i32, i32 }, i64 1, align 4
679+
// LLVM: %[[RESULT:.*]] = alloca { i32, i32 }, i64 1, align 4
680+
// LLVM: %[[TMP_COND:.*]] = load i8, ptr %[[COND]], align 1
681+
// LLVM: %[[COND_VAL:.*]] = trunc i8 %[[TMP_COND]] to i1
682+
// LLVM: br i1 %[[COND_VAL]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]
683+
// LLVM: [[TRUE_BB]]:
684+
// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[COMPLEX_A]], align 4
685+
// LLVM: br label %[[END_BB:.*]]
686+
// LLVM: [[FALSE_BB]]:
687+
// LLVM: %[[TMP_B:.*]] = load { i32, i32 }, ptr %[[COMPLEX_B]], align 4
688+
// LLVM: br label %[[END_BB]]
689+
// LLVM: [[END_BB]]:
690+
// LLVM: %[[RESULT_VAL:.*]] = phi { i32, i32 } [ %[[TMP_B]], %[[FALSE_BB]] ], [ %[[TMP_A]], %[[TRUE_BB]] ]
691+
// LLVM: store { i32, i32 } %[[RESULT_VAL]], ptr %[[RESULT]], align 4
692+
693+
// OGCG: %[[COMPLEX_A:.*]] = alloca { i32, i32 }, align 4
694+
// OGCG: %[[COMPLEX_B:.*]] = alloca { i32, i32 }, align 4
695+
// OGCG: %[[COND:.*]] = alloca i8, align 1
696+
// OGCG: %[[RESULT:.*]] = alloca { i32, i32 }, align 4
697+
// OGCG: %[[TMP_COND:.*]] = load i8, ptr %[[COND]], align 1
698+
// OGCG: %[[COND_VAL:.*]] = trunc i8 %[[TMP_COND]] to i1
699+
// OGCG: br i1 %[[COND_VAL]], label %[[TRUE_BB:.*]], label %[[FALSE_BB:.*]]
700+
// OGCG: [[TRUE_BB]]:
701+
// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_A]], i32 0, i32 0
702+
// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 4
703+
// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_A]], i32 0, i32 1
704+
// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4
705+
// OGCG: br label %[[END_BB:.*]]
706+
// OGCG: [[FALSE_BB]]:
707+
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_B]], i32 0, i32 0
708+
// OGCG: %[[B_REAL:.*]] = load i32, ptr %[[B_REAL_PTR]], align 4
709+
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[COMPLEX_B]], i32 0, i32 1
710+
// OGCG: %[[B_IMAG:.*]] = load i32, ptr %[[B_IMAG_PTR]], align 4
711+
// OGCG: br label %[[END_BB]]
712+
// OGCG: [[END_BB]]:
713+
// OGCG: %[[REAL:.*]] = phi i32 [ %[[A_REAL]], %[[TRUE_BB]] ], [ %[[B_REAL]], %[[FALSE_BB]] ]
714+
// OGCG: %[[IMAG:.*]] = phi i32 [ %[[A_IMAG]], %[[TRUE_BB]] ], [ %[[B_IMAG]], %[[FALSE_BB]] ]
715+
// OGCG: %[[RESULT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 0
716+
// OGCG: %[[RESULT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[RESULT]], i32 0, i32 1
717+
// OGCG: store i32 %[[REAL]], ptr %[[RESULT_REAL_PTR]], align 4
718+
// OGCG: store i32 %[[IMAG]], ptr %[[RESULT_IMAG_PTR]], align 4
719+
658720
void foo29() {
659721
using IntComplex = int _Complex;
660722
int _Complex a = IntComplex{};
@@ -671,4 +733,4 @@ void foo29() {
671733
// OGCG: %[[INIT_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[INIT]], i32 0, i32 0
672734
// OGCG: %[[INIT_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[INIT]], i32 0, i32 1
673735
// OGCG: store i32 0, ptr %[[INIT_REAL_PTR]], align 4
674-
// OGCG: store i32 0, ptr %[[INIT_IMAG_PTR]], align 4
736+
// OGCG: store i32 0, ptr %[[INIT_IMAG_PTR]], align 4

0 commit comments

Comments
 (0)