forked from OSchip/llvm-project
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. llvm-svn: 171281
This commit is contained in:
parent
eeefe1bc07
commit
f5cca68c2c
|
@ -665,16 +665,18 @@ namespace {
|
||||||
AliasSetTracker *
|
AliasSetTracker *
|
||||||
DebugLoc DL;
|
DebugLoc DL;
|
||||||
int Alignment;
|
int Alignment;
|
||||||
|
MDNode *TBAATag;
|
||||||
public:
|
public:
|
||||||
LoopPromoter(Value *SP,
|
LoopPromoter(Value *SP,
|
||||||
const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S,
|
const SmallVectorImpl<Instruction*> &Insts, SSAUpdater &S,
|
||||||
SmallPtrSet<Value*, 4> &PMA,
|
SmallPtrSet<Value*, 4> &PMA,
|
||||||
SmallVectorImpl<BasicBlock*> &LEB,
|
SmallVectorImpl<BasicBlock*> &LEB,
|
||||||
SmallVectorImpl<Instruction*> &LIP,
|
SmallVectorImpl<Instruction*> &LIP,
|
||||||
AliasSetTracker &ast, DebugLoc dl, int alignment)
|
AliasSetTracker &ast, DebugLoc dl, int alignment,
|
||||||
|
MDNode *TBAATag)
|
||||||
: LoadAndStorePromoter(Insts, S), SomePtr(SP),
|
: LoadAndStorePromoter(Insts, S), SomePtr(SP),
|
||||||
PointerMustAliases(PMA), LoopExitBlocks(LEB), LoopInsertPts(LIP),
|
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,
|
virtual bool isInstInList(Instruction *I,
|
||||||
const SmallVectorImpl<Instruction*> &) const {
|
const SmallVectorImpl<Instruction*> &) const {
|
||||||
|
@ -698,6 +700,7 @@ namespace {
|
||||||
StoreInst *NewSI = new StoreInst(LiveInValue, SomePtr, InsertPos);
|
StoreInst *NewSI = new StoreInst(LiveInValue, SomePtr, InsertPos);
|
||||||
NewSI->setAlignment(Alignment);
|
NewSI->setAlignment(Alignment);
|
||||||
NewSI->setDebugLoc(DL);
|
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
|
// We start with an alignment of one and try to find instructions that allow
|
||||||
// us to prove better alignment.
|
// us to prove better alignment.
|
||||||
unsigned Alignment = 1;
|
unsigned Alignment = 1;
|
||||||
|
MDNode *TBAATag = 0;
|
||||||
|
|
||||||
// Check that all of the pointers in the alias set have the same type. We
|
// 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
|
// 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) {
|
for (AliasSet::iterator ASI = AS.begin(), E = AS.end(); ASI != E; ++ASI) {
|
||||||
Value *ASIV = ASI->getValue();
|
Value *ASIV = ASI->getValue();
|
||||||
PointerMustAliases.insert(ASIV);
|
PointerMustAliases.insert(ASIV);
|
||||||
|
@ -796,8 +800,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||||
// instruction will be executed, update the alignment.
|
// instruction will be executed, update the alignment.
|
||||||
// Larger is better, with the exception of 0 being the best alignment.
|
// Larger is better, with the exception of 0 being the best alignment.
|
||||||
unsigned InstAlignment = store->getAlignment();
|
unsigned InstAlignment = store->getAlignment();
|
||||||
if ((InstAlignment > Alignment || InstAlignment == 0)
|
if ((InstAlignment > Alignment || InstAlignment == 0) && Alignment != 0)
|
||||||
&& (Alignment != 0))
|
|
||||||
if (isGuaranteedToExecute(*Use)) {
|
if (isGuaranteedToExecute(*Use)) {
|
||||||
GuaranteedToExecute = true;
|
GuaranteedToExecute = true;
|
||||||
Alignment = InstAlignment;
|
Alignment = InstAlignment;
|
||||||
|
@ -809,6 +812,14 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||||
} else
|
} else
|
||||||
return; // Not a load or store.
|
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);
|
LoopUses.push_back(Use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -841,7 +852,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||||
SmallVector<PHINode*, 16> NewPHIs;
|
SmallVector<PHINode*, 16> NewPHIs;
|
||||||
SSAUpdater SSA(&NewPHIs);
|
SSAUpdater SSA(&NewPHIs);
|
||||||
LoopPromoter Promoter(SomePtr, LoopUses, SSA, PointerMustAliases, ExitBlocks,
|
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
|
// 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.
|
// value from the preheader that uses in the loop will use.
|
||||||
|
@ -850,6 +861,7 @@ void LICM::PromoteAliasSet(AliasSet &AS,
|
||||||
Preheader->getTerminator());
|
Preheader->getTerminator());
|
||||||
PreheaderLoad->setAlignment(Alignment);
|
PreheaderLoad->setAlignment(Alignment);
|
||||||
PreheaderLoad->setDebugLoc(DL);
|
PreheaderLoad->setDebugLoc(DL);
|
||||||
|
if (TBAATag) PreheaderLoad->setMetadata(LLVMContext::MD_tbaa, TBAATag);
|
||||||
SSA.AddAvailableValue(Preheader, PreheaderLoad);
|
SSA.AddAvailableValue(Preheader, PreheaderLoad);
|
||||||
|
|
||||||
// Rewrite all the loads in the loop and remember all the definitions from
|
// 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"
|
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]
|
@X = global i32 7 ; <i32*> [#uses=4]
|
||||||
|
@ -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