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:
Chris Lattner 2012-12-31 08:37:17 +00:00
parent eeefe1bc07
commit f5cca68c2c
2 changed files with 58 additions and 8 deletions

View File

@ -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

View File

@ -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]
@ -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}