forked from OSchip/llvm-project
[InstCombine] -X / C --> X / -C for FP
We already do this in DAGCombiner, but it should also be good to eliminate the fsub use in IR. llvm-svn: 325648
This commit is contained in:
parent
cd8758233e
commit
d8dd0151fc
|
@ -1285,12 +1285,18 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/// Try to convert X/C into X * (1/C).
|
||||
/// Remove negation and try to convert division into multiplication.
|
||||
static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
|
||||
Constant *C;
|
||||
if (!match(I.getOperand(1), m_Constant(C)))
|
||||
return nullptr;
|
||||
|
||||
// -X / C --> X / -C
|
||||
Value *X;
|
||||
if (match(I.getOperand(0), m_FNeg(m_Value(X))))
|
||||
return BinaryOperator::CreateWithCopiedFlags(Instruction::FDiv, X,
|
||||
ConstantExpr::getFNeg(C), &I);
|
||||
|
||||
// If the constant divisor has an exact inverse, this is always safe. If not,
|
||||
// then we can still create a reciprocal if fast-math-flags allow it and the
|
||||
// constant is a regular number (not zero, infinite, or denormal).
|
||||
|
@ -1305,6 +1311,7 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
|
|||
if (!RecipC->isNormalFP())
|
||||
return nullptr;
|
||||
|
||||
// X / C --> X * (1 / C)
|
||||
return BinaryOperator::CreateWithCopiedFlags(
|
||||
Instruction::FMul, I.getOperand(0), RecipC, &I);
|
||||
}
|
||||
|
@ -1345,11 +1352,11 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {
|
|||
SQ.getWithInstruction(&I)))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
if (Instruction *FMul = foldFDivConstantDivisor(I))
|
||||
return FMul;
|
||||
if (Instruction *R = foldFDivConstantDivisor(I))
|
||||
return R;
|
||||
|
||||
if (Instruction *NewFDiv = foldFDivConstantDividend(I))
|
||||
return NewFDiv;
|
||||
if (Instruction *R = foldFDivConstantDividend(I))
|
||||
return R;
|
||||
|
||||
if (isa<Constant>(Op0))
|
||||
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
|
||||
|
|
|
@ -215,45 +215,43 @@ define <2 x float> @fneg_fneg_vec(<2 x float> %x, <2 x float> %y) {
|
|||
|
||||
define float @fneg_dividend_constant_divisor(float %x) {
|
||||
; CHECK-LABEL: @fneg_dividend_constant_divisor(
|
||||
; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv float [[NEG]], 3.000000e+00
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv nsz float [[X:%.*]], -3.000000e+00
|
||||
; CHECK-NEXT: ret float [[DIV]]
|
||||
;
|
||||
%neg = fsub float -0.0, %x
|
||||
%div = fdiv float %neg, 3.0
|
||||
%div = fdiv nsz float %neg, 3.0
|
||||
ret float %div
|
||||
}
|
||||
|
||||
define float @fneg_divisor_constant_dividend(float %x) {
|
||||
; CHECK-LABEL: @fneg_divisor_constant_dividend(
|
||||
; CHECK-NEXT: [[NEG:%.*]] = fsub float -0.000000e+00, [[X:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv float -3.000000e+00, [[NEG]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float -3.000000e+00, [[NEG]]
|
||||
; CHECK-NEXT: ret float [[DIV]]
|
||||
;
|
||||
%neg = fsub float -0.0, %x
|
||||
%div = fdiv float -3.0, %neg
|
||||
%div = fdiv nnan float -3.0, %neg
|
||||
ret float %div
|
||||
}
|
||||
|
||||
define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {
|
||||
; CHECK-LABEL: @fneg_dividend_constant_divisor_vec(
|
||||
; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> [[NEG]], <float 3.000000e+00, float -8.000000e+00>
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv ninf <2 x float> [[X:%.*]], <float -3.000000e+00, float 8.000000e+00>
|
||||
; CHECK-NEXT: ret <2 x float> [[DIV]]
|
||||
;
|
||||
%neg = fsub <2 x float> <float -0.0, float -0.0>, %x
|
||||
%div = fdiv <2 x float> %neg, <float 3.0, float -8.0>
|
||||
%div = fdiv ninf <2 x float> %neg, <float 3.0, float -8.0>
|
||||
ret <2 x float> %div
|
||||
}
|
||||
|
||||
define <2 x float> @fneg_divisor_constant_dividend_vec(<2 x float> %x) {
|
||||
; CHECK-LABEL: @fneg_divisor_constant_dividend_vec(
|
||||
; CHECK-NEXT: [[NEG:%.*]] = fsub <2 x float> <float -0.000000e+00, float -0.000000e+00>, [[X:%.*]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv <2 x float> <float -3.000000e+00, float 5.000000e+00>, [[NEG]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv afn <2 x float> <float -3.000000e+00, float 5.000000e+00>, [[NEG]]
|
||||
; CHECK-NEXT: ret <2 x float> [[DIV]]
|
||||
;
|
||||
%neg = fsub <2 x float> <float -0.0, float -0.0>, %x
|
||||
%div = fdiv <2 x float> <float -3.0, float 5.0>, %neg
|
||||
%div = fdiv afn <2 x float> <float -3.0, float 5.0>, %neg
|
||||
ret <2 x float> %div
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue