-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[Attributor] Check range size before constant fold load #151359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Attributor] Check range size before constant fold load #151359
Conversation
|
I'm currently trying to resolve an issue that can be demonstrated by the following code. In this example, we have a constant global variable When we call In this case, after Since the user call back is skipped, there is nothing in That said, I'm not sure if the fix here is correct. If it is not, what is the semantics of |
3514320 to
97a51a3
Compare
|
@llvm/pr-subscribers-llvm-transforms Author: Shilei Tian (shiltian) ChangesIf the range size doesn't match the type size, it might read wrong data. Full diff: https://github.com/llvm/llvm-project/pull/151359.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 077d29f7499a4..3b59ebbbb9322 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -272,6 +272,9 @@ AA::getInitialValueForObj(Attributor &A, const AbstractAttribute &QueryingAA,
}
if (RangePtr && !RangePtr->offsetOrSizeAreUnknown()) {
+ int64_t StorageSize = DL.getTypeStoreSize(&Ty);
+ if (StorageSize != RangePtr->Size)
+ return nullptr;
APInt Offset = APInt(64, RangePtr->Offset);
return ConstantFoldLoadFromConst(Initializer, &Ty, Offset, DL);
}
diff --git a/llvm/test/Transforms/Attributor/range-and-constant-fold.ll b/llvm/test/Transforms/Attributor/range-and-constant-fold.ll
new file mode 100644
index 0000000000000..fcc5e6e0fd52f
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/range-and-constant-fold.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=attributor %s -o - | FileCheck %s
+
+@g = internal unnamed_addr addrspace(4) constant [3 x i8] c"12\00", align 16
+
+define void @foo(i32 %a, i32 %b, ptr %p) {
+; CHECK-LABEL: define void @foo(
+; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], ptr nofree nonnull writeonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A]], [[B]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[L1:.*]], label %[[L2:.*]]
+; CHECK: [[L1]]:
+; CHECK-NEXT: br label %[[L3:.*]]
+; CHECK: [[L2]]:
+; CHECK-NEXT: br label %[[L3]]
+; CHECK: [[L3]]:
+; CHECK-NEXT: [[PHI:%.*]] = phi ptr addrspace(4) [ @g, %[[L1]] ], [ getelementptr inbounds nuw (i8, ptr addrspace(4) @g, i64 1), %[[L2]] ]
+; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr addrspace(4) [[PHI]], align 1
+; CHECK-NEXT: store i8 [[LOAD]], ptr [[P]], align 1
+; CHECK-NEXT: ret void
+;
+entry:
+ %cmp = icmp ne i32 %a, %b
+ br i1 %cmp, label %l1, label %l2
+l1:
+ br label %l3
+l2:
+ br label %l3
+l3:
+ %phi = phi ptr addrspace(4) [ @g, %l1 ], [ getelementptr inbounds nuw (i8, ptr addrspace(4) @g, i64 1), %l2 ]
+ %load = load i8, ptr addrspace(4) %phi
+ store i8 %load, ptr %p
+ ret void
+}
|
|
It doesn't seem like this PR causes any changes (except the new test) to the existing test cases so I assume it'd be fine. |
|
ping |
If the range size doesn't match the type size, it might read wrong data.
97a51a3 to
003c4a9
Compare
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/24524 Here is the relevant piece of the build log for the reference |
If the range size doesn't match the type size, it might read wrong data.
If the range size doesn't match the type size, it might read wrong data.
If the range size doesn't match the type size, it might read wrong data.

If the range size doesn't match the type size, it might read wrong data.