From e63898e4a8dc9d948caa432bb350b0237e74d8e5 Mon Sep 17 00:00:00 2001 From: Morris Hafner Date: Fri, 23 May 2025 18:33:33 +0200 Subject: [PATCH] [CIR] Generate SelectOp instead of TernaryOp for if cheap enough to evaluate unconditionally --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 36 ++++++-------- clang/test/CIR/CodeGen/ternary.c | 7 +++ clang/test/CIR/Transforms/ternary-fold.cpp | 56 ---------------------- 3 files changed, 21 insertions(+), 78 deletions(-) delete mode 100644 clang/test/CIR/Transforms/ternary-fold.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 8a81b60c1c2b..3e47d4e10486 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -2516,30 +2516,22 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator( if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) { bool lhsIsVoid = false; - auto condV = CGF.evaluateExprAsBool(condExpr); + mlir::Value condV = CGF.evaluateExprAsBool(condExpr); assert(!cir::MissingFeatures::incrementProfileCounter()); - return builder - .create( - loc, condV, /*thenBuilder=*/ - [&](mlir::OpBuilder &b, mlir::Location loc) { - auto lhs = Visit(lhsExpr); - if (!lhs) { - lhs = builder.getNullValue(CGF.VoidTy, loc); - lhsIsVoid = true; - } - builder.create(loc, lhs); - }, - /*elseBuilder=*/ - [&](mlir::OpBuilder &b, mlir::Location loc) { - auto rhs = Visit(rhsExpr); - if (lhsIsVoid) { - assert(!rhs && "lhs and rhs types must match"); - rhs = builder.getNullValue(CGF.VoidTy, loc); - } - builder.create(loc, rhs); - }) - .getResult(); + mlir::Value lhs = Visit(lhsExpr); + if (!lhs) { + lhs = builder.getNullValue(CGF.VoidTy, loc); + lhsIsVoid = true; + } + + mlir::Value rhs = Visit(rhsExpr); + if (lhsIsVoid) { + assert(!rhs && "lhs and rhs types must match"); + rhs = builder.getNullValue(CGF.VoidTy, loc); + } + + return builder.createSelect(loc, condV, lhs, rhs); } mlir::Value condV = CGF.emitOpOnBoolExpr(loc, condExpr); diff --git a/clang/test/CIR/CodeGen/ternary.c b/clang/test/CIR/CodeGen/ternary.c index 16c20460f102..ee6c71549576 100644 --- a/clang/test/CIR/CodeGen/ternary.c +++ b/clang/test/CIR/CodeGen/ternary.c @@ -13,3 +13,10 @@ double f1(int cond, int n, ...) { // Fine enough to check it passes the verifying. // CIR: cir.ternary + +int unconditional_evaluation(_Bool cond) { + return cond ? 123 : 456; + // CIR: %[[TRUE_CONST:.+]] = cir.const #cir.int<123> + // CIR: %[[FALSE_CONST:.+]] = cir.const #cir.int<456> + // CIR: cir.select if {{.+}} then %[[TRUE_CONST]] else %[[FALSE_CONST]] : (!cir.bool, !s32i, !s32i) -> !s32i +} diff --git a/clang/test/CIR/Transforms/ternary-fold.cpp b/clang/test/CIR/Transforms/ternary-fold.cpp deleted file mode 100644 index eadc74f99a17..000000000000 --- a/clang/test/CIR/Transforms/ternary-fold.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-canonicalize %s -o %t1.cir 2>&1 | FileCheck -check-prefix=CIR-BEFORE %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-simplify %s -o %t2.cir 2>&1 | FileCheck -check-prefix=CIR-AFTER %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -O1 -fclangir -emit-llvm %s -o %t.ll -// RUN: FileCheck --input-file=%t.ll --check-prefix=LLVM %s - -int test(bool x) { - return x ? 1 : 2; -} - -// CIR-BEFORE: cir.func @_Z4testb -// CIR-BEFORE: %{{.+}} = cir.ternary(%{{.+}}, true { -// CIR-BEFORE-NEXT: %[[#A:]] = cir.const #cir.int<1> : !s32i -// CIR-BEFORE-NEXT: cir.yield %[[#A]] : !s32i -// CIR-BEFORE-NEXT: }, false { -// CIR-BEFORE-NEXT: %[[#B:]] = cir.const #cir.int<2> : !s32i -// CIR-BEFORE-NEXT: cir.yield %[[#B]] : !s32i -// CIR-BEFORE-NEXT: }) : (!cir.bool) -> !s32i -// CIR-BEFORE: } - -// CIR-AFTER: cir.func @_Z4testb -// CIR-AFTER: %[[#A:]] = cir.const #cir.int<1> : !s32i -// CIR-AFTER-NEXT: %[[#B:]] = cir.const #cir.int<2> : !s32i -// CIR-AFTER-NEXT: %{{.+}} = cir.select if %{{.+}} then %[[#A]] else %[[#B]] : (!cir.bool, !s32i, !s32i) -> !s32i -// CIR-AFTER: } - -// LLVM: @_Z4testb -// LLVM: %{{.+}} = select i1 %{{.+}}, i32 1, i32 2 -// LLVM: } - -int test2(bool cond) { - constexpr int x = 1; - constexpr int y = 2; - return cond ? x : y; -} - -// CIR-BEFORE: cir.func @_Z5test2b -// CIR-BEFORE: %[[#COND:]] = cir.load{{.*}} %{{.+}} : !cir.ptr, !cir.bool -// CIR-BEFORE-NEXT: %{{.+}} = cir.ternary(%[[#COND]], true { -// CIR-BEFORE-NEXT: %[[#A:]] = cir.const #cir.int<1> : !s32i -// CIR-BEFORE-NEXT: cir.yield %[[#A]] : !s32i -// CIR-BEFORE-NEXT: }, false { -// CIR-BEFORE-NEXT: %[[#B:]] = cir.const #cir.int<2> : !s32i -// CIR-BEFORE-NEXT: cir.yield %[[#B]] : !s32i -// CIR-BEFORE-NEXT: }) : (!cir.bool) -> !s32i -// CIR-BEFORE: } - -// CIR-AFTER: cir.func @_Z5test2b -// CIR-AFTER: %[[#COND:]] = cir.load{{.*}} %{{.+}} : !cir.ptr, !cir.bool -// CIR-AFTER-NEXT: %[[#A:]] = cir.const #cir.int<1> : !s32i -// CIR-AFTER-NEXT: %[[#B:]] = cir.const #cir.int<2> : !s32i -// CIR-AFTER-NEXT: %{{.+}} = cir.select if %[[#COND]] then %[[#A]] else %[[#B]] : (!cir.bool, !s32i, !s32i) -> !s32i -// CIR-AFTER: } - -// LLVM: @_Z5test2b -// LLVM: %{{.+}} = select i1 %{{.+}}, i32 1, i32 2 -// LLVM: }