[GVNHoist] Properly merge alignments when hoisting

If we two loads of two different alignments, we must use the minimum of
the two alignments when hoisting.  Same deal for stores.

For allocas, use the maximum of the two allocas.

llvm-svn: 276601
This commit is contained in:
David Majnemer 2016-07-25 02:21:23 +00:00
parent 6f014d37d5
commit 4728569d0a
2 changed files with 35 additions and 4 deletions

View File

@ -628,7 +628,6 @@ public:
cast<Instruction>(cast<StoreInst>(OtherInst)->getValueOperand());
ClonedVal->intersectOptionalDataWith(OtherVal);
}
ClonedVal->clearSubclassOptionalData();
Repl->replaceUsesOfWith(Val, ClonedVal);
}
@ -685,12 +684,23 @@ public:
for (Instruction *I : InstructionsToHoist)
if (I != Repl) {
++NR;
if (isa<LoadInst>(Repl))
if (auto *ReplacementLoad = dyn_cast<LoadInst>(Repl)) {
ReplacementLoad->setAlignment(
std::min(ReplacementLoad->getAlignment(),
cast<LoadInst>(I)->getAlignment()));
++NumLoadsRemoved;
else if (isa<StoreInst>(Repl))
} else if (auto *ReplacementStore = dyn_cast<StoreInst>(Repl)) {
ReplacementStore->setAlignment(
std::min(ReplacementStore->getAlignment(),
cast<StoreInst>(I)->getAlignment()));
++NumStoresRemoved;
else if (isa<CallInst>(Repl))
} else if (auto *ReplacementAlloca = dyn_cast<AllocaInst>(Repl)) {
ReplacementAlloca->setAlignment(
std::max(ReplacementAlloca->getAlignment(),
cast<AllocaInst>(I)->getAlignment()));
} else if (isa<CallInst>(Repl)) {
++NumCallsRemoved;
}
Repl->intersectOptionalDataWith(I);
I->replaceAllUsesWith(Repl);
I->eraseFromParent();

View File

@ -689,3 +689,24 @@ if.else: ; preds = %entry
if.end: ; preds = %if.else, %if.then
ret void
}
define i32 @mergeAlignments(i1 %b, i32* %y) {
entry:
br i1 %b, label %if.then, label %if.end
if.then: ; preds = %entry
%l1 = load i32, i32* %y, align 4
br label %return
if.end: ; preds = %entry
%l2 = load i32, i32* %y, align 1
br label %return
return: ; preds = %if.end, %if.then
%retval.0 = phi i32 [ %l1, %if.then ], [ %l2, %if.end ]
ret i32 %retval.0
}
; CHECK-LABEL: define i32 @mergeAlignments(
; CHECK: %[[load:.*]] = load i32, i32* %y, align 1
; CHECK: %[[phi:.*]] = phi i32 [ %[[load]], %{{.*}} ], [ %[[load]], %{{.*}} ]
; CHECK: i32 %[[phi]]