[llvm] [LAA] Fix off-by-EltSize in negative-step deref bounds check (PR #211964)
Aleksandr Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 31 09:04:09 PDT 2026
================
@@ -0,0 +1,94 @@
+; RUN: opt -passes='print<access-info>' -disable-output %s 2>&1 | FileCheck %s
+
+; Reverse i32 loop over 4 elements whose access range exactly fills the
+; dereferenceable region (deref(16), reads bytes [0, 16)).
+;
+; LAA recognises that the AR fits and emits tight bounds
+; (Low: %A, High: %A + 16).
+;
+; Pseudocode:
+; // A, B: at least 4 i32s dereferenceable each
+; for (i64 i = 3; i >= 0; --i) {
+; i32 l = A[i]; // A[3], A[2], A[1], A[0]
+; B[i] = 0;
+; if (l == 0) break;
+; }
+
+define void @reverse_reaches_base(ptr dereferenceable(16) %A, ptr dereferenceable(16) %B) {
+; CHECK-LABEL: 'reverse_reaches_base'
+; CHECK: Group GRP0:
+; CHECK-NEXT: (Low: %B High: (16 + %B)<nuw>)
+; CHECK-NEXT: Member: {(12 + %B)<nuw>,+,-4}<nw><%loop>
+; CHECK: Group GRP1:
+; CHECK-NEXT: (Low: %A High: (16 + %A)<nuw>)
+; CHECK-NEXT: Member: {(12 + %A)<nuw>,+,-4}<nw><%loop>
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 3, %entry ], [ %iv.dec, %latch ]
+ %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
+ %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
+ %l = load i32, ptr %gep.A, align 4
+ store i32 0, ptr %gep.B, align 4
+ %uncntable = icmp eq i32 %l, 0
+ br i1 %uncntable, label %exit.early, label %latch
+
+latch:
+ %iv.dec = add nsw i64 %iv, -1
+ %ec = icmp eq i64 %iv, 0
+ br i1 %ec, label %exit.done, label %loop
+
+exit.early:
+ ret void
+
+exit.done:
+ ret void
+}
+
+; Reverse i32 loop whose top read spills one byte past the deref end.
+; The IR is UB by construction: top i32 read at byte 13 covers [13, 17),
----------------
aleks-tmb wrote:
I do. I expected the preparatory NFC patch to be merged first, and then planned to rebase this patch on top of it.
https://github.com/llvm/llvm-project/pull/211964
More information about the llvm-commits
mailing list