[llvm] d84cdb8 - [InstCombine] fabs(X) / fabs(X) -> X / X

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 20 07:21:45 PDT 2020


Author: Sanjay Patel
Date: 2020-06-20T10:20:21-04:00
New Revision: d84cdb81ed44943217b0159139cfc6e7cd7132ef

URL: https://github.com/llvm/llvm-project/commit/d84cdb81ed44943217b0159139cfc6e7cd7132ef
DIFF: https://github.com/llvm/llvm-project/commit/d84cdb81ed44943217b0159139cfc6e7cd7132ef.diff

LOG: [InstCombine] fabs(X) / fabs(X) -> X / X

Also, consolidate related folds so we don't miss/repeat these.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/test/Transforms/InstCombine/fdiv.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 775c0e94ab2d..5f7e35ecf038 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -402,6 +402,25 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
   return Changed ? &I : nullptr;
 }
 
+static Instruction *foldFPSignBitOps(BinaryOperator &I,
+                                     InstCombiner::BuilderTy &Builder) {
+  Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+  BinaryOperator::BinaryOps Opcode = I.getOpcode();
+  Value *X, *Y;
+
+  // -X * -Y --> X * Y
+  // -X / -Y --> X / Y
+  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
+    return BinaryOperator::CreateWithCopiedFlags(Opcode, X, Y, &I);
+
+  // fabs(X) * fabs(X) -> X * X
+  // fabs(X) / fabs(X) -> X / X
+  if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::fabs>(m_Value(X))))
+    return BinaryOperator::CreateWithCopiedFlags(Opcode, X, X, &I);
+
+  return nullptr;
+}
+
 Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
   if (Value *V = SimplifyFMulInst(I.getOperand(0), I.getOperand(1),
                                   I.getFastMathFlags(),
@@ -420,25 +439,20 @@ Instruction *InstCombiner::visitFMul(BinaryOperator &I) {
   if (Value *FoldedMul = foldMulSelectToNegate(I, Builder))
     return replaceInstUsesWith(I, FoldedMul);
 
+  if (Instruction *R = foldFPSignBitOps(I, Builder))
+    return R;
+
   // X * -1.0 --> -X
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   if (match(Op1, m_SpecificFP(-1.0)))
     return UnaryOperator::CreateFNegFMF(Op0, &I);
 
-  // -X * -Y --> X * Y
-  Value *X, *Y;
-  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y))))
-    return BinaryOperator::CreateFMulFMF(X, Y, &I);
-
   // -X * C --> X * -C
+  Value *X, *Y;
   Constant *C;
   if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_Constant(C)))
     return BinaryOperator::CreateFMulFMF(X, ConstantExpr::getFNeg(C), &I);
 
-  // fabs(X) * fabs(X) -> X * X
-  if (Op0 == Op1 && match(Op0, m_Intrinsic<Intrinsic::fabs>(m_Value(X))))
-    return BinaryOperator::CreateFMulFMF(X, X, &I);
-
   // (select A, B, C) * (select A, D, E) --> select A, (B*D), (C*E)
   if (Value *V = SimplifySelectsFeedingBinaryOp(I, Op0, Op1))
     return replaceInstUsesWith(I, V);
@@ -1223,6 +1237,9 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
   if (Instruction *R = foldFDivConstantDividend(I))
     return R;
 
+  if (Instruction *R = foldFPSignBitOps(I, Builder))
+    return R;
+
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
   if (isa<Constant>(Op0))
     if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
@@ -1283,17 +1300,10 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
     }
   }
 
-  // -X / -Y -> X / Y
-  Value *X, *Y;
-  if (match(Op0, m_FNeg(m_Value(X))) && match(Op1, m_FNeg(m_Value(Y)))) {
-    replaceOperand(I, 0, X);
-    replaceOperand(I, 1, Y);
-    return &I;
-  }
-
   // X / (X * Y) --> 1.0 / Y
   // Reassociate to (X / X -> 1.0) is legal when NaNs are not allowed.
   // We can ignore the possibility that X is infinity because INF/INF is NaN.
+  Value *X, *Y;
   if (I.hasNoNaNs() && I.hasAllowReassoc() &&
       match(Op1, m_c_FMul(m_Specific(Op0), m_Value(Y)))) {
     replaceOperand(I, 0, ConstantFP::get(I.getType(), 1.0));

diff  --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll
index c5ea7413ab5e..ce9548f29a29 100644
--- a/llvm/test/Transforms/InstCombine/fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv.ll
@@ -575,8 +575,7 @@ define float @fdiv_fneg1_extra_use(float %x, float %y) {
 
 define float @fabs_same_op(float %x) {
 ; CHECK-LABEL: @fabs_same_op(
-; CHECK-NEXT:    [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
-; CHECK-NEXT:    [[R:%.*]] = fdiv float [[A]], [[A]]
+; CHECK-NEXT:    [[R:%.*]] = fdiv float [[X:%.*]], [[X]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %a = call float @llvm.fabs.f32(float %x)
@@ -588,7 +587,7 @@ define float @fabs_same_op_extra_use(float %x) {
 ; CHECK-LABEL: @fabs_same_op_extra_use(
 ; CHECK-NEXT:    [[A:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
 ; CHECK-NEXT:    call void @use_f32(float [[A]])
-; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf float [[A]], [[A]]
+; CHECK-NEXT:    [[R:%.*]] = fdiv reassoc ninf float [[X]], [[X]]
 ; CHECK-NEXT:    ret float [[R]]
 ;
   %a = call float @llvm.fabs.f32(float %x)


        


More information about the llvm-commits mailing list