mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[IR] Add a Instruction::dropPoisonGeneratingFlags helper
Summary: The helper will be used in a later change. This change itself is NFC since the only user of this new function is its unit test. Reviewers: majnemer, efriedma Reviewed By: efriedma Subscribers: efriedma, mcrosier, llvm-commits Differential Revision: https://reviews.llvm.org/D30184 llvm-svn: 296035
This commit is contained in:
parent
828acceeb5
commit
c1d9ef40b5
@ -276,6 +276,10 @@ public:
|
||||
/// Determine whether the no signed wrap flag is set.
|
||||
bool hasNoSignedWrap() const;
|
||||
|
||||
/// Drops flags that may cause this instruction to evaluate to poison despite
|
||||
/// having non-poison inputs.
|
||||
void dropPoisonGeneratingFlags();
|
||||
|
||||
/// Determine whether the exact flag is set.
|
||||
bool isExact() const;
|
||||
|
||||
|
@ -122,6 +122,29 @@ bool Instruction::hasNoSignedWrap() const {
|
||||
return cast<OverflowingBinaryOperator>(this)->hasNoSignedWrap();
|
||||
}
|
||||
|
||||
void Instruction::dropPoisonGeneratingFlags() {
|
||||
switch (getOpcode()) {
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::Mul:
|
||||
case Instruction::Shl:
|
||||
cast<OverflowingBinaryOperator>(this)->setHasNoUnsignedWrap(false);
|
||||
cast<OverflowingBinaryOperator>(this)->setHasNoSignedWrap(false);
|
||||
break;
|
||||
|
||||
case Instruction::UDiv:
|
||||
case Instruction::SDiv:
|
||||
case Instruction::AShr:
|
||||
case Instruction::LShr:
|
||||
cast<PossiblyExactOperator>(this)->setIsExact(false);
|
||||
break;
|
||||
|
||||
case Instruction::GetElementPtr:
|
||||
cast<GetElementPtrInst>(this)->setIsInBounds(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Instruction::isExact() const {
|
||||
return cast<PossiblyExactOperator>(this)->isExact();
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/MDBuilder.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/NoFolder.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <memory>
|
||||
@ -579,5 +580,65 @@ TEST(InstructionsTest, AlterInvokeBundles) {
|
||||
EXPECT_TRUE(Clone->getOperandBundle("after").hasValue());
|
||||
}
|
||||
|
||||
TEST_F(ModuleWithFunctionTest, DropPoisonGeneratingFlags) {
|
||||
auto *OnlyBB = BasicBlock::Create(Ctx, "bb", F);
|
||||
auto *Arg0 = &*F->arg_begin();
|
||||
|
||||
IRBuilder<NoFolder> B(Ctx);
|
||||
B.SetInsertPoint(OnlyBB);
|
||||
|
||||
{
|
||||
auto *UI =
|
||||
cast<Instruction>(B.CreateUDiv(Arg0, Arg0, "", /*isExact*/ true));
|
||||
ASSERT_TRUE(UI->isExact());
|
||||
UI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(UI->isExact());
|
||||
}
|
||||
|
||||
{
|
||||
auto *ShrI =
|
||||
cast<Instruction>(B.CreateLShr(Arg0, Arg0, "", /*isExact*/ true));
|
||||
ASSERT_TRUE(ShrI->isExact());
|
||||
ShrI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(ShrI->isExact());
|
||||
}
|
||||
|
||||
{
|
||||
auto *AI = cast<Instruction>(
|
||||
B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ false));
|
||||
ASSERT_TRUE(AI->hasNoUnsignedWrap());
|
||||
AI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(AI->hasNoUnsignedWrap());
|
||||
ASSERT_FALSE(AI->hasNoSignedWrap());
|
||||
}
|
||||
|
||||
{
|
||||
auto *SI = cast<Instruction>(
|
||||
B.CreateAdd(Arg0, Arg0, "", /*HasNUW*/ false, /*HasNSW*/ true));
|
||||
ASSERT_TRUE(SI->hasNoSignedWrap());
|
||||
SI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(SI->hasNoUnsignedWrap());
|
||||
ASSERT_FALSE(SI->hasNoSignedWrap());
|
||||
}
|
||||
|
||||
{
|
||||
auto *ShlI = cast<Instruction>(
|
||||
B.CreateShl(Arg0, Arg0, "", /*HasNUW*/ true, /*HasNSW*/ true));
|
||||
ASSERT_TRUE(ShlI->hasNoSignedWrap());
|
||||
ASSERT_TRUE(ShlI->hasNoUnsignedWrap());
|
||||
ShlI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(ShlI->hasNoUnsignedWrap());
|
||||
ASSERT_FALSE(ShlI->hasNoSignedWrap());
|
||||
}
|
||||
|
||||
{
|
||||
Value *GEPBase = Constant::getNullValue(B.getInt8PtrTy());
|
||||
auto *GI = cast<GetElementPtrInst>(B.CreateInBoundsGEP(GEPBase, {Arg0}));
|
||||
ASSERT_TRUE(GI->isInBounds());
|
||||
GI->dropPoisonGeneratingFlags();
|
||||
ASSERT_FALSE(GI->isInBounds());
|
||||
}
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
} // end namespace llvm
|
||||
|
Loading…
x
Reference in New Issue
Block a user