[llvm] c664769 - [AssumeBundles] offset should be added to correctly calculate align
Juneyoung Lee via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 1 20:32:25 PDT 2021
Author: Juneyoung Lee
Date: 2021-04-02T12:32:05+09:00
New Revision: c6647693300be4b74575143db7429f284f3afeb1
URL: https://github.com/llvm/llvm-project/commit/c6647693300be4b74575143db7429f284f3afeb1
DIFF: https://github.com/llvm/llvm-project/commit/c6647693300be4b74575143db7429f284f3afeb1.diff
LOG: [AssumeBundles] offset should be added to correctly calculate align
This is a patch to fix the bug in alignment calculation (see https://reviews.llvm.org/D90529#2619492).
Consider this code:
```
call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 28)]
%arrayidx = getelementptr inbounds i32, i32* %a, i64 -1
; aligment of %arrayidx?
```
The llvm.assume guarantees that `%a - 28` is 32-bytes aligned, meaning that `%a` is 32k + 28 for some k.
Therefore `a - 4` cannot be 32-bytes aligned but the existing code was calculating the pointer as 32-bytes aligned.
The reason why this happened is as follows.
`DiffSCEV` stores `%arrayidx - %a` which is -4.
`OffSCEV` stores the offset value of “align”, which is 28.
`DiffSCEV` + `OffSCEV` = 24 should be used for `a - 4`'s offset from 32k, but `DiffSCEV` - `OffSCEV` = 32 was being used instead.
Reviewed By: Tyker
Differential Revision: https://reviews.llvm.org/D98759
Added:
Modified:
llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
index bccf94fc217fe..45e3b7b05a074 100644
--- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
+++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
@@ -141,7 +141,7 @@ static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV,
// What we really want to know is the overall offset to the aligned
// address. This address is displaced by the provided offset.
- DiffSCEV = SE->getMinusSCEV(DiffSCEV, OffSCEV);
+ DiffSCEV = SE->getAddExpr(DiffSCEV, OffSCEV);
LLVM_DEBUG(dbgs() << "AFI: alignment of " << *Ptr << " relative to "
<< *AlignSCEV << " and offset " << *OffSCEV
diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll b/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
index 610fd448c3b98..80761ad3be6b2 100644
--- a/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
+++ b/llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
@@ -16,7 +16,7 @@ entry:
define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly {
entry:
tail call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 24)]
- %arrayidx = getelementptr inbounds i32, i32* %a, i64 2
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 -2
%0 = load i32, i32* %arrayidx, align 4
ret i32 %0
@@ -28,7 +28,7 @@ entry:
define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly {
entry:
tail call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 28)]
- %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 1
%0 = load i32, i32* %arrayidx, align 4
ret i32 %0
@@ -37,6 +37,19 @@ entry:
; CHECK: ret i32
}
+; TODO: this can be 8-bytes aligned
+define i32 @foo2b(i32* nocapture %a) nounwind uwtable readonly {
+entry:
+ tail call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 28)]
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 -1
+ %0 = load i32, i32* %arrayidx, align 4
+ ret i32 %0
+
+; CHECK-LABEL: @foo2b
+; CHECK: load i32, i32* {{[^,]+}}, align 4
+; CHECK: ret i32
+}
+
define i32 @goo(i32* nocapture %a) nounwind uwtable readonly {
entry:
tail call void @llvm.assume(i1 true) ["align"(i32* %a, i32 32, i32 0)]
diff --git a/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll b/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
index 453899c15c4fb..ddc0e5b641ae2 100644
--- a/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
+++ b/llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
@@ -23,13 +23,13 @@ define i32 @foo2(i32* nocapture %a) nounwind uwtable readonly {
; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 24) ]
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 2
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -2
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 16
; CHECK-NEXT: ret i32 [[TMP0]]
;
entry:
call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 24)]
- %arrayidx = getelementptr inbounds i32, i32* %a, i64 2
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 -2
%0 = load i32, i32* %arrayidx, align 4
ret i32 %0
@@ -40,10 +40,28 @@ define i32 @foo2a(i32* nocapture %a) nounwind uwtable readonly {
; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 28) ]
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -1
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 1
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 32
; CHECK-NEXT: ret i32 [[TMP0]]
;
+entry:
+ call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 28)]
+ %arrayidx = getelementptr inbounds i32, i32* %a, i64 1
+ %0 = load i32, i32* %arrayidx, align 4
+ ret i32 %0
+
+}
+
+; TODO: this can be 8-bytes aligned
+define i32 @foo2b(i32* nocapture %a) nounwind uwtable readonly {
+; CHECK-LABEL: define {{[^@]+}}@foo2b
+; CHECK-SAME: (i32* nocapture [[A:%.*]]) #0
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[A]], i64 32, i64 28) ]
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 -1
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT: ret i32 [[TMP0]]
+;
entry:
call void @llvm.assume(i1 true) ["align"(i32* %a, i64 32, i64 28)]
%arrayidx = getelementptr inbounds i32, i32* %a, i64 -1
More information about the llvm-commits
mailing list