1
0
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:
Bill Wendling 2008-11-22 07:24:01 +00:00
parent 3175516f94
commit 0b07d30acc
4 changed files with 31 additions and 28 deletions

View File

@ -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.

View File

@ -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) {

View File

@ -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);

View File

@ -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() ==