Commit 24ae5ce5 authored by Alina Sbirlea's avatar Alina Sbirlea
Browse files

[MemorySSA] Update Phi creation when inserting a Def.

MemoryPhis should be added in the IDF of the blocks newly gaining Defs.
This includes the blocks that gained a Phi and the block gaining a Def,
if the block did not have one before.
Resolves PR43427.

llvm-svn: 373505
parent 340406a7
Loading
Loading
Loading
Loading
+40 −37
Original line number Diff line number Diff line
@@ -347,12 +347,16 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {

    // If this is the first def in the block and this insert is in an arbitrary
    // place, compute IDF and place phis.
    SmallPtrSet<BasicBlock *, 2> DefiningBlocks;

    // If this is the last Def in the block, also compute IDF based on MD, since
    // this may a new Def added, and we may need additional Phis.
    auto Iter = MD->getDefsIterator();
    ++Iter;
    auto IterEnd = MSSA->getBlockDefs(MD->getBlock())->end();
    if (Iter == IterEnd) {
      SmallPtrSet<BasicBlock *, 2> DefiningBlocks;
    if (Iter == IterEnd)
      DefiningBlocks.insert(MD->getBlock());

    for (const auto &VH : InsertedPHIs)
      if (const auto *RealPHI = cast_or_null<MemoryPhi>(VH))
        DefiningBlocks.insert(RealPHI->getBlock());
@@ -367,31 +371,30 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
        MPhi = MSSA->createMemoryPhi(BBIDF);
        NewInsertedPHIs.push_back(MPhi);
      }
        // Add the phis created into the IDF blocks to NonOptPhis, so they are
        // not optimized out as trivial by the call to getPreviousDefFromEnd
        // below. Once they are complete, all these Phis are added to the
        // FixupList, and removed from NonOptPhis inside fixupDefs(). Existing
        // Phis in IDF may need fixing as well, and potentially be trivial
        // before this insertion, hence add all IDF Phis. See PR43044.
      // Add the phis created into the IDF blocks to NonOptPhis, so they are not
      // optimized out as trivial by the call to getPreviousDefFromEnd below.
      // Once they are complete, all these Phis are added to the FixupList, and
      // removed from NonOptPhis inside fixupDefs(). Existing Phis in IDF may
      // need fixing as well, and potentially be trivial before this insertion,
      // hence add all IDF Phis. See PR43044.
      NonOptPhis.insert(MPhi);
    }
    for (auto &MPhi : NewInsertedPHIs) {
      auto *BBIDF = MPhi->getBlock();
      for (auto *Pred : predecessors(BBIDF)) {
        DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> CachedPreviousDef;
          MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef),
                            Pred);
        MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred);
      }
    }

      // Re-take the index where we're adding the new phis, because the above
      // call to getPreviousDefFromEnd, may have inserted into InsertedPHIs.
    // Re-take the index where we're adding the new phis, because the above call
    // to getPreviousDefFromEnd, may have inserted into InsertedPHIs.
    NewPhiIndex = InsertedPHIs.size();
    for (auto &MPhi : NewInsertedPHIs) {
      InsertedPHIs.push_back(&*MPhi);
      FixupList.push_back(&*MPhi);
    }
    }

    FixupList.push_back(MD);
  }

+42 −0
Original line number Diff line number Diff line
; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s

; CHECK-LABEL: @f()
; CHECK: 8 = MemoryPhi(
; CHECK: 7 = MemoryPhi(
; CHECK: 9 = MemoryPhi(
define void @f() {
entry:
  %e = alloca i16, align 1
  br label %lbl1

lbl1:                                             ; preds = %if.else, %cleanup, %entry
  store i16 undef, i16* %e, align 1
  call void @g()
  br i1 undef, label %for.end, label %if.else

for.end:                                          ; preds = %lbl1
  br i1 undef, label %lbl3, label %lbl2

lbl2:                                             ; preds = %lbl3, %for.end
  br label %lbl3

lbl3:                                             ; preds = %lbl2, %for.end
  br i1 undef, label %lbl2, label %cleanup

cleanup:                                          ; preds = %lbl3
  %cleanup.dest = load i32, i32* undef, align 1
  %switch = icmp ult i32 %cleanup.dest, 1
  br i1 %switch, label %cleanup.cont, label %lbl1

cleanup.cont:                                     ; preds = %cleanup
  call void @llvm.lifetime.end.p0i8(i64 1, i8* null)
  ret void

if.else:                                          ; preds = %lbl1
  br label %lbl1
}

declare void @g()

; Function Attrs: argmemonly nounwind willreturn
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)