Skip to content

Commit a77346b

Browse files
authored
[IRBuilder] Refactor FMF interface (#121657)
Up to now, the only way to set specified FMF flags in IRBuilder is to use `FastMathFlagGuard`. It makes the code ugly and hard to maintain. This patch introduces a helper class `FMFSource` to replace the original parameter `Instruction *FMFSource` in IRBuilder. To maximize the compatibility, it accepts an instruction or a specified FMF. This patch also removes the use of `FastMathFlagGuard` in some simple cases. Compile-time impact: https://llvm-compile-time-tracker.com/compare.php?from=f87a9db8322643ccbc324e317a75b55903129b55&to=9397e712f6010be15ccf62f12740e9b4a67de2f4&stat=instructions%3Au
1 parent 483832b commit a77346b

File tree

12 files changed

+231
-282
lines changed

12 files changed

+231
-282
lines changed

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 121 additions & 119 deletions
Large diffs are not rendered by default.

llvm/lib/IR/IRBuilder.cpp

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
7878

7979
CallInst *
8080
IRBuilderBase::createCallHelper(Function *Callee, ArrayRef<Value *> Ops,
81-
const Twine &Name, Instruction *FMFSource,
81+
const Twine &Name, FMFSource FMFSource,
8282
ArrayRef<OperandBundleDef> OpBundles) {
8383
CallInst *CI = CreateCall(Callee, Ops, OpBundles, Name);
84-
if (FMFSource)
85-
CI->copyFastMathFlags(FMFSource);
84+
if (isa<FPMathOperator>(CI))
85+
CI->setFastMathFlags(FMFSource.get(FMF));
8686
return CI;
8787
}
8888

@@ -869,28 +869,28 @@ CallInst *IRBuilderBase::CreateGCGetPointerOffset(Value *DerivedPtr,
869869
}
870870

871871
CallInst *IRBuilderBase::CreateUnaryIntrinsic(Intrinsic::ID ID, Value *V,
872-
Instruction *FMFSource,
872+
FMFSource FMFSource,
873873
const Twine &Name) {
874874
Module *M = BB->getModule();
875875
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, {V->getType()});
876876
return createCallHelper(Fn, {V}, Name, FMFSource);
877877
}
878878

879879
Value *IRBuilderBase::CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS,
880-
Value *RHS, Instruction *FMFSource,
880+
Value *RHS, FMFSource FMFSource,
881881
const Twine &Name) {
882882
Module *M = BB->getModule();
883883
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, {LHS->getType()});
884884
if (Value *V = Folder.FoldBinaryIntrinsic(ID, LHS, RHS, Fn->getReturnType(),
885-
FMFSource))
885+
/*FMFSource=*/nullptr))
886886
return V;
887887
return createCallHelper(Fn, {LHS, RHS}, Name, FMFSource);
888888
}
889889

