[llvm] [llubi] Update the implementation of assume align operand bundle (PR #203775)
Zhige Chen via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 14 22:05:06 PDT 2026
https://github.com/nofe1248 updated https://github.com/llvm/llvm-project/pull/203775
>From 4b3520b36b64e2ff8a340763c2cd595bdb19b3d6 Mon Sep 17 00:00:00 2001
From: Zhige Chen <zhigec_cpp at outlook.com>
Date: Sun, 14 Jun 2026 23:55:35 +0800
Subject: [PATCH 1/2] [llubi] Update the implementation of assume align operand
bundle
---
llvm/test/tools/llubi/assume_align_offset.ll | 16 ++++++++++++++++
llvm/test/tools/llubi/assume_operand_bundles.ll | 4 ++--
llvm/tools/llubi/lib/Interpreter.cpp | 16 ++++++----------
3 files changed, 24 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/tools/llubi/assume_align_offset.ll
diff --git a/llvm/test/tools/llubi/assume_align_offset.ll b/llvm/test/tools/llubi/assume_align_offset.ll
new file mode 100644
index 0000000000000..4c13b6f959db3
--- /dev/null
+++ b/llvm/test/tools/llubi/assume_align_offset.ll
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: not llubi --verbose < %s 2>&1 | FileCheck %s
+
+define void @main() {
+ %alloc = alloca i32
+ call void @llvm.assume(i1 true) ["align"(ptr %alloc, i32 17, i32 8)]
+ call void @llvm.assume(i1 true) ["align"(ptr %alloc, i32 17, i32 4)]
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 17, i32 8) ]
+; CHECK-NEXT: Stacktrace:
+; CHECK-NEXT: #0 call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 17, i32 4) ] at @main <stdin>:10
+; CHECK-NEXT: Immediate UB detected: Assume on pointer ptr 0x8 [alloc] with a nonzero adjusted address and a non-power-of-two alignment 17.
+; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/test/tools/llubi/assume_operand_bundles.ll b/llvm/test/tools/llubi/assume_operand_bundles.ll
index e9abb574e0a1b..0c13993b08cf6 100644
--- a/llvm/test/tools/llubi/assume_operand_bundles.ll
+++ b/llvm/test/tools/llubi/assume_operand_bundles.ll
@@ -4,7 +4,7 @@
define void @assume_align_dynamic(ptr %p, i32 %align) {
call void @llvm.assume(i1 true) ["align"(ptr %p, i32 4)]
call void @llvm.assume(i1 true) ["align"(ptr %p, i32 %align)]
- call void @llvm.assume(i1 true) ["align"(ptr %p, i32 %align, i32 20)]
+ call void @llvm.assume(i1 true) ["align"(ptr %p, i32 %align, i32 0)]
ret void
}
@@ -31,7 +31,7 @@ define void @main() {
; CHECK-NEXT: i32 %align = i32 8
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 4) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 %align) ]
-; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 %align, i32 20) ]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %p, i32 %align, i32 0) ]
; CHECK-NEXT: ret void
; CHECK-NEXT: Exiting function: assume_align_dynamic
; CHECK-NEXT: call void @assume_align_dynamic(ptr %alloc, i32 8)
diff --git a/llvm/tools/llubi/lib/Interpreter.cpp b/llvm/tools/llubi/lib/Interpreter.cpp
index 5769d0a4a9c4d..a1460f20e6c58 100644
--- a/llvm/tools/llubi/lib/Interpreter.cpp
+++ b/llvm/tools/llubi/lib/Interpreter.cpp
@@ -830,25 +830,21 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
switch (Kind) {
case Attribute::Alignment: {
// Alignment assumptions should have 2 or 3 arguments.
- // If there are two integer arguments, use the largest power of 2
- // that divides them as the alignment.
APInt Alignment = getIntNonPoison(getValue(GetBundleArg(1)));
+ APInt CheckedAddr = WasOnPtr.address();
if (OBU.Inputs.size() == 3) {
APInt Offset = getIntNonPoison(getValue(GetBundleArg(2)));
- if (!Alignment.isZero() || !Offset.isZero())
- Alignment = APInt::getOneBitSet(
- std::max(Alignment.getBitWidth(), Offset.getBitWidth()),
- std::min(Alignment.countr_zero(), Offset.countr_zero()));
+ CheckedAddr -= Offset.zextOrTrunc(CheckedAddr.getBitWidth());
}
if (!Alignment.isPowerOf2()) {
- if (!WasOnPtr.address().isZero())
- reportImmediateUB() << "Assume on nonzero pointer " << WasOn
- << " with a "
+ if (!CheckedAddr.isZero())
+ reportImmediateUB() << "Assume on pointer " << WasOn
+ << " with a nonzero adjusted address and a "
"non-power-of-two alignment "
<< Alignment << '.';
break;
}
- if (WasOnPtr.address().countr_zero() < Alignment.logBase2())
+ if (CheckedAddr.countr_zero() < Alignment.logBase2())
reportImmediateUB()
<< "The pointer " << WasOn << " violates align(" << Alignment
<< ") assumption.";
>From f5d0b282a2c4d1d8411c601a9c08128ee2b5a9a1 Mon Sep 17 00:00:00 2001
From: Zhige Chen <zhigec_cpp at outlook.com>
Date: Mon, 15 Jun 2026 13:04:51 +0800
Subject: [PATCH 2/2] [llubi] Address comments
---
...offset.ll => assume_non_pow2_align_offset.ll} | 2 +-
.../test/tools/llubi/assume_pow2_align_offset.ll | 16 ++++++++++++++++
llvm/tools/llubi/lib/Interpreter.cpp | 2 +-
3 files changed, 18 insertions(+), 2 deletions(-)
rename llvm/test/tools/llubi/{assume_align_offset.ll => assume_non_pow2_align_offset.ll} (94%)
create mode 100644 llvm/test/tools/llubi/assume_pow2_align_offset.ll
diff --git a/llvm/test/tools/llubi/assume_align_offset.ll b/llvm/test/tools/llubi/assume_non_pow2_align_offset.ll
similarity index 94%
rename from llvm/test/tools/llubi/assume_align_offset.ll
rename to llvm/test/tools/llubi/assume_non_pow2_align_offset.ll
index 4c13b6f959db3..6eb86046a0f04 100644
--- a/llvm/test/tools/llubi/assume_align_offset.ll
+++ b/llvm/test/tools/llubi/assume_non_pow2_align_offset.ll
@@ -11,6 +11,6 @@ define void @main() {
; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 17, i32 8) ]
; CHECK-NEXT: Stacktrace:
-; CHECK-NEXT: #0 call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 17, i32 4) ] at @main <stdin>:10
+; CHECK-NEXT: #0 call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 17, i32 4) ] at @main <stdin>:7
; CHECK-NEXT: Immediate UB detected: Assume on pointer ptr 0x8 [alloc] with a nonzero adjusted address and a non-power-of-two alignment 17.
; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/test/tools/llubi/assume_pow2_align_offset.ll b/llvm/test/tools/llubi/assume_pow2_align_offset.ll
new file mode 100644
index 0000000000000..17a3c0981cb2d
--- /dev/null
+++ b/llvm/test/tools/llubi/assume_pow2_align_offset.ll
@@ -0,0 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_llubi_test_checks.py UTC_ARGS: --version 6
+; RUN: not llubi --verbose < %s 2>&1 | FileCheck %s
+
+define void @main() {
+ %alloc = alloca i32
+ call void @llvm.assume(i1 true) ["align"(ptr %alloc, i32 16, i32 8)]
+ call void @llvm.assume(i1 true) ["align"(ptr %alloc, i32 16, i32 4)]
+ ret void
+}
+; CHECK: Entering function: main
+; CHECK-NEXT: %alloc = alloca i32, align 4 => ptr 0x8 [alloc]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 16, i32 8) ]
+; CHECK-NEXT: Stacktrace:
+; CHECK-NEXT: #0 call void @llvm.assume(i1 true) [ "align"(ptr %alloc, i32 16, i32 4) ] at @main <stdin>:7
+; CHECK-NEXT: Immediate UB detected: The pointer ptr 0x8 [alloc] violates align(16) assumption.
+; CHECK-NEXT: error: Execution of function 'main' failed.
diff --git a/llvm/tools/llubi/lib/Interpreter.cpp b/llvm/tools/llubi/lib/Interpreter.cpp
index a1460f20e6c58..d1351450a3c6f 100644
--- a/llvm/tools/llubi/lib/Interpreter.cpp
+++ b/llvm/tools/llubi/lib/Interpreter.cpp
@@ -834,7 +834,7 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
APInt CheckedAddr = WasOnPtr.address();
if (OBU.Inputs.size() == 3) {
APInt Offset = getIntNonPoison(getValue(GetBundleArg(2)));
- CheckedAddr -= Offset.zextOrTrunc(CheckedAddr.getBitWidth());
+ CheckedAddr -= Offset.sextOrTrunc(CheckedAddr.getBitWidth());
}
if (!Alignment.isPowerOf2()) {
if (!CheckedAddr.isZero())
More information about the llvm-commits
mailing list