[llvm-commits] [llvm] r84810 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/crash.ll
Chris Lattner
sabre at nondot.org
Wed Oct 21 17:17:27 PDT 2009
Author: lattner
Date: Wed Oct 21 19:17:26 2009
New Revision: 84810
URL: http://llvm.org/viewvc/llvm-project?rev=84810&view=rev
Log:
fix PR5262.
Modified:
llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
llvm/trunk/test/Transforms/InstCombine/crash.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=84810&r1=84809&r2=84810&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Oct 21 19:17:26 2009
@@ -9274,14 +9274,44 @@
return Changed ? &SI : 0;
}
-/// isDefinedInBB - Return true if the value is an instruction defined in the
-/// specified basicblock.
-static bool isDefinedInBB(const Value *V, const BasicBlock *BB) {
+
+/// CanSelectOperandBeMappingIntoPredBlock - SI is a select whose condition is a
+/// PHI node (but the two may be in different blocks). See if the true/false
+/// values (V) are live in all of the predecessor blocks of the PHI. For
+/// example, cases like this cannot be mapped:
+///
+/// X = phi [ C1, BB1], [C2, BB2]
+/// Y = add
+/// Z = select X, Y, 0
+///
+/// because Y is not live in BB1/BB2.
+///
+static bool CanSelectOperandBeMappingIntoPredBlock(const Value *V,
+ const SelectInst &SI) {
+ // If the value is a non-instruction value like a constant or argument, it
+ // can always be mapped.
const Instruction *I = dyn_cast<Instruction>(V);
- return I != 0 && I->getParent() == BB;
+ if (I == 0) return true;
+
+ // If V is a PHI node defined in the same block as the condition PHI, we can
+ // map the arguments.
+ const PHINode *CondPHI = cast<PHINode>(SI.getCondition());
+
+ if (const PHINode *VP = dyn_cast<PHINode>(I))
+ if (VP->getParent() == CondPHI->getParent())
+ return true;
+
+ // Otherwise, if the PHI and select are defined in the same block and if V is
+ // defined in a different block, then we can transform it.
+ if (SI.getParent() == CondPHI->getParent() &&
+ I->getParent() != CondPHI->getParent())
+ return true;
+
+ // Otherwise we have a 'hard' case and we can't tell without doing more
+ // detailed dominator based analysis, punt.
+ return false;
}
-
Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
Value *CondVal = SI.getCondition();
Value *TrueVal = SI.getTrueValue();
@@ -9493,16 +9523,13 @@
return FoldI;
}
- // See if we can fold the select into a phi node. The true/false values have
- // to be live in the predecessor blocks. If they are instructions in SI's
- // block, we can't map to the predecessor.
- if (isa<PHINode>(SI.getCondition()) &&
- (!isDefinedInBB(SI.getTrueValue(), SI.getParent()) ||
- isa<PHINode>(SI.getTrueValue())) &&
- (!isDefinedInBB(SI.getFalseValue(), SI.getParent()) ||
- isa<PHINode>(SI.getFalseValue())))
- if (Instruction *NV = FoldOpIntoPhi(SI))
- return NV;
+ // See if we can fold the select into a phi node if the condition is a select.
+ if (isa<PHINode>(SI.getCondition()))
+ // The true/false values have to be live in the PHI predecessor's blocks.
+ if (CanSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
+ CanSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
+ if (Instruction *NV = FoldOpIntoPhi(SI))
+ return NV;
if (BinaryOperator::isNot(CondVal)) {
SI.setOperand(0, BinaryOperator::getNotArgument(CondVal));
Modified: llvm/trunk/test/Transforms/InstCombine/crash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/crash.ll?rev=84810&r1=84809&r2=84810&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/crash.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/crash.ll Wed Oct 21 19:17:26 2009
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine | llvm-dis
+; RUN: opt < %s -instcombine -S
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
target triple = "i386-apple-darwin10.0"
@@ -99,3 +99,29 @@
%15 = tail call %t0* @bar2(i64 %14) nounwind ; <%0*> [#uses=0]
ret void
}
+
+
+
+
+; PR5262
+; Make sure the PHI node gets put in a place where all of its operands dominate
+; it.
+define i64 @test4(i1 %c, i64* %P) nounwind align 2 {
+BB0:
+ br i1 %c, label %BB1, label %BB2
+
+BB1:
+ br label %BB2
+
+BB2:
+ %v5_ = phi i1 [ true, %BB0], [false, %BB1]
+ %v6 = load i64* %P
+ br label %l8
+
+l8:
+ br label %l10
+
+l10:
+ %v11 = select i1 %v5_, i64 0, i64 %v6
+ ret i64 %v11
+}
More information about the llvm-commits
mailing list