From d91998a5ac5e5155419d3ea1e8b4113792626fe3 Mon Sep 17 00:00:00 2001 From: "Kevin P. Neal" Date: Thu, 18 Jul 2019 18:01:57 +0000 Subject: [PATCH] [FPEnv] Teach the IRBuilder about constrained FPTrunc and FPExt The IRBuilder doesn't know that FPTrunc and FPExt have constrained equivalents. Add the support by building on the strict FP mode now present in the IRBuilder. Reviewed by: John McCall Approved by: John McCall Differential Revision: https://reviews.llvm.org/D64934 llvm-svn: 366477 --- llvm/include/llvm/IR/IRBuilder.h | 30 ++++++++++++++++++++++++++++++ llvm/unittests/IR/IRBuilderTest.cpp | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index a74364d..88630f5 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1931,10 +1931,17 @@ public: Value *CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPCast( + Intrinsic::experimental_constrained_fptrunc, V, DestTy, nullptr, + Name); return CreateCast(Instruction::FPTrunc, V, DestTy, Name); } Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fpext, + V, DestTy, nullptr, Name); return CreateCast(Instruction::FPExt, V, DestTy, Name); } @@ -2046,6 +2053,29 @@ public: return Insert(CastInst::CreateFPCast(V, DestTy), Name); } + CallInst *CreateConstrainedFPCast( + Intrinsic::ID ID, Value *V, Type *DestTy, + Instruction *FMFSource = nullptr, const Twine &Name = "", + MDNode *FPMathTag = nullptr, + Optional Rounding = None, + Optional Except = None) { + Value *RoundingV = getConstrainedFPRounding(Rounding); + Value *ExceptV = getConstrainedFPExcept(Except); + + FastMathFlags UseFMF = FMF; + if (FMFSource) + UseFMF = FMFSource->getFastMathFlags(); + + CallInst *C; + if (ID == Intrinsic::experimental_constrained_fpext) + C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr, + Name); + else + C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV}, + nullptr, Name); + return cast(setFPAttrs(C, FPMathTag, UseFMF)); + } + // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a // compile time error, instead of converting the string to bool for the // isSigned parameter. diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 667b9ef..f73cf14 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -125,10 +125,14 @@ TEST_F(IRBuilderTest, Intrinsics) { TEST_F(IRBuilderTest, ConstrainedFP) { IRBuilder<> Builder(BB); Value *V; + Value *VDouble; CallInst *Call; IntrinsicInst *II; + GlobalVariable *GVDouble = new GlobalVariable(*M, Type::getDoubleTy(Ctx), + true, GlobalValue::ExternalLinkage, nullptr); V = Builder.CreateLoad(GV->getValueType(), GV); + VDouble = Builder.CreateLoad(GVDouble->getValueType(), GVDouble); // See if we get constrained intrinsics instead of non-constrained // instructions. @@ -159,6 +163,16 @@ TEST_F(IRBuilderTest, ConstrainedFP) { II = cast(V); EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem); + V = Builder.CreateFPTrunc(VDouble, Type::getFloatTy(Ctx)); + ASSERT_TRUE(isa(V)); + II = cast(V); + EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptrunc); + + VDouble = Builder.CreateFPExt(V, Type::getDoubleTy(Ctx)); + ASSERT_TRUE(isa(VDouble)); + II = cast(VDouble); + EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fpext); + // Verify the codepaths for setting and overriding the default metadata. V = Builder.CreateFAdd(V, V); ASSERT_TRUE(isa(V)); -- 2.7.4