-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[ConstantFolding] Handle reading from type padding #144330
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
Conversation
ReadDataFromGlobal() did not handle reads from the padding of types (in the sense of type store size != type alloc size, rather than struct padding). Just bail out in that case. (Alternatively could make this return zero as well, but the value seems dubious.) Fixes llvm#144279.
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesReadDataFromGlobal() did not handle reads from the padding of types (in the sense of type store size != type alloc size, rather than struct padding). Just bail out in that case. (Alternatively could make this return zero as well, but the value seems dubious.) Fixes #144279. Full diff: https://github.com/llvm/llvm-project/pull/144330.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 2b7a438a9ef01..7bd67d2a95dbc 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -432,6 +432,10 @@ bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr,
assert(ByteOffset <= DL.getTypeAllocSize(C->getType()) &&
"Out of range access");
+ // Trying to read type padding.
+ if (ByteOffset >= DL.getTypeStoreSize(C->getType()))
+ return false;
+
// If this element is zero or undefined, we can just return since *CurPtr is
// zero initialized.
if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
index dd75560e25ced..134025514dcf6 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/loads.ll
@@ -441,3 +441,41 @@ define i128 @load-128bit(){
%1 = load i128, ptr @global128, align 4
ret i128 %1
}
+
+
+@i40_struct = constant { i40, i8 } { i40 0, i8 1 }
+@i40_array = constant [2 x i40] [i40 0, i40 1]
+
+define i8 @load_i40_struct_padding() {
+; CHECK-LABEL: @load_i40_struct_padding(
+; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6), align 1
+; CHECK-NEXT: ret i8 [[V]]
+;
+ %v = load i8, ptr getelementptr (i8, ptr @i40_struct, i64 6)
+ ret i8 %v
+}
+
+define i16 @load_i40_struct_partial_padding() {
+; CHECK-LABEL: @load_i40_struct_partial_padding(
+; CHECK-NEXT: ret i16 0
+;
+ %v = load i16, ptr getelementptr (i8, ptr @i40_struct, i64 4)
+ ret i16 %v
+}
+
+define i8 @load_i40_array_padding() {
+; CHECK-LABEL: @load_i40_array_padding(
+; CHECK-NEXT: [[V:%.*]] = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6), align 1
+; CHECK-NEXT: ret i8 [[V]]
+;
+ %v = load i8, ptr getelementptr (i8, ptr @i40_array, i64 6)
+ ret i8 %v
+}
+
+define i16 @load_i40_array_partial_padding() {
+; CHECK-LABEL: @load_i40_array_partial_padding(
+; CHECK-NEXT: ret i16 0
+;
+ %v = load i16, ptr getelementptr (i8, ptr @i40_array, i64 4)
+ ret i16 %v
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is weird to me that the following load (across the padding) gets folded into 0.
@i40_struct = constant { i40, i8 } { i40 0, i8 1 }
define i16 @load_i40_struct_padding() {
%v = load i16, ptr getelementptr (i8, ptr @i40_struct, i64 4) ; [4, 6)
ret i16 %v
}
I think it is ok to always return zero, as the padding is initialized with undef.
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG. The PR title should be updated.
ReadDataFromGlobal() did not handle reads from the padding of types (in the sense of type store size != type alloc size, rather than struct padding).
Return zero in that case.
Fixes #144279.