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


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to