From 90a3b310917031c802bb930626e85f067d53ea5b Mon Sep 17 00:00:00 2001 From: Dmitry Vassiliev Date: Wed, 23 Feb 2022 00:11:20 +0400 Subject: [PATCH] [Transforms] Enhance CorrelatedValuePropagation to handle both values of select The "Correlated Value Propagation" pass was missing a case when handling select instructions. It was only handling the "false" constant value, while in NVPTX the select may have the condition (and thus the branches) inverted, for example: ``` loop: %phi = phi i32* [ %sel, %loop ], [ %x, %entry ] %f = tail call i32* @f(i32* %phi) %cmp1 = icmp ne i32* %f, %y %sel = select i1 %cmp1, i32* %f, i32* null %cmp2 = icmp eq i32* %sel, null br i1 %cmp2, label %return, label %loop ``` But the select condition can be inverted: ``` %cmp1 = icmp eq i32* %f, %y %sel = select i1 %cmp1, i32* null, i32* %f ``` The fix is to enhance "Correlated Value Propagation" to handle both branches of the select instruction. Reviewed By: nikic, lebedev.ri Differential Revision: https://reviews.llvm.org/D119643 --- llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 9 +++++++++ llvm/test/Transforms/CorrelatedValuePropagation/basic.ll | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index cc90be9..dc28a1c 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -245,11 +245,20 @@ static Value *getValueOnEdge(LazyValueInfo *LVI, Value *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 "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 index 024ff29..55ae559 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll @@ -179,9 +179,8 @@ define void @loop2(i32* %x, i32* %y) { ; 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 -- 2.7.4