[llvm] 8524622 - [SLP] Simplify getOperandInfo implementation and be consistent

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 31 12:24:51 PDT 2022


Author: Philip Reames
Date: 2022-08-31T12:24:05-07:00
New Revision: 8524622bdc667d459f1f4bc980055ddc6aa886d5

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

LOG: [SLP] Simplify getOperandInfo implementation and be consistent

This is NOT nfc.  Specifically, the following behavior changes:
* Pointers are now allowed.  Both uniform, and constants.
* FP uniform non-constants can now be recognized.
* FP undefs are no longer considered constant.  This matches int behavior which we had tests for.  FP behavior was untested.  Its not clear to me int behavior is reasonable, but it's what tests seem to expect, so go with minimum impact for now.

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 50163102547f6..7e475e60a32a2 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -5814,55 +5814,36 @@ static bool isAlternateInstruction(const Instruction *I,
 
 TTI::OperandValueInfo BoUpSLP::getOperandInfo(ArrayRef<Value *> VL,
                                               unsigned OpIdx) {
-  // If all float point constants are the same, return OK_UniformConstantValue.
-  // If all float operands are 
diff erent constants then set the operand kind to
-  // OK_NonUniformConstantValue. Otherwise, return OK_AnyValue.
-  const auto *I0 = cast<Instruction>(VL.front());
-  if (I0->getOperand(OpIdx)->getType()->isFloatingPointTy()) {
-    if (any_of(VL, [OpIdx, I0](Value *V) {
-          const auto *Inst = cast<Instruction>(V);
-          assert(Inst->getOpcode() == I0->getOpcode() &&
-                 "Expected same opcode");
-          (void)I0;
-          return !isConstant(Inst->getOperand(OpIdx));
-        }))
-      return {TTI::OK_AnyValue, TTI::OP_None};
-    const auto *Op0 = I0->getOperand(OpIdx);
-    if (any_of(VL, [OpIdx, Op0](Value *V) {
-          return cast<Instruction>(V)->getOperand(OpIdx) != Op0;
-        }))
-      return {TTI::OK_NonUniformConstantValue, TTI::OP_None};
-    return {TTI::OK_UniformConstantValue, TTI::OP_None};
-  }
+  assert(!VL.empty());
+  const auto *Op0 = cast<Instruction>(VL.front())->getOperand(OpIdx);
+
+  const bool IsConstant = all_of(VL, [&](Value *V) {
+    // TODO: We should allow undef elements here
+    auto *Op = cast<Instruction>(V)->getOperand(OpIdx);
+    return isConstant(Op) && !isa<UndefValue>(Op);
+  });
+  const bool IsUniform = all_of(VL, [&](Value *V) {
+    // TODO: We should allow undef elements here
+    return cast<Instruction>(V)->getOperand(OpIdx) == Op0;
+  });
+  const bool IsPowerOfTwo = all_of(VL, [&](Value *V) {
+    // TODO: We should allow undef elements here
+    auto *Op = cast<Instruction>(V)->getOperand(OpIdx);
+    if (auto *CI = dyn_cast<ConstantInt>(Op))
+      return CI->getValue().isPowerOf2();
+    return false;
+  });
 
-  TTI::OperandValueKind VK = TTI::OK_UniformConstantValue;
-  TTI::OperandValueProperties VP = TTI::OP_PowerOf2;
+  TTI::OperandValueKind VK = TTI::OK_AnyValue;
+  if (IsConstant && IsUniform)
+    VK = TTI::OK_UniformConstantValue;
+  else if (IsConstant)
+    VK = TTI::OK_NonUniformConstantValue;
+  else if (IsUniform)
+    VK = TTI::OK_UniformValue;
 
-  // If all operands are exactly the same ConstantInt then set the
-  // operand kind to OK_UniformConstantValue.
-  // If instead not all operands are constants, then set the operand kind
-  // to OK_AnyValue. If all operands are constants but not the same,
-  // then set the operand kind to OK_NonUniformConstantValue.
-  ConstantInt *CInt0 = nullptr;
-  for (Value *V : VL) {
-    const auto *Inst = cast<Instruction>(V);
-    assert(Inst->getOpcode() == cast<Instruction>(VL[0])->getOpcode() &&
-           "Expected same opcode");
-    auto *CInt = dyn_cast<ConstantInt>(Inst->getOperand(OpIdx));
-    if (!CInt) {
-      VK = TTI::OK_AnyValue;
-      VP = TTI::OP_None;
-      break;
-    }
-    if (VP == TTI::OP_PowerOf2 && !CInt->getValue().isPowerOf2())
-      VP = TTI::OP_None;
-    if (!CInt0) {
-      CInt0 = CInt;
-      continue;
-    }
-    if (CInt0 != CInt)
-      VK = TTI::OK_NonUniformConstantValue;
-  }
+  const TTI::OperandValueProperties VP =
+    IsPowerOfTwo ? TTI::OP_PowerOf2 : TTI::OP_None;
   return {VK, VP};
 }
 


        


More information about the llvm-commits mailing list