diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h index c9c11be89d6..617f40de8f5 100644 --- a/include/llvm/IR/IRBuilder.h +++ b/include/llvm/IR/IRBuilder.h @@ -638,7 +638,7 @@ public: bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateSub(LC, RC), Name); + return Insert(Folder.CreateSub(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Sub, LHS, RHS, Name, HasNUW, HasNSW); } @@ -660,7 +660,7 @@ public: bool HasNUW = false, bool HasNSW = false) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateMul(LC, RC), Name); + return Insert(Folder.CreateMul(LC, RC, HasNUW, HasNSW), Name); return CreateInsertNUWNSWBinOp(Instruction::Mul, LHS, RHS, Name, HasNUW, HasNSW); } diff --git a/unittests/IR/IRBuilderTest.cpp b/unittests/IR/IRBuilderTest.cpp index fcb56779073..a0a72e82ed8 100644 --- a/unittests/IR/IRBuilderTest.cpp +++ b/unittests/IR/IRBuilderTest.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Module.h" +#include "llvm/Support/NoFolder.h" #include "gtest/gtest.h" using namespace llvm; @@ -190,6 +191,56 @@ TEST_F(IRBuilderTest, FastMathFlags) { } +TEST_F(IRBuilderTest, WrapFlags) { + IRBuilder Builder(BB); + + // Test instructions. + GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true, + GlobalValue::ExternalLinkage, 0); + Value *V = Builder.CreateLoad(G); + EXPECT_TRUE( + cast(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNSWMul(V, V))->hasNoSignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNSWSub(V, V))->hasNoSignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true)) + ->hasNoSignedWrap()); + + EXPECT_TRUE( + cast(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE( + cast(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false)) + ->hasNoUnsignedWrap()); + + // Test operators created with constants. + Constant *C = Builder.getInt32(42); + EXPECT_TRUE(cast(Builder.CreateNSWAdd(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNSWSub(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNSWMul(C, C)) + ->hasNoSignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true)) + ->hasNoSignedWrap()); + + EXPECT_TRUE(cast(Builder.CreateNUWAdd(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNUWSub(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast(Builder.CreateNUWMul(C, C)) + ->hasNoUnsignedWrap()); + EXPECT_TRUE(cast( + Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false)) + ->hasNoUnsignedWrap()); +} + TEST_F(IRBuilderTest, RAIIHelpersTest) { IRBuilder<> Builder(BB); EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());