[llvm] [FPEnv][IRBuilder] Set strictfp mode automatically when possible. (PR #98677)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 12 11:28:45 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Kevin P. Neal (kpneal)

<details>
<summary>Changes</summary>

The IRBuilder has a strictfp mode that replaces FP instructions with the matching constrained intrinsic, and it adds the strictfp attribute to all function calls. Check the function definition to see if the strictfp attribute is present and, if it is, enable the strictfp mode in the constructor.

Not all cases can be handled since some IRBuilder constructors don't provide a way to get the Function*, and additionally operations with a BasicBlock that doesn't belong to a Function are allowed by LLVM.

---
Full diff: https://github.com/llvm/llvm-project/pull/98677.diff


2 Files Affected:

- (modified) llvm/include/llvm/IR/IRBuilder.h (+20) 
- (modified) llvm/unittests/IR/IRBuilderTest.cpp (+40) 


``````````diff
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 31a1fef321995..7f2a853b06567 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -2691,6 +2691,10 @@ class IRBuilder : public IRBuilderBase {
                       FPMathTag, OpBundles),
         Folder(Folder) {
     SetInsertPoint(TheBB);
+    Function *F = TheBB->getParent();
+    if (F && F->hasFnAttribute(Attribute::StrictFP)) {
+      setIsFPConstrained(true);
+    }
   }
 
   explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
@@ -2698,6 +2702,10 @@ class IRBuilder : public IRBuilderBase {
       : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
                       FPMathTag, OpBundles) {
     SetInsertPoint(TheBB);
+    Function *F = TheBB->getParent();
+    if (F && F->hasFnAttribute(Attribute::StrictFP)) {
+      setIsFPConstrained(true);
+    }
   }
 
   explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
@@ -2705,6 +2713,10 @@ class IRBuilder : public IRBuilderBase {
       : IRBuilderBase(IP->getContext(), this->Folder, this->Inserter, FPMathTag,
                       OpBundles) {
     SetInsertPoint(IP);
+    Function *F = IP->getParent()->getParent();
+    if (F && F->hasFnAttribute(Attribute::StrictFP)) {
+      setIsFPConstrained(true);
+    }
   }
 
   IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, FolderTy Folder,
@@ -2714,6 +2726,10 @@ class IRBuilder : public IRBuilderBase {
                       FPMathTag, OpBundles),
         Folder(Folder) {
     SetInsertPoint(TheBB, IP);
+    Function *F = TheBB->getParent();
+    if (F && F->hasFnAttribute(Attribute::StrictFP)) {
+      setIsFPConstrained(true);
+    }
   }
 
   IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
@@ -2722,6 +2738,10 @@ class IRBuilder : public IRBuilderBase {
       : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
                       FPMathTag, OpBundles) {
     SetInsertPoint(TheBB, IP);
+    Function *F = TheBB->getParent();
+    if (F && F->hasFnAttribute(Attribute::StrictFP)) {
+      setIsFPConstrained(true);
+    }
   }
 
   /// Avoid copying the full IRBuilder. Prefer using InsertPointGuard
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index ff96df8581200..215390334b0be 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -448,6 +448,46 @@ TEST_F(IRBuilderTest, ConstrainedFPFunctionCall) {
   EXPECT_FALSE(verifyModule(*M));
 }
 
+TEST_F(IRBuilderTest, DetectDefaultStrictFP) {
+  // Create an empty constrained FP function.
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
+                                        /*isVarArg=*/false);
+  Function *FStrict = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
+  FStrict->addFnAttr(Attribute::StrictFP);
+  BasicBlock *BBStrict = BasicBlock::Create(Ctx, "", FStrict);
+
+  struct TestInserter : public IRBuilderDefaultInserter {
+    TestInserter() = default;
+  };
+  InstSimplifyFolder Folder(M->getDataLayout());
+
+  IRBuilder Builder1(BBStrict, Folder);
+
+  // A simple check is sufficient since we already check that StrictFP
+  // mode works correctly in previous tests above.
+  EXPECT_TRUE(Builder1.getIsFPConstrained());
+
+  MDBuilder MDB(M->getContext());
+  MDNode *FPMath = MDB.createFPMath(0.01f);
+
+  IRBuilder Builder2(BBStrict, FPMath);
+  EXPECT_TRUE(Builder2.getIsFPConstrained());
+
+  Value *V = Builder2.CreateLoad(GV->getValueType(), GV);
+  V = Builder2.CreateFAdd(V, V);
+  ASSERT_TRUE(isa<IntrinsicInst>(V));
+  auto *II = cast<IntrinsicInst>(V);
+
+  IRBuilder Builder3(II, FPMath);
+  EXPECT_TRUE(Builder3.getIsFPConstrained());
+
+  IRBuilder Builder4(BBStrict, BBStrict->back().getIterator(), Folder);
+  EXPECT_TRUE(Builder4.getIsFPConstrained());
+
+  IRBuilder Builder5(BBStrict, BBStrict->back().getIterator(), FPMath);
+  EXPECT_TRUE(Builder5.getIsFPConstrained());
+}
+
 TEST_F(IRBuilderTest, Lifetime) {
   IRBuilder<> Builder(BB);
   AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());

``````````

</details>


https://github.com/llvm/llvm-project/pull/98677


More information about the llvm-commits mailing list