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:
parent
68f371389f
commit
09bcc572cb
@ -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() &&
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user