Skip to content

Commit

Permalink
[VPlan] Add VPRecipeBase::mayHaveSideEffects.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fhahn committed Apr 15, 2021
1 parent 0f3ed7a commit 6adebe3
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
25 changes: 25 additions & 0 deletions llvm/lib/Transforms/Vectorize/VPlan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() &&
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
97 changes: 97 additions & 0 deletions llvm/unittests/Transforms/Vectorize/VPlanTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 6adebe3

Please sign in to comment.