mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 13:10:42 +00:00
Fix LICM's memory promotion optimization to preserve TBAA tags when
promoting a store in a loop. This was noticed when working on PR14753, but isn't directly related. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171281 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
240b9b1d80
commit
503fc1c488
@ -665,16 +665,18 @@ namespace {
|
||||
AliasSetTracker *
|
||||
DebugLoc DL;
|
||||
int Alignment;
|
||||
MDNode *TBAATag;
|
||||
public:
|
||||
LoopPromoter(Value *SP,
|
||||
const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S,
|
||||
SmallPtrSet<Value*, 4> &PMA,
|
||||
SmallVectorImpl<BasicBlock*> &LEB,
|
||||
SmallVectorImpl<Instruction*> &LIP,
|
||||
AliasSetTracker &ast, DebugLoc dl, int alignment)
|
||||
AliasSetTracker &ast, DebugLoc dl, int alignment,
|
||||
MDNode *TBAATag)
|
||||
: LoadAndStorePromoter(Insts, S), SomePtr(SP),
|
||||
PointerMustAliases(PMA), LoopExitBlocks(LEB), LoopInsertPts(LIP),
|
||||
AST(ast), DL(dl), Alignment(alignment) {}
|
||||
AST(ast), DL(dl), Alignment(alignment), TBAATag(TBAATag) {}
|
||||
|
||||
virtual bool isInstInList(Instruction *I,
|
||||
const SmallVectorImpl<Instruction*> &) const {
|
||||
@ -698,6 +700,7 @@ namespace {
|
||||
StoreInst *NewSI = new StoreInst(LiveInValue, SomePtr, InsertPos);
|
||||
NewSI->setAlignment(Alignment);
|
||||
NewSI->setDebugLoc(DL);
|
||||
if (TBAATag) NewSI->setMetadata(LLVMContext::MD_tbaa, TBAATag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,10 +754,11 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||
// We start with an alignment of one and try to find instructions that allow
|
||||
// us to prove better alignment.
|
||||
unsigned Alignment = 1;
|
||||
MDNode *TBAATag = 0;
|
||||
|
||||
// Check that all of the pointers in the alias set have the same type. We
|
||||
// cannot (yet) promote a memory location that is loaded and stored in
|
||||
// different sizes.
|
||||
// different sizes. While we are at it, collect alignment and TBAA info.
|
||||
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) {
|
||||
Value *ASIV = ASI->getValue();
|
||||
PointerMustAliases.insert(ASIV);
|
||||
@ -796,8 +800,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||
// instruction will be executed, update the alignment.
|
||||
// Larger is better, with the exception of 0 being the best alignment.
|
||||
unsigned InstAlignment = store->getAlignment();
|
||||
if ((InstAlignment > Alignment || InstAlignment == 0)
|
||||
&& (Alignment != 0))
|
||||
if ((InstAlignment > Alignment || InstAlignment == 0) && Alignment != 0)
|
||||
if (isGuaranteedToExecute(*Use)) {
|
||||
GuaranteedToExecute = true;
|
||||
Alignment = InstAlignment;
|
||||
@ -809,6 +812,14 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||
} else
|
||||
return; // Not a load or store.
|
||||
|
||||
// Merge the TBAA tags.
|
||||
if (LoopUses.empty()) {
|
||||
// On the first load/store, just take its TBAA tag.
|
||||
TBAATag = Use->getMetadata(LLVMContext::MD_tbaa);
|
||||
} else if (TBAATag && TBAATag != Use->getMetadata(LLVMContext::MD_tbaa)) {
|
||||
TBAATag = 0;
|
||||
}
|
||||
|
||||
LoopUses.push_back(Use);
|
||||
}
|
||||
}
|
||||
@ -841,7 +852,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||
SmallVector<PHINode*, 16> NewPHIs;
|
||||
SSAUpdater SSA(&NewPHIs);
|
||||
LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks,
|
||||
InsertPts, *CurAST, DL, Alignment);
|
||||
InsertPts, *CurAST, DL, Alignment, TBAATag);
|
||||
|
||||
// Set up the preheader to have a definition of the value. It is the live-out
|
||||
// value from the preheader that uses in the loop will use.
|
||||
@ -850,6 +861,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||
Preheader->getTerminator());
|
||||
PreheaderLoad->setAlignment(Alignment);
|
||||
PreheaderLoad->setDebugLoc(DL);
|
||||
if (TBAATag) PreheaderLoad->setMetadata(LLVMContext::MD_tbaa, TBAATag);
|
||||
SSA.AddAvailableValue(Preheader, PreheaderLoad);
|
||||
|
||||
// Rewrite all the loads in the loop and remember all the definitions from
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: opt < %s -basicaa -licm -S | FileCheck %s
|
||||
; RUN: opt < %s -basicaa -tbaa -licm -S | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||
|
||||
@X = global i32 7 ; <i32*> [#uses=4]
|
||||
@ -134,7 +134,7 @@ Loop: ; preds = %Loop, %0
|
||||
store i32 %x2, i32* @X
|
||||
|
||||
store volatile i32* @X, i32** %P2
|
||||
|
||||
|
||||
%Next = add i32 %j, 1 ; <i32> [#uses=2]
|
||||
%cond = icmp eq i32 %Next, 0 ; <i1> [#uses=1]
|
||||
br i1 %cond, label %Out, label %Loop
|
||||
@ -148,3 +148,41 @@ Out:
|
||||
}
|
||||
|
||||
|
||||
; PR14753 - Preserve TBAA tags when promoting values in a loop.
|
||||
define void @test6(i32 %n, float* nocapture %a, i32* %gi) {
|
||||
entry:
|
||||
store i32 0, i32* %gi, align 4, !tbaa !0
|
||||
%cmp1 = icmp slt i32 0, %n
|
||||
br i1 %cmp1, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%storemerge2 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%idxprom = sext i32 %storemerge2 to i64
|
||||
%arrayidx = getelementptr inbounds float* %a, i64 %idxprom
|
||||
store float 0.000000e+00, float* %arrayidx, align 4, !tbaa !3
|
||||
%0 = load i32* %gi, align 4, !tbaa !0
|
||||
%inc = add nsw i32 %0, 1
|
||||
store i32 %inc, i32* %gi, align 4, !tbaa !0
|
||||
%cmp = icmp slt i32 %inc, %n
|
||||
br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
|
||||
|
||||
for.cond.for.end_crit_edge: ; preds = %for.body
|
||||
br label %for.end
|
||||
|
||||
for.end: ; preds = %for.cond.for.end_crit_edge, %entry
|
||||
ret void
|
||||
|
||||
; CHECK: for.body.lr.ph:
|
||||
; CHECK-NEXT: %gi.promoted = load i32* %gi, align 4, !tbaa !0
|
||||
; CHECK: for.cond.for.end_crit_edge:
|
||||
; CHECK-NEXT: store i32 %inc, i32* %gi, align 4, !tbaa !0
|
||||
}
|
||||
|
||||
!0 = metadata !{metadata !"int", metadata !1}
|
||||
!1 = metadata !{metadata !"omnipotent char", metadata !2}
|
||||
!2 = metadata !{metadata !"Simple C/C++ TBAA"}
|
||||
!3 = metadata !{metadata !"float", metadata !1}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user