[MemorySSA] Consider def-only BBs for live-in calculations.

If we have a BB with only MemoryDefs, live-in calculations will ignore
it. This means we get results like this:

define void @foo(i8* %p) {
  ; 1 = MemoryDef(liveOnEntry)
  store i8 0, i8* %p
  br i1 undef, label %if.then, label %if.end

if.then:
  ; 2 = MemoryDef(1)
  store i8 1, i8* %p
  br label %if.end

if.end:
  ; 3 = MemoryDef(1)
  store i8 2, i8* %p
  ret void
}

...When there should be a MemoryPhi in the `if.end` BB.

This patch fixes that behavior.

llvm-svn: 263991
This commit is contained in:
George Burgess IV 2016-03-21 21:25:39 +00:00
parent 67e6ae5e2a
commit 3887a41725
2 changed files with 25 additions and 6 deletions

View File

@ -253,17 +253,13 @@ MemorySSAWalker *MemorySSA::buildMemorySSA(AliasAnalysis *AA,
// Go through each block, figure out where defs occur, and chain together all
// the accesses.
for (BasicBlock &B : F) {
bool InsertIntoDefUse = false;
bool InsertIntoDef = false;
AccessListType *Accesses = nullptr;
for (Instruction &I : B) {
MemoryUseOrDef *MUD = createNewAccess(&I, true);
if (!MUD)
continue;
if (isa<MemoryDef>(MUD))
InsertIntoDef = true;
else
InsertIntoDefUse = true;
InsertIntoDef |= isa<MemoryDef>(MUD);
if (!Accesses)
Accesses = getOrCreateAccessList(&B);
@ -271,7 +267,7 @@ MemorySSAWalker *MemorySSA::buildMemorySSA(AliasAnalysis *AA,
}
if (InsertIntoDef)
DefiningBlocks.insert(&B);
if (InsertIntoDefUse)
if (Accesses)
DefUseBlocks.insert(&B);
}

View File

@ -27,3 +27,26 @@ merge:
%c = load i8, i8* %0
ret void
}
; Ensure we treat def-only blocks as though they have uses for phi placement.
; CHECK-LABEL: define void @F3
define void @F3() {
%a = alloca i8
; CHECK: 1 = MemoryDef(liveOnEntry)
; CHECK-NEXT: store i8 0, i8* %a
store i8 0, i8* %a
br i1 undef, label %if.then, label %if.end
if.then:
; CHECK: 2 = MemoryDef(1)
; CHECK-NEXT: store i8 1, i8* %a
store i8 1, i8* %a
br label %if.end
if.end:
; CHECK: 4 = MemoryPhi({%0,1},{if.then,2})
; CHECK: 3 = MemoryDef(4)
; CHECK-NEXT: store i8 2, i8* %a
store i8 2, i8* %a
ret void
}