mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-25 00:29:20 +00:00
Fix a case where SROA did not correctly detect dead PHI or selects due
to chains or cycles between PHIs and/or selects. Also add a couple of really nice test cases reduced from Kostya's reports in PR13905 and PR13906. Both are fixed by this patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164596 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
00edf4c1d8
commit
c303463dcc
@ -522,8 +522,10 @@ private:
|
|||||||
|
|
||||||
void insertUse(Instruction &I, int64_t Offset, uint64_t Size,
|
void insertUse(Instruction &I, int64_t Offset, uint64_t Size,
|
||||||
bool IsSplittable = false) {
|
bool IsSplittable = false) {
|
||||||
// Completely skip uses which don't overlap the allocation.
|
// Completely skip uses which have a zero size or don't overlap the
|
||||||
if ((Offset >= 0 && (uint64_t)Offset >= AllocSize) ||
|
// allocation.
|
||||||
|
if (Size == 0 ||
|
||||||
|
(Offset >= 0 && (uint64_t)Offset >= AllocSize) ||
|
||||||
(Offset < 0 && (uint64_t)-Offset >= Size)) {
|
(Offset < 0 && (uint64_t)-Offset >= Size)) {
|
||||||
DEBUG(dbgs() << "WARNING: Ignoring " << Size << " byte use @" << Offset
|
DEBUG(dbgs() << "WARNING: Ignoring " << Size << " byte use @" << Offset
|
||||||
<< " which starts past the end of the " << AllocSize
|
<< " which starts past the end of the " << AllocSize
|
||||||
@ -697,6 +699,9 @@ private:
|
|||||||
SmallVector<std::pair<Instruction *, Instruction *>, 4> Uses;
|
SmallVector<std::pair<Instruction *, Instruction *>, 4> Uses;
|
||||||
Visited.insert(Root);
|
Visited.insert(Root);
|
||||||
Uses.push_back(std::make_pair(cast<Instruction>(*U), Root));
|
Uses.push_back(std::make_pair(cast<Instruction>(*U), Root));
|
||||||
|
// If there are no loads or stores, the access is dead. We mark that as
|
||||||
|
// a size zero access.
|
||||||
|
Size = 0;
|
||||||
do {
|
do {
|
||||||
Instruction *I, *UsedI;
|
Instruction *I, *UsedI;
|
||||||
llvm::tie(UsedI, I) = Uses.pop_back_val();
|
llvm::tie(UsedI, I) = Uses.pop_back_val();
|
||||||
@ -824,9 +829,9 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void insertUse(Instruction &User, int64_t Offset, uint64_t Size) {
|
void insertUse(Instruction &User, int64_t Offset, uint64_t Size) {
|
||||||
// If the use extends outside of the allocation, record it as a dead use
|
// If the use has a zero size or extends outside of the allocation, record
|
||||||
// for elimination later.
|
// it as a dead use for elimination later.
|
||||||
if ((uint64_t)Offset >= AllocSize ||
|
if (Size == 0 || (uint64_t)Offset >= AllocSize ||
|
||||||
(Offset < 0 && (uint64_t)-Offset >= Size))
|
(Offset < 0 && (uint64_t)-Offset >= Size))
|
||||||
return markAsDead(User);
|
return markAsDead(User);
|
||||||
|
|
||||||
|
@ -327,3 +327,48 @@ exit:
|
|||||||
%load = load i32* %a
|
%load = load i32* %a
|
||||||
ret i32 %load
|
ret i32 %load
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i32 @PR13905() {
|
||||||
|
; Check a pattern where we have a chain of dead phi nodes to ensure they are
|
||||||
|
; deleted and promotion can proceed.
|
||||||
|
; CHECK: @PR13905
|
||||||
|
; CHECK-NOT: alloca i32
|
||||||
|
; CHECK: ret i32 undef
|
||||||
|
|
||||||
|
entry:
|
||||||
|
%h = alloca i32
|
||||||
|
store i32 0, i32* %h
|
||||||
|
br i1 undef, label %loop1, label %exit
|
||||||
|
|
||||||
|
loop1:
|
||||||
|
%phi1 = phi i32* [ null, %entry ], [ %h, %loop1 ], [ %h, %loop2 ]
|
||||||
|
br i1 undef, label %loop1, label %loop2
|
||||||
|
|
||||||
|
loop2:
|
||||||
|
br i1 undef, label %loop1, label %exit
|
||||||
|
|
||||||
|
exit:
|
||||||
|
%phi2 = phi i32* [ %phi1, %loop2 ], [ null, %entry ]
|
||||||
|
ret i32 undef
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @PR13906() {
|
||||||
|
; Another pattern which can lead to crashes due to failing to clear out dead
|
||||||
|
; PHI nodes or select nodes. This triggers subtly differently from the above
|
||||||
|
; cases because the PHI node is (recursively) alive, but the select is dead.
|
||||||
|
; CHECK: @PR13906
|
||||||
|
; CHECK-NOT: alloca
|
||||||
|
|
||||||
|
entry:
|
||||||
|
%c = alloca i32
|
||||||
|
store i32 0, i32* %c
|
||||||
|
br label %for.cond
|
||||||
|
|
||||||
|
for.cond:
|
||||||
|
%d.0 = phi i32* [ undef, %entry ], [ %c, %if.then ], [ %d.0, %for.cond ]
|
||||||
|
br i1 undef, label %if.then, label %for.cond
|
||||||
|
|
||||||
|
if.then:
|
||||||
|
%tmpcast.d.0 = select i1 undef, i32* %c, i32* %d.0
|
||||||
|
br label %for.cond
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user