Index: lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -103,24 +103,37 @@ Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB, P); - // Look if the incoming value is a select with a constant but LVI tells us + // Look if the incoming value is a select for which LVI can tells us the + // condition value, or if its a select with a constant but LVI tells us // that the incoming value can never be that constant. In that case replace - // the incoming value with the other value of the select. This often allows - // us to remove the select later. + // the incoming value with the appropriate value of the select. This often + // allows us to remove the select later. if (!V) { SelectInst *SI = dyn_cast(Incoming); if (!SI) continue; - Constant *C = dyn_cast(SI->getFalseValue()); - if (!C) continue; - - if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, - P->getIncomingBlock(i), BB, P) != - LazyValueInfo::False) - continue; + Value *Condition = SI->getCondition(); + switch (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, Condition, + ConstantInt::getTrue(Condition->getType()), + P->getIncomingBlock(i), BB, P)) { + case LazyValueInfo::False: + V = SI->getFalseValue(); + break; + case LazyValueInfo::True: + V = SI->getTrueValue(); + break; + case LazyValueInfo::Unknown: + Constant *C = dyn_cast(SI->getFalseValue()); + if (!C) continue; + + if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, + P->getIncomingBlock(i), BB, P) != + LazyValueInfo::False) + continue; + V = SI->getTrueValue(); + } DEBUG(dbgs() << "CVP: Threading PHI over " << *SI << '\n'); - V = SI->getTrueValue(); } P->setIncomingValue(i, V); Index: test/Transforms/CorrelatedValuePropagation/select.ll =================================================================== --- /dev/null +++ test/Transforms/CorrelatedValuePropagation/select.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -correlated-propagation -S | FileCheck %s + +; CHECK-LABEL: @test( +define void @test(i32) { +entry: + br label %loop + +loop: + %idx = phi i32 [ %0, %entry ], [ %sel, %loop ] +; CHECK: %idx = phi i32 [ %0, %entry ], [ %2, %loop ] + %1 = icmp eq i32 %idx, 0 + %2 = add i32 %idx, -1 + %sel = select i1 %1, i32 0, i32 %2 + br i1 %1, label %out, label %loop + +out: + ret void +}