[PATCH] D81004: [MemorySSA] Skip phi translation for phis in cycles (WIP).
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 2 07:08:52 PDT 2020
fhahn created this revision.
fhahn added reviewers: george.burgess.iv, asbirlea, efriedma.
Herald added subscribers: kosarev, Prazek.
Herald added a project: LLVM.
Currently we use the phi-translated address when traversing the
definitions upwards. The translated address is then used to check for
clobbers along a path. If the Phi is part of a cycle, this is not
correct I think, as it means we only check for clobbers with the initial
value of the cycle. But it is possible that a definition along the path
clobbers an address other than the initial value of the cycle.
This patch just detects trivial cycles, as I want to make sure I am not
missing anything before generalizing.
Consider the example below. Without this patch, MemorySSA will set the
defining access of `%lv = load i16, i16* %arrayidx, align 2, !tbaa !3`
to LiveOnEntry, because it phi-translates the location of the load to
`getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 1` in
%entry, but the loop body is executed twice and it loads from
`getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 1` andj
`getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0`. The
latter aliases the store in %entry.
define i32 @main(i32* noalias %ptr) {
entry:
%s1.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
store i16 1, i16* %s1.ptr, align 2, !tbaa !3
br label %for.body
for.body:
%storemerge2 = phi i32 [ 1, %entry ], [ %dec, %for.body ]
%idxprom1 = zext i32 %storemerge2 to i64
%arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 %idxprom1
%lv = load i16, i16* %arrayidx, align 2, !tbaa !3
%conv = sext i16 %lv to i32
store i32 %conv, i32* %ptr, align 4, !tbaa !7
%dec = add nsw i32 %storemerge2, -1
%cmp = icmp sgt i32 %storemerge2, 0
br i1 %cmp, label %for.body, label %for.end
for.end:
%s2.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
store i16 0, i16* %s2.ptr, align 2, !tbaa !3
ret i32 0
}
Fixes PR46156.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D81004
Files:
llvm/include/llvm/Analysis/MemorySSA.h
llvm/test/Analysis/MemorySSA/phi-translation-cycle.ll
Index: llvm/test/Analysis/MemorySSA/phi-translation-cycle.ll
===================================================================
--- /dev/null
+++ llvm/test/Analysis/MemorySSA/phi-translation-cycle.ll
@@ -0,0 +1,45 @@
+; RUN: opt -basicaa -tbaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s --check-prefixes=CHECK
+; RUN: opt -aa-pipeline=basic-aa,type-based-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK
+
+; Test case for PR46156. Make sure phi translation is skipped for cyclic phis.
+
+ at c = local_unnamed_addr global [2 x i16] zeroinitializer, align 2
+
+define i32 @test1(i32* noalias %ptr) {
+; CHECK-LABEL: define i32 @test1
+; CHECK-LABEL: entry:
+; CHECK: ; 1 = MemoryDef(liveOnEntry)
+; CHECK-NEXT: store i16 1, i16* %s1.ptr, align 2
+
+; CHECK-LABEL: %for.body
+; CHECK: ; MemoryUse(1) MayAlias
+; CHECK-NEXT: %lv = load i16, i16* %arrayidx, align 2, !tbaa !0
+
+entry:
+ %s1.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
+ store i16 1, i16* %s1.ptr, align 2, !tbaa !0
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %storemerge2 = phi i32 [ 1, %entry ], [ %dec, %for.body ]
+ %idxprom1 = zext i32 %storemerge2 to i64
+ %arrayidx = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 %idxprom1
+ %lv = load i16, i16* %arrayidx, align 2, !tbaa !0
+ %conv = sext i16 %lv to i32
+ store i32 %conv, i32* %ptr, align 4, !tbaa !4
+ %dec = add nsw i32 %storemerge2, -1
+ %cmp = icmp sgt i32 %storemerge2, 0
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end: ; preds = %for.body
+ %s2.ptr = getelementptr inbounds [2 x i16], [2 x i16]* @c, i64 0, i64 0
+ store i16 0, i16* %s2.ptr, align 2, !tbaa !0
+ ret i32 0
+}
+
+!0 = !{!1, !1, i64 0}
+!1 = !{!"short", !2, i64 0}
+!2 = !{!"omnipotent char", !3, i64 0}
+!3 = !{!"Simple C/C++ TBAA"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !2, i64 0}
Index: llvm/include/llvm/Analysis/MemorySSA.h
===================================================================
--- llvm/include/llvm/Analysis/MemorySSA.h
+++ llvm/include/llvm/Analysis/MemorySSA.h
@@ -1217,7 +1217,18 @@
private:
void fillInCurrentPair() {
CurrentPair.first = *DefIterator;
- if (WalkingPhi && Location.Ptr) {
+ auto HasTrivialCycle = [](auto Def) {
+ BasicBlock *DefBlock = Def->getBlock();
+ auto *DefPhi = dyn_cast<MemoryPhi>(Def);
+ return DefPhi &&
+ any_of(DefPhi->blocks(), [DefBlock](BasicBlock *IncomingBlock) {
+ return DefBlock == IncomingBlock;
+ });
+ };
+ // Using a phi-translated address is only safe if the PHI is not part of a
+ // cycle. Otherwise we only check the address accessed in the first visit of
+ // the cycle.
+ if (WalkingPhi && Location.Ptr && !HasTrivialCycle(OriginalAccess)) {
PHITransAddr Translator(
const_cast<Value *>(Location.Ptr),
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81004.267874.patch
Type: text/x-patch
Size: 3116 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200602/835fd44d/attachment.bin>
More information about the llvm-commits
mailing list