[llvm] r296035 - [IR] Add a Instruction::dropPoisonGeneratingFlags helper
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 23 14:50:53 PST 2017
Author: sanjoy
Date: Thu Feb 23 16:50:52 2017
New Revision: 296035
URL: http://llvm.org/viewvc/llvm-project?rev=296035&view=rev
Log:
[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
Modified:
llvm/trunk/include/llvm/IR/Instruction.h
llvm/trunk/lib/IR/Instruction.cpp
llvm/trunk/unittests/IR/InstructionsTest.cpp
Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=296035&r1=296034&r2=296035&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Thu Feb 23 16:50:52 2017
@@ -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;
Modified: llvm/trunk/lib/IR/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instruction.cpp?rev=296035&r1=296034&r2=296035&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instruction.cpp (original)
+++ llvm/trunk/lib/IR/Instruction.cpp Thu Feb 23 16:50:52 2017
@@ -122,6 +122,29 @@ bool Instruction::hasNoSignedWrap() cons
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();
}
Modified: llvm/trunk/unittests/IR/InstructionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/InstructionsTest.cpp?rev=296035&r1=296034&r2=296035&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/InstructionsTest.cpp (original)
+++ llvm/trunk/unittests/IR/InstructionsTest.cpp Thu Feb 23 16:50:52 2017
@@ -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, AlterInvokeBundle
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
More information about the llvm-commits
mailing list