mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-13 13:45:16 +00:00
[InstCombine] C / -X --> -C / X
We already do this in DAGCombiner, but it should also be good to eliminate the fsub use in IR. This is similar to rL325648. llvm-svn: 325649
This commit is contained in:
parent
d8dd0151fc
commit
6f716a7c5e
@ -1316,21 +1316,30 @@ static Instruction *foldFDivConstantDivisor(BinaryOperator &I) {
|
||||
Instruction::FMul, I.getOperand(0), RecipC, &I);
|
||||
}
|
||||
|
||||
/// Try to reassociate C / X expressions where X includes another constant.
|
||||
/// Remove negation and try to reassociate constant math.
|
||||
static Instruction *foldFDivConstantDividend(BinaryOperator &I) {
|
||||
Constant *C1;
|
||||
if (!I.hasAllowReassoc() || !I.hasAllowReciprocal() ||
|
||||
!match(I.getOperand(0), m_Constant(C1)))
|
||||
Constant *C;
|
||||
if (!match(I.getOperand(0), m_Constant(C)))
|
||||
return nullptr;
|
||||
|
||||
// C / -X --> -C / X
|
||||
Value *X;
|
||||
if (match(I.getOperand(1), m_FNeg(m_Value(X)))) {
|
||||
return BinaryOperator::CreateWithCopiedFlags(
|
||||
Instruction::FDiv, ConstantExpr::getFNeg(C), X, &I);
|
||||
}
|
||||
|
||||
if (!I.hasAllowReassoc() || !I.hasAllowReciprocal())
|
||||
return nullptr;
|
||||
|
||||
// Try to reassociate C / X expressions where X includes another constant.
|
||||
Constant *C2, *NewC = nullptr;
|
||||
if (match(I.getOperand(1), m_FMul(m_Value(X), m_Constant(C2)))) {
|
||||
// C1 / (X * C2) --> (C1 / C2) / X
|
||||
NewC = ConstantExpr::getFDiv(C1, C2);
|
||||
// C / (X * C2) --> (C / C2) / X
|
||||
NewC = ConstantExpr::getFDiv(C, C2);
|
||||
} else if (match(I.getOperand(1), m_FDiv(m_Value(X), m_Constant(C2)))) {
|
||||
// C1 / (X / C2) --> (C1 * C2) / X
|
||||
NewC = ConstantExpr::getFMul(C1, C2);
|
||||
// C / (X / C2) --> (C * C2) / X
|
||||
NewC = ConstantExpr::getFMul(C, C2);
|
||||
}
|
||||
// Disallow denormal constants because we don't know what would happen
|
||||
// on all targets.
|
||||
|
@ -225,8 +225,7 @@ define float @fneg_dividend_constant_divisor(float %x) {
|
||||
|
||||
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 nnan float -3.000000e+00, [[NEG]]
|
||||
; CHECK-NEXT: [[DIV:%.*]] = fdiv nnan float 3.000000e+00, [[X:%.*]]
|
||||
; CHECK-NEXT: ret float [[DIV]]
|
||||
;
|
||||
%neg = fsub float -0.0, %x
|
||||
@ -246,8 +245,7 @@ define <2 x float> @fneg_dividend_constant_divisor_vec(<2 x float> %x) {
|
||||
|
||||
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 afn <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>, [[X:%.*]]
|
||||
; CHECK-NEXT: ret <2 x float> [[DIV]]
|
||||
;
|
||||
%neg = fsub <2 x float> <float -0.0, float -0.0>, %x
|
||||
|
Loading…
x
Reference in New Issue
Block a user