aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/LiveVariables.cpp19
-rw-r--r--test/CodeGen/PowerPC/2008-06-23-LiveVariablesCrash.ll25
2 files changed, 42 insertions, 2 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 4a4ef37b00..bc73b6841c 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -139,8 +139,23 @@ void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
assert(VRInfo.Kills[i]->getParent() != MBB && "entry should be at end!");
#endif
- assert(MBB != MRI->getVRegDef(reg)->getParent() &&
- "Should have kill for defblock!");
+ // This situation can occur:
+ //
+ // ,------.
+ // | |
+ // | v
+ // | t2 = phi ... t1 ...
+ // | |
+ // | v
+ // | t1 = ...
+ // | ... = ... t1 ...
+ // | |
+ // `------'
+ //
+ // where there is a use in a PHI node that's a predecessor to the defining
+ // block. We don't want to mark all predecessors as having the value "alive"
+ // in this case.
+ if (MBB == MRI->getVRegDef(reg)->getParent()) return;
// Add a new kill entry for this basic block. If this virtual register is
// already marked as alive in this basic block, that means it is alive in at
diff --git a/test/CodeGen/PowerPC/2008-06-23-LiveVariablesCrash.ll b/test/CodeGen/PowerPC/2008-06-23-LiveVariablesCrash.ll
new file mode 100644
index 0000000000..d3238d23c0
--- /dev/null
+++ b/test/CodeGen/PowerPC/2008-06-23-LiveVariablesCrash.ll
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llc -march=ppc32
+; <rdar://problem/6020042>
+
+define i32 @bork() nounwind {
+entry:
+ br i1 true, label %bb1, label %bb3
+
+bb1:
+ %tmp1 = load i8* null, align 1
+ %tmp2 = icmp eq i8 %tmp1, 0
+ br label %bb2
+
+bb2:
+ %val1 = phi i32 [ 0, %bb1 ], [ %val2, %bb2 ]
+ %val2 = select i1 %tmp2, i32 -1, i32 %val1
+ switch i32 %val2, label %bb2 [
+ i32 -1, label %bb3
+ i32 0, label %bb1
+ i32 1, label %bb3
+ i32 2, label %bb1
+ ]
+
+bb3:
+ ret i32 -1
+}