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.
|
||||
ADDE, SUBE,
|
||||
|
||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for arithmetic
|
||||
// operations. These nodes takes two operands: the normal lhs and rhs to the
|
||||
// add. They produce two results: the normal result of the add, and a
|
||||
// boolean to indicate if an overflow occured (*not* a flag, because it may
|
||||
// be stored to memory, etc.). These nodes is generated from the
|
||||
// llvm.[su]add.with.overflow intrinsics.
|
||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||
// These nodes take two operands: the normal LHS and RHS to the add. They
|
||||
// produce two results: the normal result of the add, and a boolean that
|
||||
// indicates if an overflow occured (*not* a flag, because it may be stored
|
||||
// to memory, etc.). If the type of the boolean is not i1 then the high
|
||||
// bits conform to getSetCCResultContents.
|
||||
// These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
|
||||
SADDO, UADDO,
|
||||
|
||||
// Simple binary floating point operators.
|
||||
|
@ -99,8 +99,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::UDIV:
|
||||
case ISD::UREM: Result = PromoteIntRes_UDIV(N); break;
|
||||
|
||||
case ISD::SADDO: Result = PromoteIntRes_SADDO(N, ResNo); break;
|
||||
case ISD::UADDO: Result = PromoteIntRes_UADDO(N, ResNo); break;
|
||||
case ISD::SADDO:
|
||||
case ISD::UADDO: Result = PromoteIntRes_XADDO(N, ResNo); break;
|
||||
|
||||
case ISD::ATOMIC_LOAD_ADD_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);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo,
|
||||
ISD::NodeType NTy) {
|
||||
MVT NewVT = TLI.getTypeToTransformTo(SDValue(N, ResNo).getValueType());
|
||||
assert(isTypeLegal(NewVT) && "Illegal XADDO type!");
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo) {
|
||||
assert(ResNo == 1 && "Only boolean result promotion currently supported!");
|
||||
|
||||
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 Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2);
|
||||
|
||||
SDValue Res = DAG.getNode(NTy, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
|
||||
ReplaceValueWith(SDValue(N, 0), SDValue(Res.getNode(), 0));
|
||||
ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1));
|
||||
return Res;
|
||||
}
|
||||
// Modified the sum result - switch anything that used the old sum to use
|
||||
// the new one.
|
||||
ReplaceValueWith(SDValue(N, 0), Res);
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_SADDO(SDNode *N, unsigned ResNo) {
|
||||
return PromoteIntRes_XADDO(N, ResNo, ISD::SADDO);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_UADDO(SDNode *N, unsigned ResNo) {
|
||||
return PromoteIntRes_XADDO(N, ResNo, ISD::UADDO);
|
||||
return SDValue(Res.getNode(), 1);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
|
||||
|
@ -268,11 +268,9 @@ private:
|
||||
SDValue PromoteIntRes_SRL(SDNode *N);
|
||||
SDValue PromoteIntRes_TRUNCATE(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_VAARG(SDNode *N);
|
||||
SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo);
|
||||
|
||||
// Integer Operand Promotion.
|
||||
bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
|
||||
|
@ -1491,6 +1491,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask,
|
||||
KnownOne &= KnownOne2;
|
||||
KnownZero &= KnownZero2;
|
||||
return;
|
||||
case ISD::SADDO:
|
||||
case ISD::UADDO:
|
||||
if (Op.getResNo() != 1)
|
||||
return;
|
||||
// The boolean result conforms to getSetCCResultContents. Fall through.
|
||||
case ISD::SETCC:
|
||||
// If we know the result of a setcc has the top bits zero, use this info.
|
||||
if (TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult &&
|
||||
@ -1894,6 +1899,11 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{
|
||||
Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1);
|
||||
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:
|
||||
// If setcc returns 0/-1, all bits are sign bits.
|
||||
if (TLI.getSetCCResultContents() ==
|
||||
|
Loading…
Reference in New Issue
Block a user