From 2938f1cff9f880d03c900a2bdcd078af937d9433 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Sun, 24 Mar 2024 05:56:52 -0400 Subject: [PATCH 1/2] [InstCombine] Refactor powi(X,Y) / X to call foldPowiReassoc, NFC --- .../InstCombine/InstCombineMulDivRem.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index af238a43b11a0..a9f0a16be0b8c 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -611,6 +611,18 @@ Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) { Y->getType() == Z->getType()) return createPowiExpr(I, *this, X, Y, Z); + // powi(X, Y) / X --> powi(X, Y-1) + // This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan + // are required. + // TODO: Multi-use may be also better off creating Powi(x,y-1) + if (I.hasAllowReassoc() && I.hasNoNaNs() && + match(Op0, m_OneUse(m_Intrinsic(m_Specific(Op1), + m_Value(Y)))) && + willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) { + Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType()); + return createPowiExpr(I, *this, Op1, Y, NegOne); + } + return nullptr; } @@ -1904,20 +1916,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) { return replaceInstUsesWith(I, Pow); } - // powi(X, Y) / X --> powi(X, Y-1) - // This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan - // are required. - // TODO: Multi-use may be also better off creating Powi(x,y-1) - if (I.hasAllowReassoc() && I.hasNoNaNs() && - match(Op0, m_OneUse(m_Intrinsic(m_Specific(Op1), - m_Value(Y)))) && - willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) { - Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType()); - Value *Y1 = Builder.CreateAdd(Y, NegOne); - Type *Types[] = {Op1->getType(), Y1->getType()}; - Value *Pow = Builder.CreateIntrinsic(Intrinsic::powi, Types, {Op1, Y1}, &I); - return replaceInstUsesWith(I, Pow); - } + if (Instruction *FoldedPowi = foldPowiReassoc(I)) + return FoldedPowi; return nullptr; } From bd9bb31bce0754c0a04d5c842ab3e7f8dd467861 Mon Sep 17 00:00:00 2001 From: zhongyunde 00443407 Date: Sun, 24 Mar 2024 06:16:41 -0400 Subject: [PATCH 2/2] [InstCombine] add restrict reassoc for the powi(X,Y) / X add restrict reassoc for the powi(X,Y) / X according the discuss on PR69998. --- .../InstCombine/InstCombineMulDivRem.cpp | 4 ++-- llvm/test/Transforms/InstCombine/powi.ll | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index a9f0a16be0b8c..8c698e52b5a0e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -616,8 +616,8 @@ Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) { // are required. // TODO: Multi-use may be also better off creating Powi(x,y-1) if (I.hasAllowReassoc() && I.hasNoNaNs() && - match(Op0, m_OneUse(m_Intrinsic(m_Specific(Op1), - m_Value(Y)))) && + match(Op0, m_OneUse(m_AllowReassoc(m_Intrinsic( + m_Specific(Op1), m_Value(Y))))) && willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) { Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType()); return createPowiExpr(I, *this, Op1, Y, NegOne); diff --git a/llvm/test/Transforms/InstCombine/powi.ll b/llvm/test/Transforms/InstCombine/powi.ll index 43e34c889106e..6c0575e8b7197 100644 --- a/llvm/test/Transforms/InstCombine/powi.ll +++ b/llvm/test/Transforms/InstCombine/powi.ll @@ -313,7 +313,7 @@ define double @fdiv_pow_powi(double %x) { ; CHECK-NEXT: [[DIV:%.*]] = fmul reassoc nnan double [[X:%.*]], [[X]] ; CHECK-NEXT: ret double [[DIV]] ; - %p1 = call double @llvm.powi.f64.i32(double %x, i32 3) + %p1 = call reassoc double @llvm.powi.f64.i32(double %x, i32 3) %div = fdiv reassoc nnan double %p1, %x ret double %div } @@ -323,7 +323,7 @@ define float @fdiv_powf_powi(float %x) { ; CHECK-NEXT: [[DIV:%.*]] = call reassoc nnan float @llvm.powi.f32.i32(float [[X:%.*]], i32 99) ; CHECK-NEXT: ret float [[DIV]] ; - %p1 = call float @llvm.powi.f32.i32(float %x, i32 100) + %p1 = call reassoc float @llvm.powi.f32.i32(float %x, i32 100) %div = fdiv reassoc nnan float %p1, %x ret float %div } @@ -347,10 +347,21 @@ define double @fdiv_pow_powi_multi_use(double %x) { define float @fdiv_powf_powi_missing_reassoc(float %x) { ; CHECK-LABEL: @fdiv_powf_powi_missing_reassoc( ; CHECK-NEXT: [[P1:%.*]] = call float @llvm.powi.f32.i32(float [[X:%.*]], i32 100) -; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float [[P1]], [[X]] +; CHECK-NEXT: [[DIV:%.*]] = fdiv reassoc nnan float [[P1]], [[X]] ; CHECK-NEXT: ret float [[DIV]] ; %p1 = call float @llvm.powi.f32.i32(float %x, i32 100) + %div = fdiv reassoc nnan float %p1, %x + ret float %div +} + +define float @fdiv_powf_powi_missing_reassoc1(float %x) { +; CHECK-LABEL: @fdiv_powf_powi_missing_reassoc1( +; CHECK-NEXT: [[P1:%.*]] = call reassoc float @llvm.powi.f32.i32(float [[X:%.*]], i32 100) +; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float [[P1]], [[X]] +; CHECK-NEXT: ret float [[DIV]] +; + %p1 = call reassoc float @llvm.powi.f32.i32(float %x, i32 100) %div = fdiv nnan float %p1, %x ret float %div }