]> granicus.if.org Git - llvm/commitdiff
[FPEnv] Teach the IRBuilder about constrained FPToSI and FPToUI.
authorKevin P. Neal <kevin.neal@sas.com>
Fri, 6 Sep 2019 18:04:34 +0000 (18:04 +0000)
committerKevin P. Neal <kevin.neal@sas.com>
Fri, 6 Sep 2019 18:04:34 +0000 (18:04 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@371235 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IRBuilder.h
unittests/IR/IRBuilderTest.cpp

index 35014ed5eceb18db0c1b797e35b134ca5ab71b3e..e5dcea1d4c0e9e30acf16f71c8f935c05904e5c2 100644 (file)
@@ -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<ConstrainedFPIntrinsic::RoundingMode> Rounding = None,
       Optional<ConstrainedFPIntrinsic::ExceptionBehavior> 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<CallInst>(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<FPMathOperator>(C))
+      C = cast<CallInst>(setFPAttrs(C, FPMathTag, UseFMF));
+    return C;
   }
 
   // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
index 538c2a0dd93862d922cb39332da6d06f539ff65f..8fb5337a2912204efcc7f2918b74be2dd025a8ef 100644 (file)
@@ -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<IntrinsicInst>(V);
   EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);
 
+  VInt = Builder.CreateFPToUI(VDouble, Builder.getInt32Ty());
+  ASSERT_TRUE(isa<IntrinsicInst>(VInt));
+  II = cast<IntrinsicInst>(VInt);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptoui);
+
+  VInt = Builder.CreateFPToSI(VDouble, Builder.getInt32Ty());
+  ASSERT_TRUE(isa<IntrinsicInst>(VInt));
+  II = cast<IntrinsicInst>(VInt);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fptosi);
+
   V = Builder.CreateFPTrunc(VDouble, Type::getFloatTy(Ctx));
   ASSERT_TRUE(isa<IntrinsicInst>(V));
   II = cast<IntrinsicInst>(V);