From 937528e56aed53be4286172b26ed219e20f64bac Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 7 Jan 2025 16:30:09 +0800 Subject: [PATCH 1/3] [InstCombine] Simplify FMF propagation. NFC. --- .../InstCombine/InstCombineAndOrXor.cpp | 11 +++--- .../InstCombine/InstCombineCalls.cpp | 34 +++++++------------ 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index f82a557e5760c..e44b5ac8a97a0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1672,12 +1672,11 @@ static Instruction *reassociateFCmps(BinaryOperator &BO, // and (fcmp ord X, 0), (and (fcmp ord Y, 0), Z) --> and (fcmp ord X, Y), Z // or (fcmp uno X, 0), (or (fcmp uno Y, 0), Z) --> or (fcmp uno X, Y), Z - Value *NewFCmp = Builder.CreateFCmp(NanPred, X, Y); - if (auto *NewFCmpInst = dyn_cast(NewFCmp)) { - // Intersect FMF from the 2 source fcmps. - NewFCmpInst->copyIRFlags(Op0); - NewFCmpInst->andIRFlags(BO10); - } + // Intersect FMF from the 2 source fcmps. + Value *NewFCmp = + Builder.CreateFCmpFMF(NanPred, X, Y, + cast(Op0)->getFastMathFlags() & + cast(BO10)->getFastMathFlags()); return BinaryOperator::Create(Opcode, NewFCmp, BO11); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index c55c40c88bc84..eb11237f6bce7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2500,13 +2500,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { default: llvm_unreachable("unexpected intrinsic ID"); } - Value *V = Builder.CreateBinaryIntrinsic( - IID, X, ConstantFP::get(Arg0->getType(), Res), II); // TODO: Conservatively intersecting FMF. If Res == C2, the transform // was a simplification (so Arg0 and its original flags could // propagate?) - if (auto *CI = dyn_cast(V)) - CI->andIRFlags(M); + Value *V = Builder.CreateBinaryIntrinsic( + IID, X, ConstantFP::get(Arg0->getType(), Res), + II->getFastMathFlags() & M->getFastMathFlags()); return replaceInstUsesWith(*II, V); } } @@ -2601,13 +2600,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { } case Intrinsic::fmuladd: { // Try to simplify the underlying FMul. - if (Value *V = simplifyFMulInst(II->getArgOperand(0), II->getArgOperand(1), - II->getFastMathFlags(), - SQ.getWithInstruction(II))) { - auto *FAdd = BinaryOperator::CreateFAdd(V, II->getArgOperand(2)); - FAdd->copyFastMathFlags(II); - return FAdd; - } + if (Value *V = + simplifyFMulInst(II->getArgOperand(0), II->getArgOperand(1), + II->getFastMathFlags(), SQ.getWithInstruction(II))) + return BinaryOperator::CreateFAddFMF(V, II->getArgOperand(2), + II->getFastMathFlags()); [[fallthrough]]; } @@ -2634,11 +2631,8 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { // Try to simplify the underlying FMul. We can only apply simplifications // that do not require rounding. if (Value *V = simplifyFMAFMul(Src0, Src1, II->getFastMathFlags(), - SQ.getWithInstruction(II))) { - auto *FAdd = BinaryOperator::CreateFAdd(V, Src2); - FAdd->copyFastMathFlags(II); - return FAdd; - } + SQ.getWithInstruction(II))) + return BinaryOperator::CreateFAddFMF(V, Src2, II->getFastMathFlags()); // fma x, y, 0 -> fmul x, y // This is always valid for -0.0, but requires nsz for +0.0 as @@ -2732,8 +2726,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { m_CopySign(m_Value(Magnitude), m_Value(Sign)))) { // fabs (copysign x, y) -> (fabs x) CallInst *AbsSign = - Builder.CreateCall(II->getCalledFunction(), {Magnitude}); - AbsSign->copyFastMathFlags(II); + Builder.CreateUnaryIntrinsic(Intrinsic::fabs, Magnitude, II); return replaceInstUsesWith(*II, AbsSign); } @@ -2840,16 +2833,15 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { Value *NewLdexp = nullptr; Value *Select = nullptr; if (match(SelectRHS, m_ZeroInt())) { - NewLdexp = Builder.CreateLdexp(Src, SelectLHS); + NewLdexp = Builder.CreateLdexp(Src, SelectLHS, II); Select = Builder.CreateSelect(SelectCond, NewLdexp, Src); } else if (match(SelectLHS, m_ZeroInt())) { - NewLdexp = Builder.CreateLdexp(Src, SelectRHS); + NewLdexp = Builder.CreateLdexp(Src, SelectRHS, II); Select = Builder.CreateSelect(SelectCond, Src, NewLdexp); } if (NewLdexp) { Select->takeName(II); - cast(NewLdexp)->copyFastMathFlags(II); return replaceInstUsesWith(*II, Select); } } From 097d1c9b23c4ca5eb0d9531f86fdb5db91f2424d Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 8 Jan 2025 14:29:52 +0800 Subject: [PATCH 2/3] [InstCombine] Address review comments. NFC. --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index e44b5ac8a97a0..8fa9fdf86e713 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1675,8 +1675,8 @@ static Instruction *reassociateFCmps(BinaryOperator &BO, // Intersect FMF from the 2 source fcmps. Value *NewFCmp = Builder.CreateFCmpFMF(NanPred, X, Y, - cast(Op0)->getFastMathFlags() & - cast(BO10)->getFastMathFlags()); + cast(Op0)->getFastMathFlags() & + cast(BO10)->getFastMathFlags()); return BinaryOperator::Create(Opcode, NewFCmp, BO11); } From e8f385ad98c53b19ca66cfa76df8e791e2317adf Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Thu, 9 Jan 2025 15:38:44 +0800 Subject: [PATCH 3/3] [InstCombine] Use `FMFSource::intersect`. NFC. --- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 4 +--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 8fa9fdf86e713..fb09a7b75f058 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1674,9 +1674,7 @@ static Instruction *reassociateFCmps(BinaryOperator &BO, // or (fcmp uno X, 0), (or (fcmp uno Y, 0), Z) --> or (fcmp uno X, Y), Z // Intersect FMF from the 2 source fcmps. Value *NewFCmp = - Builder.CreateFCmpFMF(NanPred, X, Y, - cast(Op0)->getFastMathFlags() & - cast(BO10)->getFastMathFlags()); + Builder.CreateFCmpFMF(NanPred, X, Y, FMFSource::intersect(Op0, BO10)); return BinaryOperator::Create(Opcode, NewFCmp, BO11); } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index eb11237f6bce7..98ea3720e2200 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -2505,7 +2505,7 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { // propagate?) Value *V = Builder.CreateBinaryIntrinsic( IID, X, ConstantFP::get(Arg0->getType(), Res), - II->getFastMathFlags() & M->getFastMathFlags()); + FMFSource::intersect(II, M)); return replaceInstUsesWith(*II, V); } }