https://github.com/erichkeane updated 
https://github.com/llvm/llvm-project/pull/184691

>From 944e8961f6d69c79ed39bd1b9fb4621fbfa9cc17 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Wed, 4 Mar 2026 14:16:40 -0800
Subject: [PATCH] [CIR] Fix void ternary operators-

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.
---
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 11 +++++----
 clang/test/CIR/CodeGen/ternary.cpp      | 33 +++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 5 deletions(-)

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