https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/224724

Ternary lowers into some blocks, so the values that come into it end up being 
block arguments, so there is no defining op for them.  As a result, the 
'optimization' of the zero/subtract isn't really possible. THis patch uses a 
dyn_cast_if_present instead of a dyn_cast to make sure we don't hit that.

>From bfc731adcfd1587a42f8bf6934be47520b7b3ce9 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Fri, 18 Sep 2026 13:01:53 -0700
Subject: [PATCH] [CIR] Fix assertion with pointer offset in ternary

Ternary lowers into some blocks, so the values that come into it end up
being block arguments, so there is no defining op for them.  As a
result, the 'optimization' of the zero/subtract isn't really possible.
THis patch uses a dyn_cast_if_present instead of a dyn_cast to make sure
we don't hit that.
---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp  |  4 ++--
 clang/test/CIR/CodeGen/ternary.cpp             | 15 +++++++++++++++
 clang/test/CIR/Lowering/ternary.cir            | 18 ++++++++++++++++++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 59654786d1ecad..53b619556f7445 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1882,8 +1882,8 @@ static mlir::Value 
convertToIndexTy(mlir::ConversionPatternRewriter &rewriter,
   auto sub = dyn_cast<mlir::LLVM::SubOp>(indexOp);
   bool rewriteSub = false;
   if (sub) {
-    if (auto lhsConst =
-            dyn_cast<mlir::LLVM::ConstantOp>(sub.getLhs().getDefiningOp())) {
+    if (auto lhsConst = dyn_cast_if_present<mlir::LLVM::ConstantOp>(
+            sub.getLhs().getDefiningOp())) {
       auto lhsConstInt = 
mlir::dyn_cast<mlir::IntegerAttr>(lhsConst.getValue());
       if (lhsConstInt && lhsConstInt.getValue() == 0) {
         index = sub.getRhs();
diff --git a/clang/test/CIR/CodeGen/ternary.cpp 
b/clang/test/CIR/CodeGen/ternary.cpp
index 061794c7835bdc..a7b82a84125de1 100644
--- a/clang/test/CIR/CodeGen/ternary.cpp
+++ b/clang/test/CIR/CodeGen/ternary.cpp
@@ -388,3 +388,18 @@ void ternary_void(bool b) {
 // OGCG: [[FALSE]]:
 // OGCG-NEXT: call void @_Z3barv()
 // OGCG-NEXT: br
+
+void ternary_cleanup(int *p, int n, int m) {
+  p+= ((n > 0) ? n : m) - m;
+}
+// CIR-LABEL: cir.func{{.*}}@_Z15ternary_cleanupPiii
+// CIR: %[[TERNARY:.*]] = cir.ternary(%{{.*}}, true {
+// CIR: cir.sub nsw %[[TERNARY]], %{{.*}} : !s32i loc(#loc166)
+
+// LLVM-LABEL: define {{.*}}@_Z15ternary_cleanupPiii
+// LLVM: %[[TERNARY:.*]] = phi i32
+// LLVM: sub nsw i32 %[[TERNARY]], %{{.*}}
+
+// OGCG-LABEL: define {{.*}}@_Z15ternary_cleanupPiii
+// OGCG: %[[TERNARY:.*]] = phi i32
+// OGCG: sub nsw i32 %[[TERNARY]], %{{.*}}
diff --git a/clang/test/CIR/Lowering/ternary.cir 
b/clang/test/CIR/Lowering/ternary.cir
index 68c98f2d9cc1ec..56128613a12cae 100644
--- a/clang/test/CIR/Lowering/ternary.cir
+++ b/clang/test/CIR/Lowering/ternary.cir
@@ -2,6 +2,7 @@
 // RUN: FileCheck --input-file=%t.ll -check-prefix=LLVM %s
 // REQUIRES: target={{x86_64-linux}}
 
+!s32i = !cir.int<s, 32>
 !u32i = !cir.int<u, 32>
 
 module  {
@@ -15,6 +16,23 @@ module  {
     }) : (!cir.bool) -> !u32i
     cir.return %0 : !u32i
   }
+
+  // The stride of a cir.ptr_stride is narrower than the pointer index width, 
so
+  // it has to be widened to i64. The widening peephole looks through a "sub 
0, x"
+  // to find a unary minus, which must not assume the subtraction's LHS has a
+  // defining operation -- here it is the phi materialized for the ternary.
+  cir.func @ternary_result_as_ptr_stride(%arg0: !cir.ptr<!s32i>, %arg1: 
!cir.bool,
+                                         %arg2: !s32i) -> !cir.ptr<!s32i> {
+    %0 = cir.ternary(%arg1, true {
+      %a = cir.const #cir.int<1> : !s32i
+      cir.yield %a : !s32i
+    }, false {
+      cir.yield %arg2 : !s32i
+    }) : (!cir.bool) -> !s32i
+    %1 = cir.sub %0, %arg2 : !s32i
+    %2 = cir.ptr_stride %arg0, %1 : (!cir.ptr<!s32i>, !s32i) -> !cir.ptr<!s32i>
+    cir.return %2 : !cir.ptr<!s32i>
+  }
 }
 
 // LLVM-LABEL: define i32 {{.*}}@blue(

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

Reply via email to