Index: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -103,24 +103,43 @@ 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 - // 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. + // Look if the incoming value is a select with a scalar condition for which + // LVI can tells us the value. In that case replace 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; + Value *Condition = SI->getCondition(); + if (!Condition->getType()->isVectorTy()) { + if (Constant *C = LVI->getConstantOnEdge(Condition, P->getIncomingBlock(i), BB, P)) { + if (C == ConstantInt::getTrue(Condition->getType())) { + V = SI->getTrueValue(); + } else { + V = SI->getFalseValue(); + } + // Once LVI learns to handle vector types, we could also add support + // for vector type constants that are not all zeroes or all ones. + } + } - if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, - P->getIncomingBlock(i), BB, P) != - LazyValueInfo::False) - continue; + // Look if the select has 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. + if (!V) { + 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: llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll =================================================================== --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/select.ll @@ -0,0 +1,53 @@ +; RUN: opt < %s -correlated-propagation -S | FileCheck %s + +; CHECK-LABEL: @simple( +define i8 @simple(i1) { +entry: + %s = select i1 %0, i8 0, i8 1 + br i1 %0, label %then, label %else + +then: +; CHECK: ret i8 0 + %a = phi i8 [ %s, %entry ] + ret i8 %a + +else: +; CHECK: ret i8 1 + %b = phi i8 [ %s, %entry ] + ret i8 %b +} + +; CHECK-LABEL: @loop( +define void @loop(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 +} + +; CHECK-LABEL: @not_correlated( +define i8 @not_correlated(i1, i1) { +entry: + %s = select i1 %0, i8 0, i8 1 + br i1 %1, label %then, label %else + +then: +; CHECK: ret i8 %s + %a = phi i8 [ %s, %entry ] + ret i8 %a + +else: +; CHECK: ret i8 %s + %b = phi i8 [ %s, %entry ] + ret i8 %b +} +