Skip to content
Snippets Groups Projects
Commit 2d54ce84 authored by Dan Gohman's avatar Dan Gohman
Browse files

Fix SSAUpdaterImpl's RecordMatchingPHI to record exactly the

PHI nodes which were matched, rather than climbing up the
original PHI node's operands to rediscover PHI nodes for
recording, since the PHI nodes found that are not
necessarily part of the matched set.
This fixes rdar://10589171.

llvm-svn: 149654
parent c934de67
No related branches found
No related tags found
No related merge requests found
...@@ -380,7 +380,7 @@ public: ...@@ -380,7 +380,7 @@ public:
if (!SomePHI) if (!SomePHI)
break; break;
if (CheckIfPHIMatches(SomePHI)) { if (CheckIfPHIMatches(SomePHI)) {
RecordMatchingPHI(SomePHI); RecordMatchingPHIs(BlockList);
break; break;
} }
// Match failed: clear all the PHITag values. // Match failed: clear all the PHITag values.
...@@ -437,38 +437,17 @@ public: ...@@ -437,38 +437,17 @@ public:
return true; return true;
} }
/// RecordMatchingPHI - For a PHI node that matches, record it and its input /// RecordMatchingPHIs - For each PHI node that matches, record it in both
/// PHIs in both the BBMap and the AvailableVals mapping. /// the BBMap and the AvailableVals mapping.
void RecordMatchingPHI(PhiT *PHI) { void RecordMatchingPHIs(BlockListTy *BlockList) {
SmallVector<PhiT*, 20> WorkList; for (typename BlockListTy::iterator I = BlockList->begin(),
WorkList.push_back(PHI); E = BlockList->end(); I != E; ++I)
if (PhiT *PHI = (*I)->PHITag) {
// Record this PHI. BlkT *BB = PHI->getParent();
BlkT *BB = PHI->getParent(); ValT PHIVal = Traits::GetPHIValue(PHI);
ValT PHIVal = Traits::GetPHIValue(PHI); (*AvailableVals)[BB] = PHIVal;
(*AvailableVals)[BB] = PHIVal; BBMap[BB]->AvailableVal = PHIVal;
BBMap[BB]->AvailableVal = PHIVal;
while (!WorkList.empty()) {
PHI = WorkList.pop_back_val();
// Iterate through the PHI's incoming values.
for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
E = Traits::PHI_end(PHI); I != E; ++I) {
ValT IncomingVal = I.getIncomingValue();
PhiT *IncomingPHI = Traits::ValueIsPHI(IncomingVal, Updater);
if (!IncomingPHI) continue;
BB = IncomingPHI->getParent();
BBInfo *Info = BBMap[BB];
if (!Info || Info->AvailableVal)
continue;
// Record the PHI and add it to the worklist.
(*AvailableVals)[BB] = IncomingVal;
Info->AvailableVal = IncomingVal;
WorkList.push_back(IncomingPHI);
} }
}
} }
}; };
......
; RUN: opt -S -scalarrepl-ssa < %s | FileCheck %s
; rdar://10589171
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%struct.foo = type { i32, i32 }
@.str = private unnamed_addr constant [6 x i8] c"x=%d\0A\00", align 1
define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
entry:
%f = alloca %struct.foo, align 4
%x.i = getelementptr inbounds %struct.foo* %f, i64 0, i32 0
store i32 1, i32* %x.i, align 4
%y.i = getelementptr inbounds %struct.foo* %f, i64 0, i32 1
br label %while.cond.i
; CHECK: while.cond.i:
; CHECK-NEXT: %tmp = phi i32 [ 1, %entry ], [ %tmp2, %while.cond.backedge.i ]
; CHECK-NEXT: %pos.0.i = phi i32 [ 1, %entry ], [ %xtmp.i, %while.cond.backedge.i ]
; CHECK-NEXT: %left.0.i = phi i32 [ 1, %entry ], [ %dec.i, %while.cond.backedge.i ]
; CHECK-NOT: phi
while.cond.i: ; preds = %while.cond.backedge.i, %entry
%tmp = phi i32 [ 1, %entry ], [ %tmp2, %while.cond.backedge.i ]
%pos.0.i = phi i32 [ 1, %entry ], [ %xtmp.i, %while.cond.backedge.i ]
%left.0.i = phi i32 [ 1, %entry ], [ %dec.i, %while.cond.backedge.i ]
%cmp.i = icmp sgt i32 %left.0.i, 0
br i1 %cmp.i, label %while.body.i, label %while.cond.i.func.exit_crit_edge
while.cond.i.func.exit_crit_edge: ; preds = %while.cond.i
br label %func.exit
while.body.i: ; preds = %while.cond.i
%dec.i = add nsw i32 %left.0.i, -1
switch i32 1, label %while.body.i.func.exit_crit_edge [
i32 0, label %while.cond.backedge.i
i32 1, label %sw.bb.i
]
while.body.i.func.exit_crit_edge: ; preds = %while.body.i
br label %func.exit
sw.bb.i: ; preds = %while.body.i
%cmp2.i = icmp eq i32 %tmp, 1
br i1 %cmp2.i, label %if.then.i, label %if.end.i
if.then.i: ; preds = %sw.bb.i
store i32 %pos.0.i, i32* %x.i, align 4
br label %if.end.i
; CHECK: if.end.i:
; CHECK-NEXT: %tmp1 = phi i32 [ %pos.0.i, %if.then.i ], [ %tmp, %sw.bb.i ]
; CHECK-NOT: phi
if.end.i: ; preds = %if.then.i, %sw.bb.i
%tmp1 = phi i32 [ %pos.0.i, %if.then.i ], [ %tmp, %sw.bb.i ]
store i32 %tmp1, i32* %y.i, align 4
br label %while.cond.backedge.i
; CHECK: while.cond.backedge.i:
; CHECK-NEXT: %tmp2 = phi i32 [ %tmp1, %if.end.i ], [ %tmp, %while.body.i ]
; CHECK-NOT: phi
while.cond.backedge.i: ; preds = %if.end.i, %while.body.i
%tmp2 = phi i32 [ %tmp1, %if.end.i ], [ %tmp, %while.body.i ]
%xtmp.i = add i32 %pos.0.i, 1
br label %while.cond.i
; CHECK: func.exit:
; CHECK-NOT: load
; CHECK: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp) nounwind
func.exit: ; preds = %while.body.i.func.exit_crit_edge, %while.cond.i.func.exit_crit_edge
%tmp3 = load i32* %x.i, align 4
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i64 0, i64 0), i32 %tmp3) nounwind
ret i32 0
}
declare i32 @printf(i8* nocapture, ...) nounwind
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment