[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