From fab40fce3ffecc3f93068a15e370c0a1abfdb8d0 Mon Sep 17 00:00:00 2001 From: "Kevin P. Neal" Date: Fri, 6 Sep 2019 18:04:34 +0000 Subject: [PATCH] [FPEnv] Teach the IRBuilder about constrained FPToSI and FPToUI. The IRBuilder doesn't know that the two floating point to integer instructions have constrained equivalents. This patch adds 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/D67291 llvm-svn: 371235 --- llvm/include/llvm/IR/IRBuilder.h | 30 ++++++++++++++++++++++-------- llvm/unittests/IR/IRBuilderTest.cpp | 11 +++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 35014ed..e5dcea1 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -1913,11 +1913,17 @@ public: return V; } - Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fptoui, + V, DestTy, nullptr, Name); return CreateCast(Instruction::FPToUI, V, DestTy, Name); } - Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = "") { + if (IsFPConstrained) + return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fptosi, + V, DestTy, nullptr, Name); return CreateCast(Instruction::FPToSI, V, DestTy, Name); } @@ -2059,7 +2065,6 @@ public: MDNode *FPMathTag = nullptr, Optional Rounding = None, Optional Except = None) { - Value *RoundingV = getConstrainedFPRounding(Rounding); Value *ExceptV = getConstrainedFPExcept(Except); FastMathFlags UseFMF = FMF; @@ -2067,13 +2072,22 @@ public: UseFMF = FMFSource->getFastMathFlags(); CallInst *C; - if (ID == Intrinsic::experimental_constrained_fpext) - C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr, - Name); - else + switch (ID) { + default: { + Value *RoundingV = getConstrainedFPRounding(Rounding); C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV}, nullptr, Name); - return cast(setFPAttrs(C, FPMathTag, UseFMF)); + } break; + case Intrinsic::experimental_constrained_fpext: + case Intrinsic::experimental_constrained_fptoui: + case Intrinsic::experimental_constrained_fptosi: + C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr, + Name); + break; + } + if (isa(C)) + C = cast(setFPAttrs(C, FPMathTag, UseFMF)); + return C; } // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 538c2a0..8fb5337 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -171,6 +171,7 @@ TEST_F(IRBuilderTest, ConstrainedFP) { IRBuilder<> Builder(BB); Value *V; Value *VDouble; + Value *VInt; CallInst *Call; IntrinsicInst *II; GlobalVariable *GVDouble = new GlobalVariable(*M, Type::getDoubleTy(Ctx), @@ -208,6 +209,16 @@ TEST_F(IRBuilderTest, ConstrainedFP) { II = cast(V); EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem); + VInt = Builder.CreateFPToUI(VDouble, Builder.getInt32Ty()); + ASSERT_TRUE(isa(VInt)); + II = cast(VInt); + EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptoui); + + VInt = Builder.CreateFPToSI(VDouble, Builder.getInt32Ty()); + ASSERT_TRUE(isa(VInt)); + II = cast(VInt); + EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptosi); + V = Builder.CreateFPTrunc(VDouble, Type::getFloatTy(Ctx)); ASSERT_TRUE(isa(V)); II = cast(V); -- 2.7.4