mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Cleanup of the [SU]ADDO type legalization code. Patch by Duncan!
"It simplifies the type legalization part a bit, and produces better code by teaching SelectionDAG about the extra bits in an i8 SADDO/UADDO node. In essence, I spontaneously decided that on x86 this i8 boolean result would be either 0 or 1, and on other platforms 0/1 or 0/-1, depending on whether the platform likes it's boolean zero extended or sign extended." llvm-svn: 59864
This commit is contained in:
parent
3175516f94
commit
0b07d30acc
@ -250,12 +250,13 @@ namespace ISD {
|
|||||||
// values.
|
// values.
|
||||||
ADDE, SUBE,
|
ADDE, SUBE,
|
||||||
|
|
||||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for arithmetic
|
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||||
// operations. These nodes takes two operands: the normal lhs and rhs to the
|
// These nodes take two operands: the normal LHS and RHS to the add. They
|
||||||
// add. They produce two results: the normal result of the add, and a
|
// produce two results: the normal result of the add, and a boolean that
|
||||||
// boolean to indicate if an overflow occured (*not* a flag, because it may
|
// indicates if an overflow occured (*not* a flag, because it may be stored
|
||||||
// be stored to memory, etc.). These nodes is generated from the
|
// to memory, etc.). If the type of the boolean is not i1 then the high
|
||||||
// llvm.[su]add.with.overflow intrinsics.
|
// bits conform to getSetCCResultContents.
|
||||||
|
// These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
|
||||||
SADDO, UADDO,
|
SADDO, UADDO,
|
||||||
|
|
||||||
// Simple binary floating point operators.
|
// Simple binary floating point operators.
|
||||||
|
@ -99,8 +99,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
|||||||
case ISD::UDIV:
|
case ISD::UDIV:
|
||||||
case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
|
case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
|
||||||
|
|
||||||
case ISD::SADDO: Result = PromoteIntRes_SADDO(N, ResNo); break;
|
case ISD::SADDO:
|
||||||
case ISD::UADDO: Result = PromoteIntRes_UADDO(N, ResNo); break;
|
case ISD::UADDO: Result = PromoteIntRes_XADDO(N, ResNo); break;
|
||||||
|
|
||||||
case ISD::ATOMIC_LOAD_ADD_8:
|
case ISD::ATOMIC_LOAD_ADD_8:
|
||||||
case ISD::ATOMIC_LOAD_SUB_8:
|
case ISD::ATOMIC_LOAD_SUB_8:
|
||||||
@ -518,26 +518,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
|
|||||||
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
|
return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo,
|
SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo) {
|
||||||
ISD::NodeType NTy) {
|
assert(ResNo == 1 && "Only boolean result promotion currently supported!");
|
||||||
MVT NewVT = TLI.getTypeToTransformTo(SDValue(N, ResNo).getValueType());
|
|
||||||
assert(isTypeLegal(NewVT) && "Illegal XADDO type!");
|
|
||||||
|
|
||||||
MVT ValueVTs[] = { N->getOperand(0).getValueType(), NewVT };
|
// Simply change the return type of the boolean result.
|
||||||
|
MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1));
|
||||||
|
MVT ValueVTs[] = { N->getValueType(0), NVT };
|
||||||
SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
|
SDValue Ops[] = { N->getOperand(0), N->getOperand(1) };
|
||||||
|
SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
|
||||||
|
|
||||||
SDValue Res = DAG.getNode(NTy, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
|
// Modified the sum result - switch anything that used the old sum to use
|
||||||
ReplaceValueWith(SDValue(N, 0), SDValue(Res.getNode(), 0));
|
// the new one.
|
||||||
ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
|
ReplaceValueWith(SDValue(N, 0), Res);
|
||||||
return Res;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDValue DAGTypeLegalizer::PromoteIntRes_SADDO(SDNode *N, unsigned ResNo) {
|
return SDValue(Res.getNode(), 1);
|
||||||
return PromoteIntRes_XADDO(N, ResNo, ISD::SADDO);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDValue DAGTypeLegalizer::PromoteIntRes_UADDO(SDNode *N, unsigned ResNo) {
|
|
||||||
return PromoteIntRes_XADDO(N, ResNo, ISD::UADDO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
|
SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
|
||||||
|
@ -268,11 +268,9 @@ private:
|
|||||||
SDValue PromoteIntRes_SRL(SDNode *N);
|
SDValue PromoteIntRes_SRL(SDNode *N);
|
||||||
SDValue PromoteIntRes_TRUNCATE(SDNode *N);
|
SDValue PromoteIntRes_TRUNCATE(SDNode *N);
|
||||||
SDValue PromoteIntRes_UDIV(SDNode *N);
|
SDValue PromoteIntRes_UDIV(SDNode *N);
|
||||||
SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo, ISD::NodeType NTy);
|
|
||||||
SDValue PromoteIntRes_SADDO(SDNode *N, unsigned ResNo);
|
|
||||||
SDValue PromoteIntRes_UADDO(SDNode *N, unsigned ResNo);
|
|
||||||
SDValue PromoteIntRes_UNDEF(SDNode *N);
|
SDValue PromoteIntRes_UNDEF(SDNode *N);
|
||||||
SDValue PromoteIntRes_VAARG(SDNode *N);
|
SDValue PromoteIntRes_VAARG(SDNode *N);
|
||||||
|
SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo);
|
||||||
|
|
||||||
// Integer Operand Promotion.
|
// Integer Operand Promotion.
|
||||||
bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
|
bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
|
||||||
|
@ -1491,6 +1491,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask,
|
|||||||
KnownOne &= KnownOne2;
|
KnownOne &= KnownOne2;
|
||||||
KnownZero &= KnownZero2;
|
KnownZero &= KnownZero2;
|
||||||
return;
|
return;
|
||||||
|
case ISD::SADDO:
|
||||||
|
case ISD::UADDO:
|
||||||
|
if (Op.getResNo() != 1)
|
||||||
|
return;
|
||||||
|
// The boolean result conforms to getSetCCResultContents. Fall through.
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
// If we know the result of a setcc has the top bits zero, use this info.
|
// If we know the result of a setcc has the top bits zero, use this info.
|
||||||
if (TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult &&
|
if (TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult &&
|
||||||
@ -1893,7 +1898,12 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{
|
|||||||
if (Tmp == 1) return 1; // Early out.
|
if (Tmp == 1) return 1; // Early out.
|
||||||
Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1);
|
Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1);
|
||||||
return std::min(Tmp, Tmp2);
|
return std::min(Tmp, Tmp2);
|
||||||
|
|
||||||
|
case ISD::SADDO:
|
||||||
|
case ISD::UADDO:
|
||||||
|
if (Op.getResNo() != 1)
|
||||||
|
break;
|
||||||
|
// The boolean result conforms to getSetCCResultContents. Fall through.
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
// If setcc returns 0/-1, all bits are sign bits.
|
// If setcc returns 0/-1, all bits are sign bits.
|
||||||
if (TLI.getSetCCResultContents() ==
|
if (TLI.getSetCCResultContents() ==
|
||||||
|
Loading…
Reference in New Issue
Block a user