Author: Erich Keane Date: 2026-09-21T13:47:08Z New Revision: 04b52bf1dc212b3af60d3d071defa4e034ece382
URL: https://github.com/llvm/llvm-project/commit/04b52bf1dc212b3af60d3d071defa4e034ece382 DIFF: https://github.com/llvm/llvm-project/commit/04b52bf1dc212b3af60d3d071defa4e034ece382.diff LOG: [CIR] Fix assertion with pointer offset in ternary (#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. Added: Modified: clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp clang/test/CIR/CodeGen/ternary.cpp clang/test/CIR/Lowering/ternary.cir Removed: ################################################################################ diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 50adaad64a763..09ec70ef03286 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 061794c7835bd..a7b82a84125de 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 68c98f2d9cc1e..56128613a12ca 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
