[clang] 743e4df - [CIR] Fix void ternary operators- (#184691)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 5 06:30:14 PST 2026
Author: Erich Keane
Date: 2026-03-05T14:30:05Z
New Revision: 743e4df2e24f77278aeb65a1776984b4b8fb247a
URL: https://github.com/llvm/llvm-project/commit/743e4df2e24f77278aeb65a1776984b4b8fb247a
DIFF: https://github.com/llvm/llvm-project/commit/743e4df2e24f77278aeb65a1776984b4b8fb247a.diff
LOG: [CIR] Fix void ternary operators- (#184691)
I discovered this while working on something else, but we were doing a
'getTerminator' on a block that we didn't know whether it had a
terminator, and MLIR causes an assert in this case. This patch
re-factors the code to better check whether it might have a terminator
(to assuage the assert in mlir::Block), and get the correct value out.
The fixup later in the ternary setup correctly gets the 'void' yields
correct, so everything else gets fixed eventually.
Added:
Modified:
clang/lib/CIR/Dialect/IR/CIRDialect.cpp
clang/test/CIR/CodeGen/ternary.cpp
Removed:
################################################################################
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 2599125c5bb4a..6f6d2f0a82916 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2563,14 +2563,15 @@ void cir::TernaryOp::build(
// Get result type from whichever branch has a yield (the other may have
// unreachable from a throw expression)
- auto yield =
- dyn_cast_or_null<cir::YieldOp>(trueRegion->back().getTerminator());
- if (!yield)
+ cir::YieldOp yield;
+ if (trueRegion->back().mightHaveTerminator())
+ yield = dyn_cast_or_null<cir::YieldOp>(trueRegion->back().getTerminator());
+ if (!yield && falseRegion->back().mightHaveTerminator())
yield = dyn_cast_or_null<cir::YieldOp>(falseRegion->back().getTerminator());
- assert((yield && yield.getNumOperands() <= 1) &&
+ assert((!yield || yield.getNumOperands() <= 1) &&
"expected zero or one result type");
- if (yield.getNumOperands() == 1)
+ if (yield && yield.getNumOperands() == 1)
result.addTypes(TypeRange{yield.getOperandTypes().front()});
}
diff --git a/clang/test/CIR/CodeGen/ternary.cpp b/clang/test/CIR/CodeGen/ternary.cpp
index 387c6ae28b6f1..7df4afdb15a1f 100644
--- a/clang/test/CIR/CodeGen/ternary.cpp
+++ b/clang/test/CIR/CodeGen/ternary.cpp
@@ -355,3 +355,36 @@ void test_cond_const_false_lvalue() {
// OGCG: %[[B:.*]] = alloca i32
// OGCG-NOT: br i1
// OGCG: store i32 88, ptr %[[B]]
+
+void foo(), bar();
+void ternary_void(bool b) {
+ b ? foo(): bar();
+}
+
+// CIR-LABEL: cir.func{{.*}}@_Z12ternary_voidb
+// CIR: %[[ARG:.*]] = cir.alloca !cir.bool
+// CIR: %[[LOAD_ARG:.*]] = cir.load{{.*}}%[[ARG]] : !cir.ptr<!cir.bool>
+// CIR: cir.ternary(%[[LOAD_ARG]], true {
+// CIR-NEXT: cir.call @_Z3foov()
+// CIR-NEXT: cir.yield
+// CIR-NEXT: }, false {
+// CIR-NEXT: cir.call @_Z3barv()
+// CIR-NEXT: cir.yield
+// CIR-NEXT: }) : (!cir.bool) -> ()
+// CIR-NEXT: cir.return
+// LLVM-LABEL: define{{.*}}@_Z12ternary_voidb
+// LLVM: br i1 %{{.*}}, label %[[TRUE:.*]], label %[[FALSE:.*]]
+// LLVM: [[TRUE]]:
+// LLVM-NEXT: call void @_Z3foov()
+// LLVM-NEXT: br
+// LLVM: [[FALSE]]:
+// LLVM-NEXT: call void @_Z3barv()
+// LLVM-NEXT: br
+// OGCG-LABEL: define{{.*}}@_Z12ternary_voidb
+// OGCG: br i1 %{{.*}}, label %[[TRUE:.*]], label %[[FALSE:.*]]
+// OGCG: [[TRUE]]:
+// OGCG-NEXT: call void @_Z3foov()
+// OGCG-NEXT: br
+// OGCG: [[FALSE]]:
+// OGCG-NEXT: call void @_Z3barv()
+// OGCG-NEXT: br
More information about the cfe-commits
mailing list