diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1543,6 +1543,7 @@ return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv, L, R, FMFSource, Name); + FastMathFlags FMF = FMFSource->getFastMathFlags(); if (Value *V = Folder.FoldBinOpFMF(Instruction::FDiv, L, R, FMF)) return V; Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr, FMF); diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -551,7 +551,7 @@ TEST_F(IRBuilderTest, FastMathFlags) { IRBuilder<> Builder(BB); Value *F, *FC; - Instruction *FDiv, *FAdd, *FCmp, *FCall; + Instruction *FDiv, *FAdd, *FCmp, *FCall, *FNeg, *FSub, *FMul, *FRem; F = Builder.CreateLoad(GV->getValueType(), GV); F = Builder.CreateFAdd(F, F); @@ -732,6 +732,36 @@ EXPECT_TRUE(FDiv->hasNoNaNs()); EXPECT_FALSE(FDiv->hasAllowReciprocal()); + // Test that CreateF*FMF functions copy flags from the source instruction + // instead of using the builder default. + Instruction *const FMFSource = FAdd; + EXPECT_FALSE(Builder.getFastMathFlags().noNaNs()); + EXPECT_TRUE(FMFSource->hasNoNaNs()); + + F = Builder.CreateFNegFMF(F, FMFSource); + ASSERT_TRUE(isa(F)); + FNeg = cast(F); + EXPECT_TRUE(FNeg->hasNoNaNs()); + F = Builder.CreateFAddFMF(F, F, FMFSource); + ASSERT_TRUE(isa(F)); + FAdd = cast(F); + EXPECT_TRUE(FAdd->hasNoNaNs()); + F = Builder.CreateFSubFMF(F, F, FMFSource); + ASSERT_TRUE(isa(F)); + FSub = cast(F); + EXPECT_TRUE(FSub->hasNoNaNs()); + F = Builder.CreateFMulFMF(F, F, FMFSource); + ASSERT_TRUE(isa(F)); + FMul = cast(F); + EXPECT_TRUE(FMul->hasNoNaNs()); + F = Builder.CreateFDivFMF(F, F, FMFSource); + ASSERT_TRUE(isa(F)); + FDiv = cast(F); + EXPECT_TRUE(FDiv->hasNoNaNs()); + F = Builder.CreateFRemFMF(F, F, FMFSource); + ASSERT_TRUE(isa(F)); + FRem = cast(F); + EXPECT_TRUE(FRem->hasNoNaNs()); } TEST_F(IRBuilderTest, WrapFlags) {