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

Sergey Kachkov via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 3 06:18:01 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
----------------
skachkov-sc wrote:

Thank you, I've added this case to the LIT tests, too (though we don't have any issues there: after constant offset extraction the index of GEP looks like `%sub1 = sub i64 0, %shr`, so it's determined as non-positive and inbounds is not preserved)

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


More information about the llvm-commits mailing list