mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Thread divisions over selects and phis. This doesn't fire much and has basically
zero effect on the testsuite (it improves two Ada testcases). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124496 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d11c57a937
commit
a3e292c7e8
@ -759,6 +759,8 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isSigned = Opcode == Instruction::SDiv;
|
||||||
|
|
||||||
// X / undef -> undef
|
// X / undef -> undef
|
||||||
if (isa<UndefValue>(Op1))
|
if (isa<UndefValue>(Op1))
|
||||||
return Op1;
|
return Op1;
|
||||||
@ -795,7 +797,6 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
|
|||||||
if (Y != Op1) std::swap(X, Y); // Ensure expression is (X * Y) / Y, Y = Op1
|
if (Y != Op1) std::swap(X, Y); // Ensure expression is (X * Y) / Y, Y = Op1
|
||||||
BinaryOperator *Mul = dyn_cast<BinaryOperator>(Op0);
|
BinaryOperator *Mul = dyn_cast<BinaryOperator>(Op0);
|
||||||
// If the Mul knows it does not overflow, then we are good to go.
|
// If the Mul knows it does not overflow, then we are good to go.
|
||||||
bool isSigned = Opcode == Instruction::SDiv;
|
|
||||||
if ((isSigned && Mul->hasNoSignedWrap()) ||
|
if ((isSigned && Mul->hasNoSignedWrap()) ||
|
||||||
(!isSigned && Mul->hasNoUnsignedWrap()))
|
(!isSigned && Mul->hasNoUnsignedWrap()))
|
||||||
return X;
|
return X;
|
||||||
@ -805,6 +806,23 @@ static Value *SimplifyDiv(unsigned Opcode, Value *Op0, Value *Op1,
|
|||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (X rem Y) / Y -> 0
|
||||||
|
if ((isSigned && match(Op0, m_SRem(m_Value(), m_Specific(Op1)))) ||
|
||||||
|
(!isSigned && match(Op0, m_URem(m_Value(), m_Specific(Op1)))))
|
||||||
|
return Constant::getNullValue(Op0->getType());
|
||||||
|
|
||||||
|
// If the operation is with the result of a select instruction, check whether
|
||||||
|
// operating on either branch of the select always yields the same value.
|
||||||
|
if (isa<SelectInst>(Op0) || isa<SelectInst>(Op1))
|
||||||
|
if (Value *V = ThreadBinOpOverSelect(Opcode, Op0, Op1, TD, DT, MaxRecurse))
|
||||||
|
return V;
|
||||||
|
|
||||||
|
// If the operation is with the result of a phi instruction, check whether
|
||||||
|
// operating on all incoming values of the phi always yields the same value.
|
||||||
|
if (isa<PHINode>(Op0) || isa<PHINode>(Op1))
|
||||||
|
if (Value *V = ThreadBinOpOverPHI(Opcode, Op0, Op1, TD, DT, MaxRecurse))
|
||||||
|
return V;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,10 +833,6 @@ static Value *SimplifySDivInst(Value *Op0, Value *Op1, const TargetData *TD,
|
|||||||
if (Value *V = SimplifyDiv(Instruction::SDiv, Op0, Op1, TD, DT, MaxRecurse))
|
if (Value *V = SimplifyDiv(Instruction::SDiv, Op0, Op1, TD, DT, MaxRecurse))
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
// (X rem Y) / Y -> 0
|
|
||||||
if (match(Op0, m_SRem(m_Value(), m_Specific(Op1))))
|
|
||||||
return Constant::getNullValue(Op0->getType());
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -834,10 +848,6 @@ static Value *SimplifyUDivInst(Value *Op0, Value *Op1, const TargetData *TD,
|
|||||||
if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, TD, DT, MaxRecurse))
|
if (Value *V = SimplifyDiv(Instruction::UDiv, Op0, Op1, TD, DT, MaxRecurse))
|
||||||
return V;
|
return V;
|
||||||
|
|
||||||
// (X rem Y) / Y -> 0
|
|
||||||
if (match(Op0, m_URem(m_Value(), m_Specific(Op1))))
|
|
||||||
return Constant::getNullValue(Op0->getType());
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user