mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Lowering of sdiv X, pow2 was broken, this fixes it. This patch is written
by Nate, I'm just committing it for him. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26230 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -725,7 +725,7 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
|
|||||||
if (TLI.MaskedValueIsZero(N1, SignBit) &&
|
if (TLI.MaskedValueIsZero(N1, SignBit) &&
|
||||||
TLI.MaskedValueIsZero(N0, SignBit))
|
TLI.MaskedValueIsZero(N0, SignBit))
|
||||||
return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
|
return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
|
||||||
// fold (sdiv X, pow2) -> (add (sra X, log(pow2)), (srl X, sizeof(X)-1))
|
// fold (sdiv X, pow2) -> simple ops.
|
||||||
if (N1C && N1C->getValue() && !TLI.isIntDivCheap() &&
|
if (N1C && N1C->getValue() && !TLI.isIntDivCheap() &&
|
||||||
(isPowerOf2_64(N1C->getSignExtended()) ||
|
(isPowerOf2_64(N1C->getSignExtended()) ||
|
||||||
isPowerOf2_64(-N1C->getSignExtended()))) {
|
isPowerOf2_64(-N1C->getSignExtended()))) {
|
||||||
@@ -735,15 +735,21 @@ SDOperand DAGCombiner::visitSDIV(SDNode *N) {
|
|||||||
return SDOperand();
|
return SDOperand();
|
||||||
int64_t pow2 = N1C->getSignExtended();
|
int64_t pow2 = N1C->getSignExtended();
|
||||||
int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
|
int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
|
||||||
SDOperand SRL = DAG.getNode(ISD::SRL, VT, N0,
|
unsigned lg2 = Log2_64(abs2);
|
||||||
|
// Splat the sign bit into the register
|
||||||
|
SDOperand SGN = DAG.getNode(ISD::SRA, VT, N0,
|
||||||
DAG.getConstant(MVT::getSizeInBits(VT)-1,
|
DAG.getConstant(MVT::getSizeInBits(VT)-1,
|
||||||
TLI.getShiftAmountTy()));
|
TLI.getShiftAmountTy()));
|
||||||
WorkList.push_back(SRL.Val);
|
|
||||||
SDOperand SGN = DAG.getNode(ISD::ADD, VT, N0, SRL);
|
|
||||||
WorkList.push_back(SGN.Val);
|
WorkList.push_back(SGN.Val);
|
||||||
SDOperand SRA = DAG.getNode(ISD::SRA, VT, SGN,
|
// Add (N0 < 0) ? abs2 - 1 : 0;
|
||||||
DAG.getConstant(Log2_64(abs2),
|
SDOperand SRL = DAG.getNode(ISD::SRL, VT, SGN,
|
||||||
|
DAG.getConstant(MVT::getSizeInBits(VT)-lg2,
|
||||||
TLI.getShiftAmountTy()));
|
TLI.getShiftAmountTy()));
|
||||||
|
SDOperand ADD = DAG.getNode(ISD::ADD, VT, N0, SRL);
|
||||||
|
WorkList.push_back(SRL.Val);
|
||||||
|
WorkList.push_back(ADD.Val); // Divide by pow2
|
||||||
|
SDOperand SRA = DAG.getNode(ISD::SRA, VT, ADD,
|
||||||
|
DAG.getConstant(lg2, TLI.getShiftAmountTy()));
|
||||||
// If we're dividing by a positive value, we're done. Otherwise, we must
|
// If we're dividing by a positive value, we're done. Otherwise, we must
|
||||||
// negate the result.
|
// negate the result.
|
||||||
if (pow2 > 0)
|
if (pow2 > 0)
|
||||||
|
Reference in New Issue
Block a user