[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