kpn updated this revision to Diff 176464.
kpn added a comment.

Address review comment: Shrink the diff by eliminating unneeded use of else.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D53157/new/

https://reviews.llvm.org/D53157

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

Index: unittests/IR/IRBuilderTest.cpp
===================================================================
--- unittests/IR/IRBuilderTest.cpp
+++ unittests/IR/IRBuilderTest.cpp
@@ -123,6 +123,100 @@
   EXPECT_FALSE(II->hasNoNaNs());
 }
 
+TEST_F(IRBuilderTest, ConstrainedFP) {
+  IRBuilder<> Builder(BB);
+  Value *V;
+  CallInst *Call;
+  IntrinsicInst *II;
+
+  V = Builder.CreateLoad(GV);
+
+  Call = Builder.CreateConstrainedFAdd(V, V);
+  II = cast<IntrinsicInst>(Call);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+
+  Call = Builder.CreateConstrainedFSub(V, V);
+  II = cast<IntrinsicInst>(Call);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fsub);
+
+  Call = Builder.CreateConstrainedFMul(V, V);
+  II = cast<IntrinsicInst>(Call);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fmul);
+
+  Call = Builder.CreateConstrainedFDiv(V, V);
+  II = cast<IntrinsicInst>(Call);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fdiv);
+
+  Call = Builder.CreateConstrainedFRem(V, V);
+  II = cast<IntrinsicInst>(Call);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);
+
+  // Now see if we get constrained intrinsics instead of non-constrained
+  // instructions.
+  Builder.setIsConstrainedFP(true);
+
+  V = Builder.CreateFAdd(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fadd);
+
+  V = Builder.CreateFSub(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fsub);
+
+  V = Builder.CreateFMul(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fmul);
+  
+  V = Builder.CreateFDiv(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fdiv);
+  
+  V = Builder.CreateFRem(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  II = cast<IntrinsicInst>(V);
+  EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_frem);
+
+  // Verify the codepaths for setting and overriding the default metadata.
+  MDNode *ExceptStr = MDNode::get(Builder.getContext(), 
+                                  MDString::get(Builder.getContext(), 
+                                                "fpexcept.strict"));
+  MDNode *ExceptIgn = MDNode::get(Builder.getContext(), 
+                                  MDString::get(Builder.getContext(), 
+                                                "fpexcept.ignore"));
+  MDNode *RoundDyn = MDNode::get(Builder.getContext(), 
+                                 MDString::get(Builder.getContext(),
+                                               "round.dynamic"));
+  MDNode *RoundUp = MDNode::get(Builder.getContext(), 
+                                MDString::get(Builder.getContext(),
+                                              "round.upward"));
+
+  V = Builder.CreateFAdd(V, V);
+  ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));
+  auto *CII = cast<ConstrainedFPIntrinsic>(V);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebStrict);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDynamic);
+
+  Builder.setDefaultConstrainedExcept(ExceptIgn);
+  Builder.setDefaultConstrainedRounding(RoundUp);
+  V = Builder.CreateFAdd(V, V);
+  CII = cast<ConstrainedFPIntrinsic>(V);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebIgnore);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmUpward);
+
+  // Now override the defaults.
+  Call = Builder.CreateConstrainedFAdd(V, V, nullptr, "", RoundDyn, ExceptStr);
+  CII = cast<ConstrainedFPIntrinsic>(Call);
+  ASSERT_TRUE(CII->getExceptionBehavior() == ConstrainedFPIntrinsic::ebStrict);
+  ASSERT_TRUE(CII->getRoundingMode() == ConstrainedFPIntrinsic::rmDynamic);
+
+  Builder.CreateRetVoid();
+  EXPECT_FALSE(verifyModule(*M));
+}
+
 TEST_F(IRBuilderTest, Lifetime) {
   IRBuilder<> Builder(BB);
   AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
Index: include/llvm/IR/IRBuilder.h
===================================================================
--- include/llvm/IR/IRBuilder.h
+++ include/llvm/IR/IRBuilder.h
@@ -97,13 +97,18 @@
   MDNode *DefaultFPMathTag;
   FastMathFlags FMF;
 
+  bool IsFPConstrained;
+  MDNode *DefaultConstrainedExcept;
+  MDNode *DefaultConstrainedRounding;
+
   ArrayRef<OperandBundleDef> DefaultOperandBundles;
 
 public:
   IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr,
                 ArrayRef<OperandBundleDef> OpBundles = None)
       : Context(context), DefaultFPMathTag(FPMathTag),
-        DefaultOperandBundles(OpBundles) {
+        IsFPConstrained(false), DefaultConstrainedExcept(nullptr),
+        DefaultConstrainedRounding(nullptr), DefaultOperandBundles(OpBundles) {
     ClearInsertionPoint();
   }
 
@@ -219,6 +224,40 @@
   /// Set the fast-math flags to be used with generated fp-math operators
   void setFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
 
+  /// Enable/Disable use of constrained floating point math
+  void setIsConstrainedFP(bool IsCon) { IsFPConstrained = IsCon; }
+
+  /// Disable use of constrained floating point math
+  void clearIsConstrainedFP() { setIsConstrainedFP(false); }
+
+  /// Set the exception handling to be used with constrained floating point
+  void setDefaultConstrainedExcept(MDNode *NewExcept) { 
+    DefaultConstrainedExcept = NewExcept; 
+  }
+
+  /// Set the rounding mode handling to be used with constrained floating point
+  void setDefaultConstrainedRounding(MDNode *NewRounding) { 
+    DefaultConstrainedRounding = NewRounding; 
+  }
+
+  /// Get the exception handling used with constrained floating point
+  MDNode *getDefaultConstrainedExcept() { 
+    if (!DefaultConstrainedExcept) {
+      DefaultConstrainedExcept = 
+        MDNode::get(Context, MDString::get(Context, "fpexcept.strict"));
+    }
+    return DefaultConstrainedExcept; 
+  }
+
+  /// Get the rounding mode handling used with constrained floating point
+  MDNode *getDefaultConstrainedRounding() {
+    if (!DefaultConstrainedRounding) {
+      DefaultConstrainedRounding = 
+        MDNode::get(Context, MDString::get(Context, "round.dynamic"));
+    }
+    return DefaultConstrainedRounding;
+  }
+
   //===--------------------------------------------------------------------===//
   // RAII helpers.
   //===--------------------------------------------------------------------===//
@@ -970,6 +1009,28 @@
     return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr;
   }
 
+  Value *getConstrainedRounding(MDNode *RoundingMD) {
+    MDString *Rounding;
+
+    if (!RoundingMD)
+      RoundingMD = getDefaultConstrainedRounding();
+
+    Rounding = cast<MDString>(RoundingMD->getOperand(0));
+
+    return MetadataAsValue::get(Context, Rounding);
+  }
+
+  Value *getConstrainedExcept(MDNode *ExceptMD) {
+    MDString *Except;
+
+    if (!ExceptMD)
+      ExceptMD = getDefaultConstrainedExcept();
+
+    Except = cast<MDString>(ExceptMD->getOperand(0));
+
+    return MetadataAsValue::get(Context, Except);
+  }
+
 public:
   Value *CreateAdd(Value *LHS, Value *RHS, const Twine &Name = "",
                    bool HasNUW = false, bool HasNSW = false) {
@@ -1172,6 +1233,9 @@
 
   Value *CreateFAdd(Value *L, Value *R, const Twine &Name = "",
                     MDNode *FPMD = nullptr) {
+    if (IsFPConstrained)
+      return CreateConstrainedFAdd(L, R, nullptr, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMF);
     return Insert(I, Name);
@@ -1181,14 +1245,34 @@
   /// default FMF.
   Value *CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource,
                        const Twine &Name = "") {
+    if (IsFPConstrained)
+      return CreateConstrainedFAdd(L, R, FMFSource, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FAdd, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), nullptr,
                                 FMFSource->getFastMathFlags());
     return Insert(I, Name);
   }
 
+  CallInst *CreateConstrainedFAdd(Value *L, Value *R, 
+                                  Instruction *FMFSource = nullptr,                                               const Twine &Name = "",
+                                  MDNode *RoundingMD = nullptr,               
+                                  MDNode *ExceptMD = nullptr) {
+
+    Value *Rounding = getConstrainedRounding(RoundingMD);
+    Value *Except = getConstrainedExcept(ExceptMD);
+
+    return CreateIntrinsic(Intrinsic::experimental_constrained_fadd, 
+                           { L->getType() }, 
+                           { L, R, Rounding, Except },
+                           FMFSource, Name);
+  }
+
   Value *CreateFSub(Value *L, Value *R, const Twine &Name = "",
                     MDNode *FPMD = nullptr) {
+    if (IsFPConstrained)
+      return CreateConstrainedFSub(L, R, nullptr, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMF);
     return Insert(I, Name);
@@ -1198,14 +1282,35 @@
   /// default FMF.
   Value *CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource,
                        const Twine &Name = "") {
+    if (IsFPConstrained)
+      return CreateConstrainedFSub(L, R, FMFSource, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FSub, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), nullptr,
                                 FMFSource->getFastMathFlags());
     return Insert(I, Name);
   }
 
+  CallInst *CreateConstrainedFSub(Value *L, Value *R, 
+                                  Instruction *FMFSource = nullptr, 
+                                  const Twine &Name = "",
+                                  MDNode *RoundingMD = nullptr, 
+                                  MDNode *ExceptMD = nullptr) {
+ 
+    Value *Rounding = getConstrainedRounding(RoundingMD);
+    Value *Except = getConstrainedExcept(ExceptMD);
+
+    return CreateIntrinsic(Intrinsic::experimental_constrained_fsub, 
+                           { L->getType() }, 
+                           { L, R, Rounding, Except },
+                           FMFSource, Name);
+  }
+
   Value *CreateFMul(Value *L, Value *R, const Twine &Name = "",
                     MDNode *FPMD = nullptr) {
+    if (IsFPConstrained)
+      return CreateConstrainedFMul(L, R, nullptr, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMF);
     return Insert(I, Name);
@@ -1215,14 +1320,35 @@
   /// default FMF.
   Value *CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource,
                        const Twine &Name = "") {
+    if (IsFPConstrained)
+      return CreateConstrainedFMul(L, R, FMFSource, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FMul, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), nullptr,
                                 FMFSource->getFastMathFlags());
     return Insert(I, Name);
   }
 
+  CallInst *CreateConstrainedFMul(Value *L, Value *R, 
+                                  Instruction *FMFSource = nullptr, 
+                                  const Twine &Name = "",
+                                  MDNode *RoundingMD = nullptr, 
+                                  MDNode *ExceptMD = nullptr) {
+ 
+    Value *Rounding = getConstrainedRounding(RoundingMD);
+    Value *Except = getConstrainedExcept(ExceptMD);
+
+    return CreateIntrinsic(Intrinsic::experimental_constrained_fmul, 
+                           { L->getType() }, 
+                           { L, R, Rounding, Except },
+                           FMFSource, Name);
+  }
+
   Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "",
                     MDNode *FPMD = nullptr) {
+    if (IsFPConstrained)
+      return CreateConstrainedFDiv(L, R, nullptr, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMF);
     return Insert(I, Name);
@@ -1232,14 +1358,35 @@
   /// default FMF.
   Value *CreateFDivFMF(Value *L, Value *R, Instruction *FMFSource,
                        const Twine &Name = "") {
+    if (IsFPConstrained)
+      return CreateConstrainedFDiv(L, R, FMFSource, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FDiv, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr,
                                 FMFSource->getFastMathFlags());
     return Insert(I, Name);
   }
 
+  CallInst *CreateConstrainedFDiv(Value *L, Value *R, 
+                                  Instruction *FMFSource = nullptr, 
+                                  const Twine &Name = "",
+                                  MDNode *RoundingMD = nullptr, 
+                                  MDNode *ExceptMD = nullptr) {
+ 
+    Value *Rounding = getConstrainedRounding(RoundingMD);
+    Value *Except = getConstrainedExcept(ExceptMD);
+
+    return CreateIntrinsic(Intrinsic::experimental_constrained_fdiv, 
+                           { L->getType() }, 
+                           { L, R, Rounding, Except },
+                           FMFSource, Name);
+  }
+
   Value *CreateFRem(Value *L, Value *R, const Twine &Name = "",
                     MDNode *FPMD = nullptr) {
+    if (IsFPConstrained)
+      return CreateConstrainedFRem(L, R, nullptr, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMF);
     return Insert(I, Name);
@@ -1249,12 +1396,30 @@
   /// default FMF.
   Value *CreateFRemFMF(Value *L, Value *R, Instruction *FMFSource,
                        const Twine &Name = "") {
+    if (IsFPConstrained)
+      return CreateConstrainedFRem(L, R, FMFSource, Name, nullptr, nullptr);
+
     if (Value *V = foldConstant(Instruction::FRem, L, R, Name)) return V;
     Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), nullptr,
                                 FMFSource->getFastMathFlags());
     return Insert(I, Name);
   }
 
+  CallInst *CreateConstrainedFRem(Value *L, Value *R, 
+                                  Instruction *FMFSource = nullptr, 
+                                  const Twine &Name = "",
+                                  MDNode *RoundingMD = nullptr, 
+                                  MDNode *ExceptMD = nullptr) {
+ 
+    Value *Rounding = getConstrainedRounding(RoundingMD);
+    Value *Except = getConstrainedExcept(ExceptMD);
+
+    return CreateIntrinsic(Intrinsic::experimental_constrained_frem, 
+                           { L->getType() }, 
+                           { L, R, Rounding, Except },
+                           FMFSource, Name);
+  }
+
   Value *CreateBinOp(Instruction::BinaryOps Opc,
                      Value *LHS, Value *RHS, const Twine &Name = "",
                      MDNode *FPMathTag = nullptr) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to