Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -785,7 +785,9 @@ MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateFAdd(LC, RC, FMF), Name); + if (Constant *C = Insert(Folder.CreateFAdd(LC, RC, FMF, + /* Strict = */ true), Name)) + return C; return Insert(AddFPMathAttributes(BinaryOperator::CreateFAdd(LHS, RHS), FPMathTag, FMF), Name); } @@ -807,7 +809,9 @@ MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateFSub(LC, RC, FMF), Name); + if (Constant *C = Insert(Folder.CreateFSub(LC, RC, FMF, + /* Strict = */ true), Name)) + return C; return Insert(AddFPMathAttributes(BinaryOperator::CreateFSub(LHS, RHS), FPMathTag, FMF), Name); } @@ -829,7 +833,9 @@ MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateFMul(LC, RC, FMF), Name); + if (Constant *C = Insert(Folder.CreateFMul(LC, RC, FMF, + /* Strict = */ true), Name)) + return C; return Insert(AddFPMathAttributes(BinaryOperator::CreateFMul(LHS, RHS), FPMathTag, FMF), Name); } @@ -861,7 +867,9 @@ MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateFDiv(LC, RC, FMF), Name); + if (Constant *C = Insert(Folder.CreateFDiv(LC, RC, FMF, + /* Strict = */ true), Name)) + return C; return Insert(AddFPMathAttributes(BinaryOperator::CreateFDiv(LHS, RHS), FPMathTag, FMF), Name); } @@ -881,7 +889,9 @@ MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateFRem(LC, RC, FMF), Name); + if (Constant *C = Insert(Folder.CreateFRem(LC, RC, FMF, + /* Strict = */ true), Name)) + return C; return Insert(AddFPMathAttributes(BinaryOperator::CreateFRem(LHS, RHS), FPMathTag, FMF), Name); } Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -221,6 +221,54 @@ } +TEST_F(IRBuilderTest, FPEnvFlags) { + IRBuilder<> Builder(BB); + Value *F; + + Constant *Huge = ConstantFP::get(Type::getDoubleTy(Ctx), 1.000000e+308); + Constant *Big = ConstantFP::get(Type::getDoubleTy(Ctx), 1.000000e+300); + Constant *Small = ConstantFP::get(Type::getDoubleTy(Ctx), 1.000000e-300); + Constant *Tiny = ConstantFP::get(Type::getDoubleTy(Ctx), 1.000000e-308); + Constant *Zero = ConstantFP::get(Type::getDoubleTy(Ctx), 0.0); + + FastMathFlags KeepExceptions; + KeepExceptions.clear(); + KeepExceptions.setNoRounding(); + Builder.SetFastMathFlags(KeepExceptions); + + F = Builder.CreateFAdd(Huge, Huge); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFSub(Tiny, Huge); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFMul(Big, Big); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFDiv(Big, Small); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFDiv(Big, Zero); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFRem(Big, Zero); + EXPECT_FALSE(isa(F)); + + FastMathFlags KeepRounding; + KeepRounding.clear(); + KeepRounding.setNoExceptions(); + Builder.SetFastMathFlags(KeepRounding); + + F = Builder.CreateFAdd(Huge, Huge); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFSub(Tiny, Huge); + EXPECT_FALSE(isa(F)); + + F = Builder.CreateFMul(Huge, Huge); + EXPECT_FALSE(isa(F)); +} + TEST_F(IRBuilderTest, WrapFlags) { IRBuilder Builder(BB);