[llvm] [IRBuilder] Refactor FMF interface (PR #121657)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 5 01:11:54 PST 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/121657
>From 702b2c09b7952b0df46a975cc88aa19138d0e861 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 4 Jan 2025 22:55:51 +0800
Subject: [PATCH 1/2] [IRBuilder] Refactor FMF interface
---
llvm/include/llvm/IR/IRBuilder.h | 237 +++++++++---------
llvm/lib/IR/IRBuilder.cpp | 59 ++---
.../AArch64/AArch64TargetTransformInfo.cpp | 6 +-
.../AggressiveInstCombine.cpp | 8 +-
.../InstCombine/InstCombineAddSub.cpp | 19 +-
.../InstCombine/InstCombineAndOrXor.cpp | 37 ++-
.../InstCombine/InstCombineCasts.cpp | 16 +-
.../InstCombine/InstCombineMulDivRem.cpp | 34 +--
.../InstCombine/InstCombineSelect.cpp | 21 +-
llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 15 +-
.../lib/Transforms/Utils/SimplifyLibCalls.cpp | 52 ++--
.../lib/Transforms/Vectorize/VPlanRecipes.cpp | 7 +-
12 files changed, 229 insertions(+), 282 deletions(-)
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 8cdfa27ece9378..c1f15783fb7592 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -87,6 +87,20 @@ class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
}
};
+/// This provides a helper for copying FMF from an instruction or setting
+/// specified flags.
+struct FMFSource final {
+ Instruction *Source;
+ std::optional<FastMathFlags> FMF;
+
+ FMFSource() : Source(nullptr) {}
+ FMFSource(Instruction *Source) : Source(Source) {
+ if (Source)
+ FMF = Source->getFastMathFlags();
+ }
+ FMFSource(FastMathFlags FMF) : Source(nullptr), FMF(FMF) {}
+};
+
/// Common base class shared among various IRBuilders.
class IRBuilderBase {
/// Pairs of (metadata kind, MDNode *) that should be added to all newly
@@ -958,29 +972,27 @@ class IRBuilderBase {
/// Create a call to intrinsic \p ID with 1 operand which is mangled on its
/// type.
CallInst *CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
- Instruction *FMFSource = nullptr,
+ FMFSource FMFSource = {},
const Twine &Name = "");
/// Create a call to intrinsic \p ID with 2 operands which is mangled on the
/// first type.
Value *CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS,
- Instruction *FMFSource = nullptr,
+ FMFSource FMFSource = {},
const Twine &Name = "");
/// Create a call to intrinsic \p ID with \p Args, mangled using \p Types. If
/// \p FMFSource is provided, copy fast-math-flags from that instruction to
/// the intrinsic.
CallInst *CreateIntrinsic(Intrinsic::ID ID, ArrayRef<Type *> Types,
- ArrayRef<Value *> Args,
- Instruction *FMFSource = nullptr,
+ ArrayRef<Value *> Args, FMFSource FMFSource = {},
const Twine &Name = "");
/// Create a call to intrinsic \p ID with \p RetTy and \p Args. If
/// \p FMFSource is provided, copy fast-math-flags from that instruction to
/// the intrinsic.
CallInst *CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
- ArrayRef<Value *> Args,
- Instruction *FMFSource = nullptr,
+ ArrayRef<Value *> Args, FMFSource FMFSource = {},
const Twine &Name = "");
/// Create call to the minnum intrinsic.
@@ -1026,15 +1038,14 @@ class IRBuilderBase {
}
/// Create call to the copysign intrinsic.
- Value *CreateCopySign(Value *LHS, Value *RHS,
- Instruction *FMFSource = nullptr,
+ Value *CreateCopySign(Value *LHS, Value *RHS, FMFSource FMFSource = {},
const Twine &Name = "") {
return CreateBinaryIntrinsic(Intrinsic::copysign, LHS, RHS, FMFSource,
Name);
}
/// Create call to the ldexp intrinsic.
- Value *CreateLdexp(Value *Src, Value *Exp, Instruction *FMFSource = nullptr,
+ Value *CreateLdexp(Value *Src, Value *Exp, FMFSource FMFSource = {},
const Twine &Name = "") {
assert(!IsFPConstrained && "TODO: Support strictfp");
return CreateIntrinsic(Intrinsic::ldexp, {Src->getType(), Exp->getType()},
@@ -1555,144 +1566,113 @@ class IRBuilderBase {
Value *CreateFAdd(Value *L, Value *R, const Twine &Name = "",
MDNode *FPMD = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd,
- L, R, nullptr, Name, FPMD);
-
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FAdd, L, R, FMF))
- return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMF);
- return Insert(I, Name);
+ return CreateFAddFMF(L, R, {}, Name, FPMD);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFAddFMF(Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name = "") {
+ Value *CreateFAddFMF(Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMD = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd,
- L, R, FMFSource, Name);
+ L, R, FMFSource, Name, FPMD);
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FAdd, L, R, FMF))
+ if (Value *V = Folder.FoldBinOpFMF(Instruction::FAdd, L, R,
+ FMFSource.FMF.value_or(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), nullptr, FMF);
+ Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD,
+ FMFSource.FMF.value_or(FMF));
return Insert(I, Name);
}
Value *CreateFSub(Value *L, Value *R, const Twine &Name = "",
MDNode *FPMD = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub,
- L, R, nullptr, Name, FPMD);
-
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FSub, L, R, FMF))
- return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMF);
- return Insert(I, Name);
+ return CreateFSubFMF(L, R, {}, Name, FPMD);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFSubFMF(Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name = "") {
+ Value *CreateFSubFMF(Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMD = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub,
- L, R, FMFSource, Name);
+ L, R, FMFSource, Name, FPMD);
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FSub, L, R, FMF))
+ if (Value *V = Folder.FoldBinOpFMF(Instruction::FSub, L, R,
+ FMFSource.FMF.value_or(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), nullptr, FMF);
+ Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD,
+ FMFSource.FMF.value_or(FMF));
return Insert(I, Name);
}
Value *CreateFMul(Value *L, Value *R, const Twine &Name = "",
MDNode *FPMD = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul,
- L, R, nullptr, Name, FPMD);
-
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FMul, L, R, FMF))
- return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMF);
- return Insert(I, Name);
+ return CreateFMulFMF(L, R, {}, Name, FPMD);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFMulFMF(Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name = "") {
+ Value *CreateFMulFMF(Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMD = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul,
- L, R, FMFSource, Name);
+ L, R, FMFSource, Name, FPMD);
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FMul, L, R, FMF))
+ if (Value *V = Folder.FoldBinOpFMF(Instruction::FMul, L, R,
+ FMFSource.FMF.value_or(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), nullptr, FMF);
+ Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD,
+ FMFSource.FMF.value_or(FMF));
return Insert(I, Name);
}
Value *CreateFDiv(Value *L, Value *R, const Twine &Name = "",
MDNode *FPMD = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv,
- L, R, nullptr, Name, FPMD);
-
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FDiv, L, R, FMF))
- return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMF);
- return Insert(I, Name);
+ return CreateFDivFMF(L, R, {}, Name, FPMD);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFDivFMF(Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name = "") {
+ Value *CreateFDivFMF(Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMD = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv,
- L, R, FMFSource, Name);
+ L, R, FMFSource, Name, FPMD);
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FDiv, L, R, FMF))
+ if (Value *V = Folder.FoldBinOpFMF(Instruction::FDiv, L, R,
+ FMFSource.FMF.value_or(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), nullptr, FMF);
+ Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD,
+ FMFSource.FMF.value_or(FMF));
return Insert(I, Name);
}
Value *CreateFRem(Value *L, Value *R, const Twine &Name = "",
MDNode *FPMD = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem,
- L, R, nullptr, Name, FPMD);
-
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FRem, L, R, FMF)) return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMF);
- return Insert(I, Name);
+ return CreateFRemFMF(L, R, {}, Name, FPMD);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFRemFMF(Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name = "") {
+ Value *CreateFRemFMF(Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMD = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem,
- L, R, FMFSource, Name);
+ L, R, FMFSource, Name, FPMD);
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FRem, L, R, FMF)) return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), nullptr, FMF);
+ if (Value *V = Folder.FoldBinOpFMF(Instruction::FRem, L, R,
+ FMFSource.FMF.value_or(FMF)))
+ return V;
+ Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD,
+ FMFSource.FMF.value_or(FMF));
return Insert(I, Name);
}
Value *CreateBinOp(Instruction::BinaryOps Opc,
Value *LHS, Value *RHS, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
- if (Value *V = Folder.FoldBinOp(Opc, LHS, RHS)) return V;
+ return CreateBinOpFMF(Opc, LHS, RHS, {}, Name, FPMathTag);
+ }
+
+ Value *CreateBinOpFMF(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
+ FMFSource FMFSource, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ if (Value *V = Folder.FoldBinOp(Opc, LHS, RHS))
+ return V;
Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS);
if (isa<FPMathOperator>(BinOp))
- setFPAttrs(BinOp, FPMathTag, FMF);
+ setFPAttrs(BinOp, FPMathTag, FMFSource.FMF.value_or(FMF));
return Insert(BinOp, Name);
}
@@ -1731,13 +1711,13 @@ class IRBuilderBase {
}
CallInst *CreateConstrainedFPBinOp(
- Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr,
+ Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource = {},
const Twine &Name = "", MDNode *FPMathTag = nullptr,
std::optional<RoundingMode> Rounding = std::nullopt,
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
CallInst *CreateConstrainedFPUnroundedBinOp(
- Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr,
+ Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource = {},
const Twine &Name = "", MDNode *FPMathTag = nullptr,
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
@@ -1752,21 +1732,17 @@ class IRBuilderBase {
Value *CreateFNeg(Value *V, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
- if (Value *Res = Folder.FoldUnOpFMF(Instruction::FNeg, V, FMF))
- return Res;
- return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), FPMathTag, FMF),
- Name);
+ return CreateFNegFMF(V, {}, Name, FPMathTag);
}
- /// Copy fast-math-flags from an instruction rather than using the builder's
- /// default FMF.
- Value *CreateFNegFMF(Value *V, Instruction *FMFSource,
- const Twine &Name = "") {
- FastMathFlags FMF = FMFSource->getFastMathFlags();
- if (Value *Res = Folder.FoldUnOpFMF(Instruction::FNeg, V, FMF))
+ Value *CreateFNegFMF(Value *V, FMFSource FMFSource, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ if (Value *Res = Folder.FoldUnOpFMF(Instruction::FNeg, V,
+ FMFSource.FMF.value_or(FMF)))
return Res;
- return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), nullptr, FMF),
- Name);
+ return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), FPMathTag,
+ FMFSource.FMF.value_or(FMF)),
+ Name);
}
Value *CreateNot(Value *V, const Twine &Name = "") {
@@ -2127,19 +2103,31 @@ class IRBuilderBase {
Value *CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
+ return CreateFPTruncFMF(V, DestTy, {}, Name, FPMathTag);
+ }
+
+ Value *CreateFPTruncFMF(Value *V, Type *DestTy, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMathTag = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPCast(
- Intrinsic::experimental_constrained_fptrunc, V, DestTy, nullptr, Name,
- FPMathTag);
- return CreateCast(Instruction::FPTrunc, V, DestTy, Name, FPMathTag);
+ Intrinsic::experimental_constrained_fptrunc, V, DestTy, FMFSource,
+ Name, FPMathTag);
+ return CreateCast(Instruction::FPTrunc, V, DestTy, Name, FPMathTag,
+ FMFSource);
}
Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
+ return CreateFPExtFMF(V, DestTy, {}, Name, FPMathTag);
+ }
+
+ Value *CreateFPExtFMF(Value *V, Type *DestTy, FMFSource FMFSource,
+ const Twine &Name = "", MDNode *FPMathTag = nullptr) {
if (IsFPConstrained)
return CreateConstrainedFPCast(Intrinsic::experimental_constrained_fpext,
- V, DestTy, nullptr, Name, FPMathTag);
- return CreateCast(Instruction::FPExt, V, DestTy, Name, FPMathTag);
+ V, DestTy, FMFSource, Name, FPMathTag);
+ return CreateCast(Instruction::FPExt, V, DestTy, Name, FPMathTag,
+ FMFSource);
}
Value *CreatePtrToInt(Value *V, Type *DestTy,
@@ -2187,14 +2175,15 @@ class IRBuilderBase {
}
Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy,
- const Twine &Name = "", MDNode *FPMathTag = nullptr) {
+ const Twine &Name = "", MDNode *FPMathTag = nullptr,
+ FMFSource FMFSource = {}) {
if (V->getType() == DestTy)
return V;
if (Value *Folded = Folder.FoldCast(Op, V, DestTy))
return Folded;
Instruction *Cast = CastInst::Create(Op, V, DestTy);
if (isa<FPMathOperator>(Cast))
- setFPAttrs(Cast, FPMathTag, FMF);
+ setFPAttrs(Cast, FPMathTag, FMFSource.FMF.value_or(FMF));
return Insert(Cast, Name);
}
@@ -2255,9 +2244,8 @@ class IRBuilderBase {
}
CallInst *CreateConstrainedFPCast(
- Intrinsic::ID ID, Value *V, Type *DestTy,
- Instruction *FMFSource = nullptr, const Twine &Name = "",
- MDNode *FPMathTag = nullptr,
+ Intrinsic::ID ID, Value *V, Type *DestTy, FMFSource FMFSource = {},
+ const Twine &Name = "", MDNode *FPMathTag = nullptr,
std::optional<RoundingMode> Rounding = std::nullopt,
std::optional<fp::ExceptionBehavior> Except = std::nullopt);
@@ -2392,7 +2380,16 @@ class IRBuilderBase {
// Note that this differs from CreateFCmpS only if IsFPConstrained is true.
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, false);
+ return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, {}, false);
+ }
+
+ // Create a quiet floating-point comparison (i.e. one that raises an FP
+ // exception only in the case where an input is a signaling NaN).
+ // Note that this differs from CreateFCmpS only if IsFPConstrained is true.
+ Value *CreateFCmpFMF(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ FMFSource FMFSource, const Twine &Name = "",
+ MDNode *FPMathTag = nullptr) {
+ return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, FMFSource, false);
}
Value *CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
@@ -2407,14 +2404,14 @@ class IRBuilderBase {
// Note that this differs from CreateFCmp only if IsFPConstrained is true.
Value *CreateFCmpS(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, true);
+ return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, {}, true);
}
private:
// Helper routine to create either a signaling or a quiet FP comparison.
Value *CreateFCmpHelper(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name, MDNode *FPMathTag,
- bool IsSignaling);
+ FMFSource FMFSource, bool IsSignaling);
public:
CallInst *CreateConstrainedFPCmp(
@@ -2436,8 +2433,7 @@ class IRBuilderBase {
private:
CallInst *createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
- const Twine &Name = "",
- Instruction *FMFSource = nullptr,
+ const Twine &Name = "", FMFSource FMFSource = {},
ArrayRef<OperandBundleDef> OpBundles = {});
public:
@@ -2483,6 +2479,9 @@ class IRBuilderBase {
Value *CreateSelect(Value *C, Value *True, Value *False,
const Twine &Name = "", Instruction *MDFrom = nullptr);
+ Value *CreateSelectFMF(Value *C, Value *True, Value *False,
+ FMFSource FMFSource, const Twine &Name = "",
+ Instruction *MDFrom = nullptr);
VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
return Insert(new VAArgInst(List, Ty), Name);
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index f340f7aafdc76f..9bb4acfb96c750 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -78,11 +78,11 @@ void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
CallInst *
IRBuilderBase::createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
- const Twine &Name, Instruction *FMFSource,
+ const Twine &Name, FMFSource FMFSource,
ArrayRef<OperandBundleDef> OpBundles) {
CallInst *CI = CreateCall(Callee, Ops, OpBundles, Name);
- if (FMFSource)
- CI->copyFastMathFlags(FMFSource);
+ if (FMFSource.FMF.has_value())
+ CI->setFastMathFlags(*FMFSource.FMF);
return CI;
}
@@ -869,7 +869,7 @@ CallInst *IRBuilderBase::CreateGCGetPointerOffset(Value *DerivedPtr,
}
CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
- Instruction *FMFSource,
+ FMFSource FMFSource,
const Twine &Name) {
Module *M = BB->getModule();
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, {V->getType()});
@@ -877,12 +877,12 @@ CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
}
Value *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
- Value *RHS, Instruction *FMFSource,
+ Value *RHS, FMFSource FMFSource,
const Twine &Name) {
Module *M = BB->getModule();
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, {LHS->getType()});
if (Value *V = Folder.FoldBinaryIntrinsic(ID, LHS, RHS, Fn->getReturnType(),
- FMFSource))
+ FMFSource.Source))
return V;
return createCallHelper(Fn, {LHS, RHS}, Name, FMFSource);
}
@@ -890,7 +890,7 @@ Value *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
ArrayRef<Type *> Types,
ArrayRef<Value *> Args,
- Instruction *FMFSource,
+ FMFSource FMFSource,
const Twine &Name) {
Module *M = BB->getModule();
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, Types);
@@ -899,7 +899,7 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
ArrayRef<Value *> Args,
- Instruction *FMFSource,
+ FMFSource FMFSource,
const Twine &Name) {
Module *M = BB->getModule();
@@ -925,16 +925,13 @@ CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
}
CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
- Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
- const Twine &Name, MDNode *FPMathTag,
- std::optional<RoundingMode> Rounding,
+ Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource,
+ const Twine &Name, MDNode *FPMathTag, std::optional<RoundingMode> Rounding,
std::optional<fp::ExceptionBehavior> Except) {
Value *RoundingV = getConstrainedFPRounding(Rounding);
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMF;
- if (FMFSource)
- UseFMF = FMFSource->getFastMathFlags();
+ FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
CallInst *C = CreateIntrinsic(ID, {L->getType()},
{L, R, RoundingV, ExceptV}, nullptr, Name);
@@ -944,14 +941,12 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
}
CallInst *IRBuilderBase::CreateConstrainedFPUnroundedBinOp(
- Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
+ Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource,
const Twine &Name, MDNode *FPMathTag,
std::optional<fp::ExceptionBehavior> Except) {
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMF;
- if (FMFSource)
- UseFMF = FMFSource->getFastMathFlags();
+ FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
CallInst *C =
CreateIntrinsic(ID, {L->getType()}, {L, R, ExceptV}, nullptr, Name);
@@ -976,15 +971,12 @@ Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
}
CallInst *IRBuilderBase::CreateConstrainedFPCast(
- Intrinsic::ID ID, Value *V, Type *DestTy,
- Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag,
- std::optional<RoundingMode> Rounding,
+ Intrinsic::ID ID, Value *V, Type *DestTy, FMFSource FMFSource,
+ const Twine &Name, MDNode *FPMathTag, std::optional<RoundingMode> Rounding,
std::optional<fp::ExceptionBehavior> Except) {
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMF;
- if (FMFSource)
- UseFMF = FMFSource->getFastMathFlags();
+ FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
CallInst *C;
if (Intrinsic::hasConstrainedFPRoundingModeOperand(ID)) {
@@ -1002,9 +994,10 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast(
return C;
}
-Value *IRBuilderBase::CreateFCmpHelper(
- CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name,
- MDNode *FPMathTag, bool IsSignaling) {
+Value *IRBuilderBase::CreateFCmpHelper(CmpInst::Predicate P, Value *LHS,
+ Value *RHS, const Twine &Name,
+ MDNode *FPMathTag, FMFSource FMFSource,
+ bool IsSignaling) {
if (IsFPConstrained) {
auto ID = IsSignaling ? Intrinsic::experimental_constrained_fcmps
: Intrinsic::experimental_constrained_fcmp;
@@ -1013,7 +1006,9 @@ Value *IRBuilderBase::CreateFCmpHelper(
if (auto *V = Folder.FoldCmp(P, LHS, RHS))
return V;
- return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
+ return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag,
+ FMFSource.FMF.value_or(FMF)),
+ Name);
}
CallInst *IRBuilderBase::CreateConstrainedFPCmp(
@@ -1047,6 +1042,12 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall(
Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
const Twine &Name, Instruction *MDFrom) {
+ return CreateSelectFMF(C, True, False, {}, Name, MDFrom);
+}
+
+Value *IRBuilderBase::CreateSelectFMF(Value *C, Value *True, Value *False,
+ FMFSource FMFSource, const Twine &Name,
+ Instruction *MDFrom) {
if (auto *V = Folder.FoldSelect(C, True, False))
return V;
@@ -1057,7 +1058,7 @@ Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
Sel = addBranchMetadata(Sel, Prof, Unpred);
}
if (isa<FPMathOperator>(Sel))
- setFPAttrs(Sel, nullptr /* MDNode* */, FMF);
+ setFPAttrs(Sel, /*MDNode=*/nullptr, FMFSource.FMF.value_or(FMF));
return Insert(Sel, Name);
}
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 515764c915bf4a..7c5e5336b65313 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -1638,10 +1638,8 @@ instCombineSVEVectorBinOp(InstCombiner &IC, IntrinsicInst &II) {
!match(OpPredicate, m_Intrinsic<Intrinsic::aarch64_sve_ptrue>(
m_ConstantInt<AArch64SVEPredPattern::all>())))
return std::nullopt;
- IRBuilderBase::FastMathFlagGuard FMFGuard(IC.Builder);
- IC.Builder.setFastMathFlags(II.getFastMathFlags());
- auto BinOp =
- IC.Builder.CreateBinOp(BinOpCode, II.getOperand(1), II.getOperand(2));
+ auto BinOp = IC.Builder.CreateBinOpFMF(
+ BinOpCode, II.getOperand(1), II.getOperand(2), II.getFastMathFlags());
return IC.replaceInstUsesWith(II, BinOp);
}
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 12ae6740e055ef..d45aee37801736 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -425,11 +425,9 @@ static bool foldSqrt(CallInst *Call, LibFunc Func, TargetTransformInfo &TTI,
Arg, 0,
SimplifyQuery(Call->getDataLayout(), &TLI, &DT, &AC, Call)))) {
IRBuilder<> Builder(Call);
- IRBuilderBase::FastMathFlagGuard Guard(Builder);
- Builder.setFastMathFlags(Call->getFastMathFlags());
-
- Value *NewSqrt = Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
- /*FMFSource=*/nullptr, "sqrt");
+ Value *NewSqrt =
+ Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
+ /*FMFSource=*/Call->getFastMathFlags(), "sqrt");
Call->replaceAllUsesWith(NewSqrt);
// Explicitly erase the old call because a call with side effects is not
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 7a184a19d7c54a..9dc593bdf3058f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2845,12 +2845,11 @@ Instruction *InstCombinerImpl::hoistFNegAboveFMulFDiv(Value *FNegOp,
// Make sure to preserve flags and metadata on the call.
if (II->getIntrinsicID() == Intrinsic::ldexp) {
FastMathFlags FMF = FMFSource.getFastMathFlags() | II->getFastMathFlags();
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(FMF);
-
- CallInst *New = Builder.CreateCall(
- II->getCalledFunction(),
- {Builder.CreateFNeg(II->getArgOperand(0)), II->getArgOperand(1)});
+ CallInst *New =
+ Builder.CreateCall(II->getCalledFunction(),
+ {Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
+ II->getArgOperand(1)});
+ New->setFastMathFlags(FMF);
New->copyMetadata(*II);
return New;
}
@@ -2932,12 +2931,8 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
// flags the copysign doesn't also have.
FastMathFlags FMF = I.getFastMathFlags();
FMF &= cast<FPMathOperator>(OneUse)->getFastMathFlags();
-
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(FMF);
-
- Value *NegY = Builder.CreateFNeg(Y);
- Value *NewCopySign = Builder.CreateCopySign(X, NegY);
+ Value *NegY = Builder.CreateFNegFMF(Y, FMF);
+ Value *NewCopySign = Builder.CreateCopySign(X, NegY, FMF);
return replaceInstUsesWith(I, NewCopySign);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index e576eea4ca36a1..37a7c4d88b234d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -39,11 +39,12 @@ static Value *getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS,
/// This is the complement of getFCmpCode, which turns an opcode and two
/// operands into either a FCmp instruction, or a true/false constant.
static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS,
- InstCombiner::BuilderTy &Builder) {
+ InstCombiner::BuilderTy &Builder,
+ FastMathFlags FMF) {
FCmpInst::Predicate NewPred;
if (Constant *TorF = getPredForFCmpCode(Code, LHS->getType(), NewPred))
return TorF;
- return Builder.CreateFCmp(NewPred, LHS, RHS);
+ return Builder.CreateFCmpFMF(NewPred, LHS, RHS, FMF);
}
/// Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise
@@ -1429,12 +1430,9 @@ static Value *matchIsFiniteTest(InstCombiner::BuilderTy &Builder, FCmpInst *LHS,
!matchUnorderedInfCompare(PredR, RHS0, RHS1))
return nullptr;
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
- FastMathFlags FMF = LHS->getFastMathFlags();
- FMF &= RHS->getFastMathFlags();
- Builder.setFastMathFlags(FMF);
-
- return Builder.CreateFCmp(FCmpInst::getOrderedPredicate(PredR), RHS0, RHS1);
+ return Builder.CreateFCmpFMF(FCmpInst::getOrderedPredicate(PredR), RHS0, RHS1,
+ LHS->getFastMathFlags() &
+ RHS->getFastMathFlags());
}
Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
@@ -1470,12 +1468,8 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
// Intersect the fast math flags.
// TODO: We can union the fast math flags unless this is a logical select.
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
- FastMathFlags FMF = LHS->getFastMathFlags();
- FMF &= RHS->getFastMathFlags();
- Builder.setFastMathFlags(FMF);
-
- return getFCmpValue(NewPred, LHS0, LHS1, Builder);
+ return getFCmpValue(NewPred, LHS0, LHS1, Builder,
+ LHS->getFastMathFlags() & RHS->getFastMathFlags());
}
// This transform is not valid for a logical select.
@@ -1492,10 +1486,8 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
// Ignore the constants because they are obviously not NANs:
// (fcmp ord x, 0.0) & (fcmp ord y, 0.0) -> (fcmp ord x, y)
// (fcmp uno x, 0.0) | (fcmp uno y, 0.0) -> (fcmp uno x, y)
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
- Builder.setFastMathFlags(LHS->getFastMathFlags() &
- RHS->getFastMathFlags());
- return Builder.CreateFCmp(PredL, LHS0, RHS0);
+ return Builder.CreateFCmpFMF(
+ PredL, LHS0, RHS0, LHS->getFastMathFlags() & RHS->getFastMathFlags());
}
}
@@ -1557,15 +1549,14 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
std::swap(PredL, PredR);
}
if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
- BuilderTy::FastMathFlagGuard Guard(Builder);
FastMathFlags NewFlag = LHS->getFastMathFlags();
if (!IsLogicalSelect)
NewFlag |= RHS->getFastMathFlags();
- Builder.setFastMathFlags(NewFlag);
- Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0);
- return Builder.CreateFCmp(PredL, FAbs,
- ConstantFP::get(LHS0->getType(), *LHSC));
+ Value *FAbs =
+ Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0, NewFlag);
+ return Builder.CreateFCmpFMF(
+ PredL, FAbs, ConstantFP::get(LHS0->getType(), *LHSC), NewFlag);
}
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 0b9379965f4249..4ec1af394464bb 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1852,15 +1852,13 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
Value *X;
Instruction *Op = dyn_cast<Instruction>(FPT.getOperand(0));
if (Op && Op->hasOneUse()) {
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
FastMathFlags FMF = FPT.getFastMathFlags();
if (auto *FPMO = dyn_cast<FPMathOperator>(Op))
FMF &= FPMO->getFastMathFlags();
- Builder.setFastMathFlags(FMF);
if (match(Op, m_FNeg(m_Value(X)))) {
- Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty);
- Value *Neg = Builder.CreateFNeg(InnerTrunc);
+ Value *InnerTrunc = Builder.CreateFPTruncFMF(X, Ty, FMF);
+ Value *Neg = Builder.CreateFNegFMF(InnerTrunc, FMF);
return replaceInstUsesWith(FPT, Neg);
}
@@ -1870,15 +1868,17 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X)), m_Value(Y))) &&
X->getType() == Ty) {
// fptrunc (select Cond, (fpext X), Y --> select Cond, X, (fptrunc Y)
- Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
- Value *Sel = Builder.CreateSelect(Cond, X, NarrowY, "narrow.sel", Op);
+ Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
+ Value *Sel =
+ Builder.CreateSelectFMF(Cond, X, NarrowY, FMF, "narrow.sel", Op);
return replaceInstUsesWith(FPT, Sel);
}
if (match(Op, m_Select(m_Value(Cond), m_Value(Y), m_FPExt(m_Value(X)))) &&
X->getType() == Ty) {
// fptrunc (select Cond, Y, (fpext X) --> select Cond, (fptrunc Y), X
- Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
- Value *Sel = Builder.CreateSelect(Cond, NarrowY, X, "narrow.sel", Op);
+ Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
+ Value *Sel =
+ Builder.CreateSelectFMF(Cond, NarrowY, X, FMF, "narrow.sel", Op);
return replaceInstUsesWith(FPT, Sel);
}
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index f85a3c93651353..e376376c3ce282 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -121,21 +121,17 @@ static Value *foldMulSelectToNegate(BinaryOperator &I,
// fmul OtherOp, (select Cond, 1.0, -1.0) --> select Cond, OtherOp, -OtherOp
if (match(&I, m_c_FMul(m_OneUse(m_Select(m_Value(Cond), m_SpecificFP(1.0),
m_SpecificFP(-1.0))),
- m_Value(OtherOp)))) {
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(I.getFastMathFlags());
- return Builder.CreateSelect(Cond, OtherOp, Builder.CreateFNeg(OtherOp));
- }
+ m_Value(OtherOp))))
+ return Builder.CreateSelectFMF(Cond, OtherOp,
+ Builder.CreateFNegFMF(OtherOp, &I), &I);
// fmul (select Cond, -1.0, 1.0), OtherOp --> select Cond, -OtherOp, OtherOp
// fmul OtherOp, (select Cond, -1.0, 1.0) --> select Cond, -OtherOp, OtherOp
if (match(&I, m_c_FMul(m_OneUse(m_Select(m_Value(Cond), m_SpecificFP(-1.0),
m_SpecificFP(1.0))),
- m_Value(OtherOp)))) {
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(I.getFastMathFlags());
- return Builder.CreateSelect(Cond, Builder.CreateFNeg(OtherOp), OtherOp);
- }
+ m_Value(OtherOp))))
+ return Builder.CreateSelectFMF(Cond, Builder.CreateFNegFMF(OtherOp, &I),
+ OtherOp, &I);
return nullptr;
}
@@ -590,11 +586,9 @@ Instruction *InstCombinerImpl::foldFPSignBitOps(BinaryOperator &I) {
// fabs(X) / fabs(Y) --> fabs(X / Y)
if (match(Op0, m_FAbs(m_Value(X))) && match(Op1, m_FAbs(m_Value(Y))) &&
(Op0->hasOneUse() || Op1->hasOneUse())) {
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(I.getFastMathFlags());
- Value *XY = Builder.CreateBinOp(Opcode, X, Y);
- Value *Fabs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, XY);
- Fabs->takeName(&I);
+ Value *XY = Builder.CreateBinOpFMF(Opcode, X, Y, &I);
+ Value *Fabs =
+ Builder.CreateUnaryIntrinsic(Intrinsic::fabs, XY, &I, I.getName());
return replaceInstUsesWith(I, Fabs);
}
@@ -685,8 +679,6 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
match(Op0, m_AllowReassoc(m_BinOp(Op0BinOp)))) {
// Everything in this scope folds I with Op0, intersecting their FMF.
FastMathFlags FMF = I.getFastMathFlags() & Op0BinOp->getFastMathFlags();
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(FMF);
Constant *C1;
if (match(Op0, m_OneUse(m_FDiv(m_Constant(C1), m_Value(X))))) {
// (C1 / X) * C --> (C * C1) / X
@@ -718,7 +710,7 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
// (X + C1) * C --> (X * C) + (C * C1)
if (Constant *CC1 =
ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL)) {
- Value *XC = Builder.CreateFMul(X, C);
+ Value *XC = Builder.CreateFMulFMF(X, C, FMF);
return BinaryOperator::CreateFAddFMF(XC, CC1, FMF);
}
}
@@ -726,7 +718,7 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
// (C1 - X) * C --> (C * C1) - (X * C)
if (Constant *CC1 =
ConstantFoldBinaryOpOperands(Instruction::FMul, C, C1, DL)) {
- Value *XC = Builder.CreateFMul(X, C);
+ Value *XC = Builder.CreateFMulFMF(X, C, FMF);
return BinaryOperator::CreateFSubFMF(CC1, XC, FMF);
}
}
@@ -740,9 +732,7 @@ Instruction *InstCombinerImpl::foldFMulReassoc(BinaryOperator &I) {
FastMathFlags FMF = I.getFastMathFlags() & DivOp->getFastMathFlags();
if (FMF.allowReassoc()) {
// Sink division: (X / Y) * Z --> (X * Z) / Y
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- Builder.setFastMathFlags(FMF);
- auto *NewFMul = Builder.CreateFMul(X, Z);
+ auto *NewFMul = Builder.CreateFMulFMF(X, Z, FMF);
return BinaryOperator::CreateFDivFMF(NewFMul, Y, FMF);
}
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e7a8e947705f8d..042542ea3c0f11 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3910,12 +3910,11 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
// (X ugt Y) ? X : Y -> (X ole Y) ? Y : X
if (FCmp->hasOneUse() && FCmpInst::isUnordered(Pred)) {
FCmpInst::Predicate InvPred = FCmp->getInversePredicate();
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
// FIXME: The FMF should propagate from the select, not the fcmp.
- Builder.setFastMathFlags(FCmp->getFastMathFlags());
- Value *NewCond = Builder.CreateFCmp(InvPred, Cmp0, Cmp1,
- FCmp->getName() + ".inv");
- Value *NewSel = Builder.CreateSelect(NewCond, FalseVal, TrueVal);
+ Value *NewCond = Builder.CreateFCmpFMF(InvPred, Cmp0, Cmp1, FCmp,
+ FCmp->getName() + ".inv");
+ Value *NewSel =
+ Builder.CreateSelectFMF(NewCond, FalseVal, TrueVal, FCmp);
return replaceInstUsesWith(SI, NewSel);
}
}
@@ -4080,15 +4079,11 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
CmpInst::Predicate MinMaxPred = getMinMaxPred(SPF, SPR.Ordered);
Value *Cmp;
- if (CmpInst::isIntPredicate(MinMaxPred)) {
+ if (CmpInst::isIntPredicate(MinMaxPred))
Cmp = Builder.CreateICmp(MinMaxPred, LHS, RHS);
- } else {
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
- auto FMF =
- cast<FPMathOperator>(SI.getCondition())->getFastMathFlags();
- Builder.setFastMathFlags(FMF);
- Cmp = Builder.CreateFCmp(MinMaxPred, LHS, RHS);
- }
+ else
+ Cmp = Builder.CreateFCmpFMF(MinMaxPred, LHS, RHS,
+ cast<Instruction>(SI.getCondition()));
Value *NewSI = Builder.CreateSelect(Cmp, LHS, RHS, SI.getName(), &SI);
if (!IsCastNeeded)
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index febc5682c21295..03dc6c1d17446d 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2153,12 +2153,9 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(
SelectInst *&SI = InsertedSelects[std::make_pair(BB1V, BB2V)];
if (!SI) {
// Propagate fast-math-flags from phi node to its replacement select.
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
- if (isa<FPMathOperator>(PN))
- Builder.setFastMathFlags(PN.getFastMathFlags());
-
- SI = cast<SelectInst>(Builder.CreateSelect(
+ SI = cast<SelectInst>(Builder.CreateSelectFMF(
BI->getCondition(), BB1V, BB2V,
+ isa<FPMathOperator>(PN) ? &PN : nullptr,
BB1V->getName() + "." + BB2V->getName(), BI));
}
@@ -3898,16 +3895,14 @@ static bool foldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
IRBuilder<NoFolder> Builder(DomBI);
// Propagate fast-math-flags from phi nodes to replacement selects.
- IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
while (PHINode *PN = dyn_cast<PHINode>(BB->begin())) {
- if (isa<FPMathOperator>(PN))
- Builder.setFastMathFlags(PN->getFastMathFlags());
-
// Change the PHI node into a select instruction.
Value *TrueVal = PN->getIncomingValueForBlock(IfTrue);
Value *FalseVal = PN->getIncomingValueForBlock(IfFalse);
- Value *Sel = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
+ Value *Sel = Builder.CreateSelectFMF(IfCond, TrueVal, FalseVal,
+ isa<FPMathOperator>(PN) ? PN : nullptr,
+ "", DomBI);
PN->replaceAllUsesWith(Sel);
Sel->takeName(PN);
PN->eraseFromParent();
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 737818b7825cf4..2b2b4670714b68 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2005,28 +2005,21 @@ Value *LibCallSimplifier::optimizeCAbs(CallInst *CI, IRBuilderBase &B) {
AbsOp = Real;
}
- if (AbsOp) {
- IRBuilderBase::FastMathFlagGuard Guard(B);
- B.setFastMathFlags(CI->getFastMathFlags());
-
+ if (AbsOp)
return copyFlags(
- *CI, B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp, nullptr, "cabs"));
- }
+ *CI, B.CreateUnaryIntrinsic(Intrinsic::fabs, AbsOp, CI, "cabs"));
if (!CI->isFast())
return nullptr;
}
// Propagate fast-math flags from the existing call to new instructions.
- IRBuilderBase::FastMathFlagGuard Guard(B);
- B.setFastMathFlags(CI->getFastMathFlags());
-
- Value *RealReal = B.CreateFMul(Real, Real);
- Value *ImagImag = B.CreateFMul(Imag, Imag);
-
- return copyFlags(*CI, B.CreateUnaryIntrinsic(Intrinsic::sqrt,
- B.CreateFAdd(RealReal, ImagImag),
- nullptr, "cabs"));
+ Value *RealReal = B.CreateFMulFMF(Real, Real, CI);
+ Value *ImagImag = B.CreateFMulFMF(Imag, Imag, CI);
+ return copyFlags(
+ *CI, B.CreateUnaryIntrinsic(Intrinsic::sqrt,
+ B.CreateFAddFMF(RealReal, ImagImag, CI), CI,
+ "cabs"));
}
// Return a properly extended integer (DstWidth bits wide) if the operation is
@@ -2480,15 +2473,13 @@ Value *LibCallSimplifier::optimizeFMinFMax(CallInst *CI, IRBuilderBase &B) {
// "Ideally, fmax would be sensitive to the sign of zero, for example
// fmax(-0.0, +0.0) would return +0; however, implementation in software
// might be impractical."
- IRBuilderBase::FastMathFlagGuard Guard(B);
FastMathFlags FMF = CI->getFastMathFlags();
FMF.setNoSignedZeros();
- B.setFastMathFlags(FMF);
Intrinsic::ID IID = Callee->getName().starts_with("fmin") ? Intrinsic::minnum
: Intrinsic::maxnum;
return copyFlags(*CI, B.CreateBinaryIntrinsic(IID, CI->getArgOperand(0),
- CI->getArgOperand(1)));
+ CI->getArgOperand(1), FMF));
}
Value *LibCallSimplifier::optimizeLog(CallInst *Log, IRBuilderBase &B) {
@@ -2783,20 +2774,18 @@ Value *LibCallSimplifier::optimizeSqrt(CallInst *CI, IRBuilderBase &B) {
// Fast math flags for any created instructions should match the sqrt
// and multiply.
- IRBuilderBase::FastMathFlagGuard Guard(B);
- B.setFastMathFlags(I->getFastMathFlags());
// If we found a repeated factor, hoist it out of the square root and
// replace it with the fabs of that factor.
Value *FabsCall =
- B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp, nullptr, "fabs");
+ B.CreateUnaryIntrinsic(Intrinsic::fabs, RepeatOp, I, "fabs");
if (OtherOp) {
// If we found a non-repeated factor, we still need to get its square
// root. We then multiply that by the value that was simplified out
// of the square root calculation.
Value *SqrtCall =
- B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp, nullptr, "sqrt");
- return copyFlags(*CI, B.CreateFMul(FabsCall, SqrtCall));
+ B.CreateUnaryIntrinsic(Intrinsic::sqrt, OtherOp, I, "sqrt");
+ return copyFlags(*CI, B.CreateFMulFMF(FabsCall, SqrtCall, I));
}
return copyFlags(*CI, FabsCall);
}
@@ -2951,26 +2940,23 @@ static Value *optimizeSymmetricCall(CallInst *CI, bool IsEven,
Value *Src = CI->getArgOperand(0);
if (match(Src, m_OneUse(m_FNeg(m_Value(X))))) {
- IRBuilderBase::FastMathFlagGuard Guard(B);
- B.setFastMathFlags(CI->getFastMathFlags());
-
- auto *CallInst = copyFlags(*CI, B.CreateCall(CI->getCalledFunction(), {X}));
+ auto *Call = B.CreateCall(CI->getCalledFunction(), {X});
+ Call->copyFastMathFlags(CI);
+ auto *CallInst = copyFlags(*CI, Call);
if (IsEven) {
// Even function: f(-x) = f(x)
return CallInst;
}
// Odd function: f(-x) = -f(x)
- return B.CreateFNeg(CallInst);
+ return B.CreateFNegFMF(CallInst, CI);
}
// Even function: f(abs(x)) = f(x), f(copysign(x, y)) = f(x)
if (IsEven && (match(Src, m_FAbs(m_Value(X))) ||
match(Src, m_CopySign(m_Value(X), m_Value())))) {
- IRBuilderBase::FastMathFlagGuard Guard(B);
- B.setFastMathFlags(CI->getFastMathFlags());
-
- auto *CallInst = copyFlags(*CI, B.CreateCall(CI->getCalledFunction(), {X}));
- return CallInst;
+ auto *Call = B.CreateCall(CI->getCalledFunction(), {X});
+ Call->copyFastMathFlags(CI);
+ return copyFlags(*CI, Call);
}
return nullptr;
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 77c08839dbfa95..ec586fa47fe1d2 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -1352,10 +1352,9 @@ void VPWidenRecipe::execute(VPTransformState &State) {
Value *C = nullptr;
if (FCmp) {
// Propagate fast math flags.
- IRBuilder<>::FastMathFlagGuard FMFG(Builder);
- if (auto *I = dyn_cast_or_null<Instruction>(getUnderlyingValue()))
- Builder.setFastMathFlags(I->getFastMathFlags());
- C = Builder.CreateFCmp(getPredicate(), A, B);
+ C = Builder.CreateFCmpFMF(
+ getPredicate(), A, B,
+ dyn_cast_or_null<Instruction>(getUnderlyingValue()));
} else {
C = Builder.CreateICmp(getPredicate(), A, B);
}
>From 9397e712f6010be15ccf62f12740e9b4a67de2f4 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 5 Jan 2025 16:52:24 +0800
Subject: [PATCH 2/2] [IRBuilder] Remove source inst
---
llvm/include/llvm/IR/IRBuilder.h | 67 +++++++++++++++++---------------
llvm/lib/IR/IRBuilder.cpp | 20 +++++-----
2 files changed, 45 insertions(+), 42 deletions(-)
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index c1f15783fb7592..b73309175f20d1 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -89,16 +89,19 @@ class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
/// This provides a helper for copying FMF from an instruction or setting
/// specified flags.
-struct FMFSource final {
- Instruction *Source;
+class FMFSource {
std::optional<FastMathFlags> FMF;
- FMFSource() : Source(nullptr) {}
- FMFSource(Instruction *Source) : Source(Source) {
+public:
+ FMFSource() = default;
+ FMFSource(Instruction *Source) {
if (Source)
FMF = Source->getFastMathFlags();
}
- FMFSource(FastMathFlags FMF) : Source(nullptr), FMF(FMF) {}
+ FMFSource(FastMathFlags FMF) : FMF(FMF) {}
+ FastMathFlags get(FastMathFlags Default) const {
+ return FMF.value_or(Default);
+ }
};
/// Common base class shared among various IRBuilders.
@@ -1575,11 +1578,11 @@ class IRBuilderBase {
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fadd,
L, R, FMFSource, Name, FPMD);
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FAdd, L, R,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *V =
+ Folder.FoldBinOpFMF(Instruction::FAdd, L, R, FMFSource.get(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD,
- FMFSource.FMF.value_or(FMF));
+ Instruction *I =
+ setFPAttrs(BinaryOperator::CreateFAdd(L, R), FPMD, FMFSource.get(FMF));
return Insert(I, Name);
}
@@ -1594,11 +1597,11 @@ class IRBuilderBase {
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fsub,
L, R, FMFSource, Name, FPMD);
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FSub, L, R,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *V =
+ Folder.FoldBinOpFMF(Instruction::FSub, L, R, FMFSource.get(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD,
- FMFSource.FMF.value_or(FMF));
+ Instruction *I =
+ setFPAttrs(BinaryOperator::CreateFSub(L, R), FPMD, FMFSource.get(FMF));
return Insert(I, Name);
}
@@ -1613,11 +1616,11 @@ class IRBuilderBase {
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fmul,
L, R, FMFSource, Name, FPMD);
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FMul, L, R,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *V =
+ Folder.FoldBinOpFMF(Instruction::FMul, L, R, FMFSource.get(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD,
- FMFSource.FMF.value_or(FMF));
+ Instruction *I =
+ setFPAttrs(BinaryOperator::CreateFMul(L, R), FPMD, FMFSource.get(FMF));
return Insert(I, Name);
}
@@ -1632,11 +1635,11 @@ class IRBuilderBase {
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_fdiv,
L, R, FMFSource, Name, FPMD);
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FDiv, L, R,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *V =
+ Folder.FoldBinOpFMF(Instruction::FDiv, L, R, FMFSource.get(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD,
- FMFSource.FMF.value_or(FMF));
+ Instruction *I =
+ setFPAttrs(BinaryOperator::CreateFDiv(L, R), FPMD, FMFSource.get(FMF));
return Insert(I, Name);
}
@@ -1651,11 +1654,11 @@ class IRBuilderBase {
return CreateConstrainedFPBinOp(Intrinsic::experimental_constrained_frem,
L, R, FMFSource, Name, FPMD);
- if (Value *V = Folder.FoldBinOpFMF(Instruction::FRem, L, R,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *V =
+ Folder.FoldBinOpFMF(Instruction::FRem, L, R, FMFSource.get(FMF)))
return V;
- Instruction *I = setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD,
- FMFSource.FMF.value_or(FMF));
+ Instruction *I =
+ setFPAttrs(BinaryOperator::CreateFRem(L, R), FPMD, FMFSource.get(FMF));
return Insert(I, Name);
}
@@ -1672,7 +1675,7 @@ class IRBuilderBase {
return V;
Instruction *BinOp = BinaryOperator::Create(Opc, LHS, RHS);
if (isa<FPMathOperator>(BinOp))
- setFPAttrs(BinOp, FPMathTag, FMFSource.FMF.value_or(FMF));
+ setFPAttrs(BinOp, FPMathTag, FMFSource.get(FMF));
return Insert(BinOp, Name);
}
@@ -1737,12 +1740,12 @@ class IRBuilderBase {
Value *CreateFNegFMF(Value *V, FMFSource FMFSource, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
- if (Value *Res = Folder.FoldUnOpFMF(Instruction::FNeg, V,
- FMFSource.FMF.value_or(FMF)))
+ if (Value *Res =
+ Folder.FoldUnOpFMF(Instruction::FNeg, V, FMFSource.get(FMF)))
return Res;
- return Insert(setFPAttrs(UnaryOperator::CreateFNeg(V), FPMathTag,
- FMFSource.FMF.value_or(FMF)),
- Name);
+ return Insert(
+ setFPAttrs(UnaryOperator::CreateFNeg(V), FPMathTag, FMFSource.get(FMF)),
+ Name);
}
Value *CreateNot(Value *V, const Twine &Name = "") {
@@ -2183,7 +2186,7 @@ class IRBuilderBase {
return Folded;
Instruction *Cast = CastInst::Create(Op, V, DestTy);
if (isa<FPMathOperator>(Cast))
- setFPAttrs(Cast, FPMathTag, FMFSource.FMF.value_or(FMF));
+ setFPAttrs(Cast, FPMathTag, FMFSource.get(FMF));
return Insert(Cast, Name);
}
diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp
index 9bb4acfb96c750..27b499e42a4e4c 100644
--- a/llvm/lib/IR/IRBuilder.cpp
+++ b/llvm/lib/IR/IRBuilder.cpp
@@ -81,8 +81,8 @@ IRBuilderBase::createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
const Twine &Name, FMFSource FMFSource,
ArrayRef<OperandBundleDef> OpBundles) {
CallInst *CI = CreateCall(Callee, Ops, OpBundles, Name);
- if (FMFSource.FMF.has_value())
- CI->setFastMathFlags(*FMFSource.FMF);
+ if (isa<FPMathOperator>(CI))
+ CI->setFastMathFlags(FMFSource.get(FMF));
return CI;
}
@@ -882,7 +882,7 @@ Value *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
Module *M = BB->getModule();
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, {LHS->getType()});
if (Value *V = Folder.FoldBinaryIntrinsic(ID, LHS, RHS, Fn->getReturnType(),
- FMFSource.Source))
+ /*FMFSource=*/nullptr))
return V;
return createCallHelper(Fn, {LHS, RHS}, Name, FMFSource);
}
@@ -931,7 +931,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
Value *RoundingV = getConstrainedFPRounding(Rounding);
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
+ FastMathFlags UseFMF = FMFSource.get(FMF);
CallInst *C = CreateIntrinsic(ID, {L->getType()},
{L, R, RoundingV, ExceptV}, nullptr, Name);
@@ -946,7 +946,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPUnroundedBinOp(
std::optional<fp::ExceptionBehavior> Except) {
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
+ FastMathFlags UseFMF = FMFSource.get(FMF);
CallInst *C =
CreateIntrinsic(ID, {L->getType()}, {L, R, ExceptV}, nullptr, Name);
@@ -976,7 +976,7 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast(
std::optional<fp::ExceptionBehavior> Except) {
Value *ExceptV = getConstrainedFPExcept(Except);
- FastMathFlags UseFMF = FMFSource.FMF.value_or(FMF);
+ FastMathFlags UseFMF = FMFSource.get(FMF);
CallInst *C;
if (Intrinsic::hasConstrainedFPRoundingModeOperand(ID)) {
@@ -1006,9 +1006,9 @@ Value *IRBuilderBase::CreateFCmpHelper(CmpInst::Predicate P, Value *LHS,
if (auto *V = Folder.FoldCmp(P, LHS, RHS))
return V;
- return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag,
- FMFSource.FMF.value_or(FMF)),
- Name);
+ return Insert(
+ setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMFSource.get(FMF)),
+ Name);
}
CallInst *IRBuilderBase::CreateConstrainedFPCmp(
@@ -1058,7 +1058,7 @@ Value *IRBuilderBase::CreateSelectFMF(Value *C, Value *True, Value *False,
Sel = addBranchMetadata(Sel, Prof, Unpred);
}
if (isa<FPMathOperator>(Sel))
- setFPAttrs(Sel, /*MDNode=*/nullptr, FMFSource.FMF.value_or(FMF));
+ setFPAttrs(Sel, /*MDNode=*/nullptr, FMFSource.get(FMF));
return Insert(Sel, Name);
}
More information about the llvm-commits
mailing list