1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[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
This commit is contained in:
Florian Hahn 2021-04-15 10:42:40 +01:00
parent 68f371389f
commit 09bcc572cb
3 changed files with 125 additions and 0 deletions

View File

@ -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() &&

View File

@ -681,6 +681,9 @@ public:
// 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) {

View File

@ -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;