From fc3b7bbf49086e827a628e22db0b75e46c151d17 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Fri, 4 Oct 2013 23:41:05 +0000 Subject: [PATCH] UpdatePHINodes in BasicBlockUtils should not crash on duplicate predecessors UpdatePHINodes has an optimization to reuse an existing PHI node, where it first deletes all of its entries and then replaces them. Unfortunately, in the case where we had duplicate predecessors (which are allowed so long as the associated PHI entries have the same value), the loop removing the existing PHI entries from the to-be-reused PHI would assert (if that PHI was not the one which had the duplicates). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192001 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/BasicBlockUtils.cpp | 8 +++- test/Transforms/LoopSimplify/dup-preds.ll | 46 +++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 test/Transforms/LoopSimplify/dup-preds.ll diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index a2e82f337b9..12de9eed4b8 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -400,8 +400,12 @@ static void UpdatePHINodes(BasicBlock *OrigBB, BasicBlock *NewBB, // If all incoming values for the new PHI would be the same, just don't // make a new PHI. Instead, just remove the incoming values from the old // PHI. - for (unsigned i = 0, e = Preds.size(); i != e; ++i) - PN->removeIncomingValue(Preds[i], false); + for (unsigned i = 0, e = Preds.size(); i != e; ++i) { + // Explicitly check the BB index here to handle duplicates in Preds. + int Idx = PN->getBasicBlockIndex(Preds[i]); + if (Idx >= 0) + PN->removeIncomingValue(Idx, false); + } } else { // If the values coming into the block are not the same, we need a PHI. // Create the new PHI node, insert it into NewBB at the end of the block diff --git a/test/Transforms/LoopSimplify/dup-preds.ll b/test/Transforms/LoopSimplify/dup-preds.ll new file mode 100644 index 00000000000..3d1f1499b11 --- /dev/null +++ b/test/Transforms/LoopSimplify/dup-preds.ll @@ -0,0 +1,46 @@ +; RUN: opt -loop-simplify -S %s | FileCheck %s +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-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-bgq-linux" + +define fastcc void @do_update_md([3 x float]* nocapture readonly %x) #0 { +entry: + br i1 undef, label %if.end365, label %lor.lhs.false134 + +lor.lhs.false134: ; preds = %entry + br i1 undef, label %lor.lhs.false138, label %if.end365 + +lor.lhs.false138: ; preds = %lor.lhs.false134 + br i1 undef, label %lor.lhs.false142, label %if.end365 + +lor.lhs.false142: ; preds = %lor.lhs.false138 + br i1 undef, label %for.body276.lr.ph, label %if.end365 + +for.body276.lr.ph: ; preds = %lor.lhs.false142 + switch i16 undef, label %if.then288 [ + i16 4, label %for.body344 + i16 2, label %for.body344 + ] + +if.then288: ; preds = %for.body276.lr.ph + br label %for.body305 + +for.body305: ; preds = %for.body305, %if.then288 + br label %for.body305 + +for.body344: ; preds = %for.body344, %for.body276.lr.ph, %for.body276.lr.ph + %indvar = phi i64 [ %indvar.next, %for.body344 ], [ 0, %for.body276.lr.ph ] + %indvars.iv552 = phi i64 [ %indvars.iv.next553, %for.body344 ], [ 0, %for.body276.lr.ph ], [ 0, %for.body276.lr.ph ] + %indvars.iv.next553 = add nuw nsw i64 %indvars.iv552, 1 + %indvar.next = add i64 %indvar, 1 + br label %for.body344 + +; CHECK-LABEL: @do_update_md +; CHECK: %indvars.iv552 = phi i64 [ %indvars.iv.next553, %for.body344 ], [ 0, %for.body344.preheader ] +; CHECK: ret + +if.end365: ; preds = %lor.lhs.false142, %lor.lhs.false138, %lor.lhs.false134, %entry + ret void +} + +attributes #0 = { nounwind } +