Skip to content

Commit 791c327

Browse files
authored
[CIR] Generate SelectOp instead of TernaryOp for if cheap enough to evaluate unconditionally (#1642)
This came up during the review of llvm/llvm-project#138156 During codegen we check whether the LHS and RHS of the conditional operator are cheap enough to evaluate uncondionally. Unlike classic codegen we still emit `TernaryOp` instead of `SelectOp` and defer that optimization to cir-simplify. This patch changes codegen to directly emit `SelectOp` for `cond ? constant : constant` expressions.
1 parent bcc30f4 commit 791c327

File tree

3 files changed

+21
-78
lines changed

3 files changed

+21
-78
lines changed

clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,30 +2516,22 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator(
25162516
if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
25172517
isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
25182518
bool lhsIsVoid = false;
2519-
auto condV = CGF.evaluateExprAsBool(condExpr);
2519+
mlir::Value condV = CGF.evaluateExprAsBool(condExpr);
25202520
assert(!cir::MissingFeatures::incrementProfileCounter());
25212521

2522-
return builder
2523-
.create<cir::TernaryOp>(
2524-
loc, condV, /*thenBuilder=*/
2525-
[&](mlir::OpBuilder &b, mlir::Location loc) {
2526-
auto lhs = Visit(lhsExpr);
2527-
if (!lhs) {
2528-
lhs = builder.getNullValue(CGF.VoidTy, loc);
2529-
lhsIsVoid = true;
2530-
}
2531-
builder.create<cir::YieldOp>(loc, lhs);
2532-
},
2533-
/*elseBuilder=*/
2534-
[&](mlir::OpBuilder &b, mlir::Location loc) {
2535-
auto rhs = Visit(rhsExpr);
2536-
if (lhsIsVoid) {
2537-
assert(!rhs && "lhs and rhs types must match");
2538-
rhs = builder.getNullValue(CGF.VoidTy, loc);
2539-
}
2540-
builder.create<cir::YieldOp>(loc, rhs);
2541-
})
2542-
.getResult();
2522+
mlir::Value lhs = Visit(lhsExpr);
2523+
if (!lhs) {
2524+
lhs = builder.getNullValue(CGF.VoidTy, loc);
2525+
lhsIsVoid = true;
2526+
}
2527+
2528+
mlir::Value rhs = Visit(rhsExpr);
2529+
if (lhsIsVoid) {
2530+
assert(!rhs && "lhs and rhs types must match");
2531+
rhs = builder.getNullValue(CGF.VoidTy, loc);
2532+
}
2533+
2534+
return builder.createSelect(loc, condV, lhs, rhs);
25432535
}
25442536

25452537
mlir::Value condV = CGF.emitOpOnBoolExpr(loc, condExpr);

clang/test/CIR/CodeGen/ternary.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ double f1(int cond, int n, ...) {
1313

1414
// Fine enough to check it passes the verifying.
1515
// CIR: cir.ternary
16+
17+
int unconditional_evaluation(_Bool cond) {
18+
return cond ? 123 : 456;
19+
// CIR: %[[TRUE_CONST:.+]] = cir.const #cir.int<123>
20+
// CIR: %[[FALSE_CONST:.+]] = cir.const #cir.int<456>
21+
// CIR: cir.select if {{.+}} then %[[TRUE_CONST]] else %[[FALSE_CONST]] : (!cir.bool, !s32i, !s32i) -> !s32i
22+
}

clang/test/CIR/Transforms/ternary-fold.cpp

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)