890890
CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
891891
ArrayRef<Type *> Types,
892892
ArrayRef<Value *> Args,
893-
Instruction *FMFSource,
893+
FMFSource FMFSource,
894894
const Twine &Name) {
895895
Module *M = BB->getModule();
896896
Function *Fn = Intrinsic::getOrInsertDeclaration(M, ID, Types);
@@ -899,7 +899,7 @@ CallInst *IRBuilderBase::CreateIntrinsic(Intrinsic::ID ID,
899899

900900
CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
901901
ArrayRef<Value *> Args,
902-
Instruction *FMFSource,
902+
FMFSource FMFSource,
903903
const Twine &Name) {
904904
Module *M = BB->getModule();
905905

@@ -925,16 +925,13 @@ CallInst *IRBuilderBase::CreateIntrinsic(Type *RetTy, Intrinsic::ID ID,
925925
}
926926

927927
CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
928-
Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
929-
const Twine &Name, MDNode *FPMathTag,
930-
std::optional<RoundingMode> Rounding,
928+
Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource,
929+
const Twine &Name, MDNode *FPMathTag, std::optional<RoundingMode> Rounding,
931930
std::optional<fp::ExceptionBehavior> Except) {
932931
Value *RoundingV = getConstrainedFPRounding(Rounding);
933932
Value *ExceptV = getConstrainedFPExcept(Except);
934933

935-
FastMathFlags UseFMF = FMF;
936-
if (FMFSource)
937-
UseFMF = FMFSource->getFastMathFlags();
934+
FastMathFlags UseFMF = FMFSource.get(FMF);
938935

939936
CallInst *C = CreateIntrinsic(ID, {L->getType()},
940937
{L, R, RoundingV, ExceptV}, nullptr, Name);
@@ -944,14 +941,12 @@ CallInst *IRBuilderBase::CreateConstrainedFPBinOp(
944941
}
945942

946943
CallInst *IRBuilderBase::CreateConstrainedFPUnroundedBinOp(
947-
Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource,
944+
Intrinsic::ID ID, Value *L, Value *R, FMFSource FMFSource,
948945
const Twine &Name, MDNode *FPMathTag,
949946
std::optional<fp::ExceptionBehavior> Except) {
950947
Value *ExceptV = getConstrainedFPExcept(Except);
951948

952-
FastMathFlags UseFMF = FMF;
953-
if (FMFSource)
954-
UseFMF = FMFSource->getFastMathFlags();
949+
FastMathFlags UseFMF = FMFSource.get(FMF);
955950

956951
CallInst *C =
957952
CreateIntrinsic(ID, {L->getType()}, {L, R, ExceptV}, nullptr, Name);
@@ -976,15 +971,12 @@ Value *IRBuilderBase::CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
976971
}
977972

978973
CallInst *IRBuilderBase::CreateConstrainedFPCast(
979-
Intrinsic::ID ID, Value *V, Type *DestTy,
980-
Instruction *FMFSource, const Twine &Name, MDNode *FPMathTag,
981-
std::optional<RoundingMode> Rounding,
974+
Intrinsic::ID ID, Value *V, Type *DestTy, FMFSource FMFSource,
975+
const Twine &Name, MDNode *FPMathTag, std::optional<RoundingMode> Rounding,
982976
std::optional<fp::ExceptionBehavior> Except) {
983977
Value *ExceptV = getConstrainedFPExcept(Except);
984978

985-
FastMathFlags UseFMF = FMF;
986-
if (FMFSource)
987-
UseFMF = FMFSource->getFastMathFlags();
979+
FastMathFlags UseFMF = FMFSource.get(FMF);
988980

989981
CallInst *C;
990982
if (Intrinsic::hasConstrainedFPRoundingModeOperand(ID)) {
@@ -1002,9 +994,10 @@ CallInst *IRBuilderBase::CreateConstrainedFPCast(
1002994
return C;
1003995
}
1004996

1005-
Value *IRBuilderBase::CreateFCmpHelper(
1006-
CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name,
1007-
MDNode *FPMathTag, bool IsSignaling) {
997+
Value *IRBuilderBase::CreateFCmpHelper(CmpInst::Predicate P, Value *LHS,
998+
Value *RHS, const Twine &Name,
999+
MDNode *FPMathTag, FMFSource FMFSource,
1000+
bool IsSignaling) {
10081001
if (IsFPConstrained) {
10091002
auto ID = IsSignaling ? Intrinsic::experimental_constrained_fcmps
10101003
: Intrinsic::experimental_constrained_fcmp;
@@ -1013,7 +1006,9 @@ Value *IRBuilderBase::CreateFCmpHelper(
10131006

10141007
if (auto *V = Folder.FoldCmp(P, LHS, RHS))
10151008
return V;
1016-
return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
1009+
return Insert(
1010+
setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMFSource.get(FMF)),
1011+
Name);
10171012
}
10181013

10191014
CallInst *IRBuilderBase::CreateConstrainedFPCmp(
@@ -1047,6 +1042,12 @@ CallInst *IRBuilderBase::CreateConstrainedFPCall(
10471042

10481043
Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
10491044
const Twine &Name, Instruction *MDFrom) {
1045+
return CreateSelectFMF(C, True, False, {}, Name, MDFrom);
1046+
}
1047+
1048+
Value *IRBuilderBase::CreateSelectFMF(Value *C, Value *True, Value *False,
1049+
FMFSource FMFSource, const Twine &Name,
1050+
Instruction *MDFrom) {
10501051
if (auto *V = Folder.FoldSelect(C, True, False))
10511052
return V;
10521053

@@ -1057,7 +1058,7 @@ Value *IRBuilderBase::CreateSelect(Value *C, Value *True, Value *False,
10571058
Sel = addBranchMetadata(Sel, Prof, Unpred);
10581059
}
10591060
if (isa<FPMathOperator>(Sel))
1060-
setFPAttrs(Sel, nullptr /* MDNode* */, FMF);
1061+
setFPAttrs(Sel, /*MDNode=*/nullptr, FMFSource.get(FMF));
10611062
return Insert(Sel, Name);
10621063
}
10631064

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,10 +1638,8 @@ instCombineSVEVectorBinOp(InstCombiner &IC, IntrinsicInst &II) {
16381638
!match(OpPredicate, m_Intrinsic<Intrinsic::aarch64_sve_ptrue>(
16391639
m_ConstantInt<AArch64SVEPredPattern::all>())))
16401640
return std::nullopt;
1641-
IRBuilderBase::FastMathFlagGuard FMFGuard(IC.Builder);
1642-
IC.Builder.setFastMathFlags(II.getFastMathFlags());
1643-
auto BinOp =
1644-
IC.Builder.CreateBinOp(BinOpCode, II.getOperand(1), II.getOperand(2));
1641+
auto BinOp = IC.Builder.CreateBinOpFMF(
1642+
BinOpCode, II.getOperand(1), II.getOperand(2), II.getFastMathFlags());
16451643
return IC.replaceInstUsesWith(II, BinOp);
16461644
}
16471645

llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,11 +425,8 @@ static bool foldSqrt(CallInst *Call, LibFunc Func, TargetTransformInfo &TTI,
425425
Arg, 0,
426426
SimplifyQuery(Call->getDataLayout(), &TLI, &DT, &AC, Call)))) {
427427
IRBuilder<> Builder(Call);
428-
IRBuilderBase::FastMathFlagGuard Guard(Builder);
429-
Builder.setFastMathFlags(Call->getFastMathFlags());
430-
431-
Value *NewSqrt = Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg,
432-
/*FMFSource=*/nullptr, "sqrt");
428+
Value *NewSqrt =
429+
Builder.CreateIntrinsic(Intrinsic::sqrt, Ty, Arg, Call, "sqrt");
433430
Call->replaceAllUsesWith(NewSqrt);
434431

435432
// Explicitly erase the old call because a call with side effects is not

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,12 +2845,11 @@ Instruction *InstCombinerImpl::hoistFNegAboveFMulFDiv(Value *FNegOp,
28452845
// Make sure to preserve flags and metadata on the call.
28462846
if (II->getIntrinsicID() == Intrinsic::ldexp) {
28472847
FastMathFlags FMF = FMFSource.getFastMathFlags() | II->getFastMathFlags();
2848-
IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2849-
Builder.setFastMathFlags(FMF);
2850-
2851-
CallInst *New = Builder.CreateCall(
2852-
II->getCalledFunction(),
2853-
{Builder.CreateFNeg(II->getArgOperand(0)), II->getArgOperand(1)});
2848+
CallInst *New =
2849+
Builder.CreateCall(II->getCalledFunction(),
2850+
{Builder.CreateFNegFMF(II->getArgOperand(0), FMF),
2851+
II->getArgOperand(1)});
2852+
New->setFastMathFlags(FMF);
28542853
New->copyMetadata(*II);
28552854
return New;
28562855
}
@@ -2932,12 +2931,8 @@ Instruction *InstCombinerImpl::visitFNeg(UnaryOperator &I) {
29322931
// flags the copysign doesn't also have.
29332932
FastMathFlags FMF = I.getFastMathFlags();
29342933
FMF &= cast<FPMathOperator>(OneUse)->getFastMathFlags();
2935-
2936-
IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2937-
Builder.setFastMathFlags(FMF);
2938-
2939-
Value *NegY = Builder.CreateFNeg(Y);
2940-
Value *NewCopySign = Builder.CreateCopySign(X, NegY);
2934+
Value *NegY = Builder.CreateFNegFMF(Y, FMF);
2935+
Value *NewCopySign = Builder.CreateCopySign(X, NegY, FMF);
29412936
return replaceInstUsesWith(I, NewCopySign);
29422937
}
29432938

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ static Value *getNewICmpValue(unsigned Code, bool Sign, Value *LHS, Value *RHS,
3939
/// This is the complement of getFCmpCode, which turns an opcode and two
4040
/// operands into either a FCmp instruction, or a true/false constant.
4141
static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS,
42-
InstCombiner::BuilderTy &Builder) {
42+
InstCombiner::BuilderTy &Builder,
43+
FastMathFlags FMF) {
4344
FCmpInst::Predicate NewPred;
4445
if (Constant *TorF = getPredForFCmpCode(Code, LHS->getType(), NewPred))
4546
return TorF;
46-
return Builder.CreateFCmp(NewPred, LHS, RHS);
47+
return Builder.CreateFCmpFMF(NewPred, LHS, RHS, FMF);
4748
}
4849

4950
/// 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,
14291430
!matchUnorderedInfCompare(PredR, RHS0, RHS1))
14301431
return nullptr;
14311432

1432-
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
1433-
FastMathFlags FMF = LHS->getFastMathFlags();
1434-
FMF &= RHS->getFastMathFlags();
1435-
Builder.setFastMathFlags(FMF);
1436-
1437-
return Builder.CreateFCmp(FCmpInst::getOrderedPredicate(PredR), RHS0, RHS1);
1433+
return Builder.CreateFCmpFMF(FCmpInst::getOrderedPredicate(PredR), RHS0, RHS1,
1434+
LHS->getFastMathFlags() &
1435+
RHS->getFastMathFlags());
14381436
}
14391437

14401438
Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
@@ -1470,12 +1468,8 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
14701468

14711469
// Intersect the fast math flags.
14721470
// TODO: We can union the fast math flags unless this is a logical select.
1473-
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
1474-
FastMathFlags FMF = LHS->getFastMathFlags();
1475-
FMF &= RHS->getFastMathFlags();
1476-
Builder.setFastMathFlags(FMF);
1477-
1478-
return getFCmpValue(NewPred, LHS0, LHS1, Builder);
1471+
return getFCmpValue(NewPred, LHS0, LHS1, Builder,
1472+
LHS->getFastMathFlags() & RHS->getFastMathFlags());
14791473
}
14801474

14811475
// This transform is not valid for a logical select.
@@ -1492,10 +1486,8 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
14921486
// Ignore the constants because they are obviously not NANs:
14931487
// (fcmp ord x, 0.0) & (fcmp ord y, 0.0) -> (fcmp ord x, y)
14941488
// (fcmp uno x, 0.0) | (fcmp uno y, 0.0) -> (fcmp uno x, y)
1495-
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
1496-
Builder.setFastMathFlags(LHS->getFastMathFlags() &
1497-
RHS->getFastMathFlags());
1498-
return Builder.CreateFCmp(PredL, LHS0, RHS0);
1489+
return Builder.CreateFCmpFMF(
1490+
PredL, LHS0, RHS0, LHS->getFastMathFlags() & RHS->getFastMathFlags());
14991491
}
15001492
}
15011493

