[llvm] [FPEnv][IRBuilder] Set strictfp mode automatically when possible. (PR #98677)
Kevin P. Neal via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 16 05:22:43 PDT 2024
https://github.com/kpneal updated https://github.com/llvm/llvm-project/pull/98677
>From 9cbb67df36c6c887c4ee1621e15bf1f4da5e4b8b Mon Sep 17 00:00:00 2001
From: "Kevin P. Neal" <kevin.neal at sas.com>
Date: Fri, 12 Jul 2024 14:11:43 -0400
Subject: [PATCH 1/2] [FPEnv][IRBuilder] Set strictfp mode automatically when
possible.
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.
---
llvm/include/llvm/IR/IRBuilder.h | 20 +++++++++++++++
llvm/unittests/IR/IRBuilderTest.cpp | 40 +++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
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());
>From 17765ab618c0c5267d12b8e50ebe165aafe44f89 Mon Sep 17 00:00:00 2001
From: "Kevin P. Neal" <kevin.neal at sas.com>
Date: Tue, 16 Jul 2024 08:21:49 -0400
Subject: [PATCH 2/2] Fix clang-format warning from bot.
---
llvm/unittests/IR/IRBuilderTest.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index 215390334b0be..37b6e76bb436b 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -452,7 +452,8 @@ 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());
+ Function *FStrict =
+ Function::Create(FTy, Function::ExternalLinkage, "", M.get());
FStrict->addFnAttr(Attribute::StrictFP);
BasicBlock *BBStrict = BasicBlock::Create(Ctx, "", FStrict);
More information about the llvm-commits
mailing list