diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -245,11 +245,20 @@ // 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 "false" case if (auto *C = dyn_cast(SI->getFalseValue())) if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, From, To, CxtI) == LazyValueInfo::False) return SI->getTrueValue(); + // The "true" case, + // similar to the select "false" case, but try the select "true" value + if (auto *C = dyn_cast(SI->getTrueValue())) + if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C, From, To, CxtI) == + LazyValueInfo::False) + return SI->getFalseValue(); + return nullptr; } diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -179,9 +179,8 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -;; CorrelatedValuePropagation should handle inverted select condition, but it does not yet. -;; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ] -; CHECK-NEXT: [[F:%.*]] = tail call i32* @f(i32* [[PHI]]) +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[F:%.*]], [[LOOP]] ], [ [[X:%.*]], [[ENTRY:%.*]] ] +; CHECK-NEXT: [[F]] = tail call i32* @f(i32* [[PHI]]) ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* [[F]], [[Y:%.*]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], i32* null, i32* [[F]] ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32* [[SEL]], null