@@ -1557,15 +1549,14 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
15571549
std::swap(PredL, PredR);
15581550
}
15591551
if (IsLessThanOrLessEqual(IsAnd ? PredL : PredR)) {
1560-
BuilderTy::FastMathFlagGuard Guard(Builder);
15611552
FastMathFlags NewFlag = LHS->getFastMathFlags();
15621553
if (!IsLogicalSelect)
15631554
NewFlag |= RHS->getFastMathFlags();
1564-
Builder.setFastMathFlags(NewFlag);
15651555

1566-
Value *FAbs = Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0);
1567-
return Builder.CreateFCmp(PredL, FAbs,
1568-
ConstantFP::get(LHS0->getType(), *LHSC));
1556+
Value *FAbs =
1557+
Builder.CreateUnaryIntrinsic(Intrinsic::fabs, LHS0, NewFlag);
1558+
return Builder.CreateFCmpFMF(
1559+
PredL, FAbs, ConstantFP::get(LHS0->getType(), *LHSC), NewFlag);
15691560
}
15701561
}
15711562

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,15 +1852,13 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
18521852
Value *X;
18531853
Instruction *Op = dyn_cast<Instruction>(FPT.getOperand(0));
18541854
if (Op && Op->hasOneUse()) {
1855-
IRBuilder<>::FastMathFlagGuard FMFG(Builder);
18561855
FastMathFlags FMF = FPT.getFastMathFlags();
18571856
if (auto *FPMO = dyn_cast<FPMathOperator>(Op))
18581857
FMF &= FPMO->getFastMathFlags();
1859-
Builder.setFastMathFlags(FMF);
18601858

18611859
if (match(Op, m_FNeg(m_Value(X)))) {
1862-
Value *InnerTrunc = Builder.CreateFPTrunc(X, Ty);
1863-
Value *Neg = Builder.CreateFNeg(InnerTrunc);
1860+
Value *InnerTrunc = Builder.CreateFPTruncFMF(X, Ty, FMF);
1861+
Value *Neg = Builder.CreateFNegFMF(InnerTrunc, FMF);
18641862
return replaceInstUsesWith(FPT, Neg);
18651863
}
18661864

@@ -1870,15 +1868,17 @@ Instruction *InstCombinerImpl::visitFPTrunc(FPTruncInst &FPT) {
18701868
if (match(Op, m_Select(m_Value(Cond), m_FPExt(m_Value(X)), m_Value(Y))) &&
18711869
X->getType() == Ty) {
18721870
// fptrunc (select Cond, (fpext X), Y --> select Cond, X, (fptrunc Y)
1873-
Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
1874-
Value *Sel = Builder.CreateSelect(Cond, X, NarrowY, "narrow.sel", Op);
1871+
Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
1872+
Value *Sel =
1873+
Builder.CreateSelectFMF(Cond, X, NarrowY, FMF, "narrow.sel", Op);
18751874
return replaceInstUsesWith(FPT, Sel);
18761875
}
18771876
if (match(Op, m_Select(m_Value(Cond), m_Value(Y), m_FPExt(m_Value(X)))) &&
18781877
X->getType() == Ty) {
18791878
// fptrunc (select Cond, Y, (fpext X) --> select Cond, (fptrunc Y), X
1880-
Value *NarrowY = Builder.CreateFPTrunc(Y, Ty);
1881-
Value *Sel = Builder.CreateSelect(Cond, NarrowY, X, "narrow.sel", Op);
1879+
Value *NarrowY = Builder.CreateFPTruncFMF(Y, Ty, FMF);
1880+
Value *Sel =
1881+
Builder.CreateSelectFMF(Cond, NarrowY, X, FMF, "narrow.sel", Op);
18821882
return replaceInstUsesWith(FPT, Sel);
18831883
}
18841884
}

0 commit comments

Comments
 (0)