[llvm] f0f8dab - [SLP]Check if the first reduced value requires freeze/swap, if it may be too poisonous

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 24 07:43:52 PST 2024


Author: Alexey Bataev
Date: 2024-12-24T07:40:35-08:00
New Revision: f0f8dab712967b8fca5fcca4d7338b1d25017634

URL: https://github.com/llvm/llvm-project/commit/f0f8dab712967b8fca5fcca4d7338b1d25017634
DIFF: https://github.com/llvm/llvm-project/commit/f0f8dab712967b8fca5fcca4d7338b1d25017634.diff

LOG: [SLP]Check if the first reduced value requires freeze/swap, if it may be too poisonous

If several reduced values are combined and the first reduced value is
just the original reduced value of the bool logical op, need to freeze
it to prevent the propagation of the poison value.

Fixes #114905

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
    llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index b5d68c075b9861..2785d7fb36ffdd 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -19679,20 +19679,35 @@ class HorizontalReduction {
       return cast<Instruction>(ScalarCond);
     };
 
+    bool AnyBoolLogicOp = any_of(ReductionOps.back(), [](Value *V) {
+      return isBoolLogicOp(cast<Instruction>(V));
+    });
     // Return new VectorizedTree, based on previous value.
     auto GetNewVectorizedTree = [&](Value *VectorizedTree, Value *Res) {
       if (VectorizedTree) {
         // Update the final value in the reduction.
         Builder.SetCurrentDebugLocation(
             cast<Instruction>(ReductionOps.front().front())->getDebugLoc());
-        if ((isa<PoisonValue>(VectorizedTree) && !isa<PoisonValue>(Res)) ||
-            (isGuaranteedNotToBePoison(Res) &&
-             !isGuaranteedNotToBePoison(VectorizedTree))) {
-          auto It = ReducedValsToOps.find(Res);
-          if (It != ReducedValsToOps.end() &&
-              any_of(It->getSecond(),
-                     [](Instruction *I) { return isBoolLogicOp(I); }))
+        if (AnyBoolLogicOp) {
+
+          if (auto It = ReducedValsToOps.find(VectorizedTree);
+              It == ReducedValsToOps.end() ||
+              isGuaranteedNotToBePoison(VectorizedTree) ||
+              any_of(It->getSecond(), [&](Instruction *I) {
+                return isBoolLogicOp(I) &&
+                       getRdxOperand(I, 0) == VectorizedTree;
+              })) {
+            ;
+          } else if (auto It = ReducedValsToOps.find(Res);
+                     It == ReducedValsToOps.end() ||
+                     isGuaranteedNotToBePoison(Res) ||
+                     any_of(It->getSecond(), [&](Instruction *I) {
+                       return isBoolLogicOp(I) && getRdxOperand(I, 0) == Res;
+                     })) {
             std::swap(VectorizedTree, Res);
+          } else {
+            VectorizedTree = Builder.CreateFreeze(VectorizedTree);
+          }
         }
 
         return createOp(Builder, RdxKind, VectorizedTree, Res, "op.rdx",
@@ -19701,9 +19716,6 @@ class HorizontalReduction {
       // Initialize the final value in the reduction.
       return Res;
     };
-    bool AnyBoolLogicOp = any_of(ReductionOps.back(), [](Value *V) {
-      return isBoolLogicOp(cast<Instruction>(V));
-    });
     SmallDenseSet<Value *> IgnoreList(ReductionOps.size() *
                                       ReductionOps.front().size());
     for (ReductionOpsType &RdxOps : ReductionOps)

diff  --git a/llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll b/llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll
index 6ef6490d9f8308..101f66f3313045 100644
--- a/llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll
+++ b/llvm/test/Transforms/SLPVectorizer/logical-ops-poisonous-repeated.ll
@@ -12,7 +12,8 @@ define i1 @test(<4 x i32> %x) {
 ; CHECK-NEXT:    [[C1:%.*]] = icmp slt i32 [[X1]], 0
 ; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i32 [[X2]], 0
 ; CHECK-NEXT:    [[C3:%.*]] = icmp slt i32 [[X3]], 0
-; CHECK-NEXT:    [[OP_RDX:%.*]] = select i1 [[C3]], i1 [[C1]], i1 false
+; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[C3]]
+; CHECK-NEXT:    [[OP_RDX:%.*]] = select i1 [[TMP2]], i1 [[C1]], i1 false
 ; CHECK-NEXT:    [[OP_RDX1:%.*]] = select i1 [[OP_RDX]], i1 [[TMP1]], i1 false
 ; CHECK-NEXT:    ret i1 [[OP_RDX1]]
 ;


        


More information about the llvm-commits mailing list