[llvm] [SeparateConstOffsetFromGEP] Fix incorrect inbounds flag in case of non-negative index but negative offset (PR #190192)

Eli Friedman via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 2 11:53:09 PDT 2026


================
@@ -289,3 +289,24 @@ entry:
   store i32 %i, ptr %gep8
   ret i32 undef
 }
+
+define i64 @test_inbounds(ptr %arr, i64 %x) {
+; CHECK-LABEL: @test_inbounds(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[MIN:%.*]] = tail call i64 @llvm.umin.i64(i64 [[X:%.*]], i64 4)
+; CHECK-NEXT:    [[XOR:%.*]] = xor i64 [[MIN]], -1
+; CHECK-NEXT:    [[SHR:%.*]] = lshr i64 [[XOR]], 1
+; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr [6 x i64], ptr [[ARR:%.*]], i64 0, i64 [[SHR]]
+; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 40
+; CHECK-NEXT:    [[RES:%.*]] = load i64, ptr [[GEP2]], align 8
+; CHECK-NEXT:    ret i64 [[RES]]
+;
+entry:
+  %min = tail call i64 @llvm.umin.i64(i64 %x, i64 4)
+  %xor = xor i64 %min, -1
+  %shr = lshr i64 %xor, 1
+  %sub = add nsw i64 %shr, -9223372036854775803
----------------
efriedma-quic wrote:

For reference, the math is equivalent to the following:

```
  %min = tail call i64 @llvm.umin.i64(i64 %x, i64 4)
  %shr = lshr i64 %min, 1
  %sub = sub nsw nuw i64 4, %shr
```

https://github.com/llvm/llvm-project/pull/190192


More information about the llvm-commits mailing list