[llvm] 6adebe3 - [VPlan] Add VPRecipeBase::mayHaveSideEffects.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 15 03:58:58 PDT 2021


Author: Florian Hahn
Date: 2021-04-15T11:49:40+01:00
New Revision: 6adebe3fd2914f1f87e8e984d1bf17639b119a89

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

LOG: [VPlan] Add VPRecipeBase::mayHaveSideEffects.

Add an initial version of a helper to determine whether a recipe may
have side-effects.

Reviewed By: a.elovikov

Differential Revision: https://reviews.llvm.org/D100259

Added: 
    

Modified: 
    llvm/lib/Transforms/Vectorize/VPlan.cpp
    llvm/lib/Transforms/Vectorize/VPlan.h
    llvm/unittests/Transforms/Vectorize/VPlanTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index 421ecb28029a7..6a4ec00f17341 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -510,6 +510,31 @@ void VPRegionBlock::print(raw_ostream &O, const Twine &Indent,
 }
 #endif
 
+bool VPRecipeBase::mayHaveSideEffects() const {
+  switch (getVPDefID()) {
+  case VPBranchOnMaskSC:
+    return false;
+  case VPBlendSC:
+  case VPWidenSC:
+  case VPWidenGEPSC:
+  case VPReductionSC:
+  case VPWidenSelectSC: {
+    const Instruction *I =
+        dyn_cast_or_null<Instruction>(getVPValue()->getUnderlyingValue());
+    (void)I;
+    assert((!I || !I->mayHaveSideEffects()) &&
+           "underlying instruction has side-effects");
+    return false;
+  }
+  case VPReplicateSC: {
+    auto *R = cast<VPReplicateRecipe>(this);
+    return R->getUnderlyingInstr()->mayHaveSideEffects();
+  }
+  default:
+    return true;
+  }
+}
+
 void VPRecipeBase::insertBefore(VPRecipeBase *InsertPos) {
   assert(!Parent && "Recipe already in some VPBasicBlock");
   assert(InsertPos->getParent() &&

diff  --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 05815d1084f2a..495a98a97980c 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -681,6 +681,9 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
     // All VPDefs are also VPRecipeBases.
     return true;
   }
+
+  /// Returns true if the recipe may have side-effects.
+  bool mayHaveSideEffects() const;
 };
 
 inline bool VPUser::classof(const VPDef *Def) {

diff  --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
index 2836e8199678a..f0070640be50f 100644
--- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
@@ -610,6 +610,103 @@ TEST(VPRecipeTest, CastVPWidenMemoryInstructionRecipeToVPUserAndVPDef) {
   delete Load;
 }
 
+TEST(VPRecipeTest, MayHaveSideEffects) {
+  LLVMContext C;
+  IntegerType *Int1 = IntegerType::get(C, 1);
+  IntegerType *Int32 = IntegerType::get(C, 32);
+  PointerType *Int32Ptr = PointerType::get(Int32, 0);
+
+  {
+    auto *AI = BinaryOperator::CreateAdd(UndefValue::get(Int32),
+                                         UndefValue::get(Int32));
+    VPValue Op1;
+    VPValue Op2;
+    SmallVector<VPValue *, 2> Args;
+    Args.push_back(&Op1);
+    Args.push_back(&Op1);
+    VPWidenRecipe Recipe(*AI, make_range(Args.begin(), Args.end()));
+    EXPECT_FALSE(Recipe.mayHaveSideEffects());
+
+    delete AI;
+  }
+
+  {
+    auto *SelectI = SelectInst::Create(
+        UndefValue::get(Int1), UndefValue::get(Int32), UndefValue::get(Int32));
+    VPValue Op1;
+    VPValue Op2;
+    VPValue Op3;
+    SmallVector<VPValue *, 4> Args;
+    Args.push_back(&Op1);
+    Args.push_back(&Op2);
+    Args.push_back(&Op3);
+    VPWidenSelectRecipe Recipe(*SelectI, make_range(Args.begin(), Args.end()),
+                               false);
+    EXPECT_FALSE(Recipe.mayHaveSideEffects());
+    delete SelectI;
+  }
+
+  {
+    auto *GEP = GetElementPtrInst::Create(Int32, UndefValue::get(Int32Ptr),
+                                          UndefValue::get(Int32));
+    VPValue Op1;
+    VPValue Op2;
+    SmallVector<VPValue *, 4> Args;
+    Args.push_back(&Op1);
+    Args.push_back(&Op2);
+    VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end()));
+    EXPECT_FALSE(Recipe.mayHaveSideEffects());
+    delete GEP;
+  }
+
+  {
+    VPValue Mask;
+    VPBranchOnMaskRecipe Recipe(&Mask);
+    EXPECT_FALSE(Recipe.mayHaveSideEffects());
+  }
+
+  {
+    VPValue ChainOp;
+    VPValue VecOp;
+    VPValue CondOp;
+    VPReductionRecipe Recipe(nullptr, nullptr, &ChainOp, &CondOp, &VecOp,
+                             nullptr);
+    EXPECT_FALSE(Recipe.mayHaveSideEffects());
+  }
+
+  {
+    auto *Load =
+        new LoadInst(Int32, UndefValue::get(Int32Ptr), "", false, Align(1));
+    VPValue Addr;
+    VPValue Mask;
+    VPWidenMemoryInstructionRecipe Recipe(*Load, &Addr, &Mask);
+    EXPECT_TRUE(Recipe.mayHaveSideEffects());
+
+    delete Load;
+  }
+
+  {
+    FunctionType *FTy = FunctionType::get(Int32, false);
+    auto *Call = CallInst::Create(FTy, UndefValue::get(FTy));
+    VPValue Op1;
+    VPValue Op2;
+    SmallVector<VPValue *, 2> Args;
+    Args.push_back(&Op1);
+    Args.push_back(&Op2);
+    VPWidenCallRecipe Recipe(*Call, make_range(Args.begin(), Args.end()));
+    EXPECT_TRUE(Recipe.mayHaveSideEffects());
+    delete Call;
+  }
+
+  // The initial implementation is conservative with respect to VPInstructions.
+  {
+    VPValue Op1;
+    VPValue Op2;
+    VPInstruction Recipe(Instruction::Add, {&Op1, &Op2});
+    EXPECT_TRUE(Recipe.mayHaveSideEffects());
+  }
+}
+
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
 TEST(VPRecipeTest, dump) {
   VPlan Plan;


        


More information about the llvm-commits mailing list