mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 12:40:17 +00:00
Some SELECT_CC cleanups:
1. move assertions for node creation to getNode() 2. legalize the values returned in ExpandOp immediately 3. Move select_cc optimizations from SELECT's getNode() to SELECT_CC's, allowing them to be cleaned up significantly. This paves the way to pick up additional optimizations on SELECT_CC, such as sum-of-absolute-differences. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22757 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c24d484b78
commit
e5d63829fd
@ -190,10 +190,6 @@ public:
|
||||
SDOperand getSelectCC(SDOperand LHS, SDOperand RHS,
|
||||
SDOperand True, SDOperand False, ISD::CondCode Cond) {
|
||||
MVT::ValueType VT = True.getValueType();
|
||||
assert(LHS.getValueType() == RHS.getValueType() &&
|
||||
"LHS and RHS of condition must have same type!");
|
||||
assert(True.getValueType() == False.getValueType() &&
|
||||
"True and False arms of SelectCC must have same type!");
|
||||
return getNode(ISD::SELECT_CC, VT, LHS, RHS, True, False,getCondCode(Cond));
|
||||
}
|
||||
|
||||
|
@ -2782,6 +2782,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||
Node->getOperand(1), TL, FL, Node->getOperand(4));
|
||||
Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
|
||||
Node->getOperand(1), TH, FH, Node->getOperand(4));
|
||||
Lo = LegalizeOp(Lo);
|
||||
Hi = LegalizeOp(Hi);
|
||||
break;
|
||||
}
|
||||
case ISD::SIGN_EXTEND: {
|
||||
|
@ -1397,59 +1397,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
if (N1 == N3) // X ? Y : X --> X ? Y : 0 --> X & Y
|
||||
return getNode(ISD::AND, VT, N1, N2);
|
||||
}
|
||||
|
||||
// If this is a selectcc, check to see if we can simplify the result.
|
||||
if (N1.Val->getOpcode() == ISD::SETCC) {
|
||||
SDNode *SetCC = N1.Val;
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
|
||||
if (ConstantFPSDNode *CFP =
|
||||
dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
|
||||
if (CFP->getValue() == 0.0) { // Allow either -0.0 or 0.0
|
||||
// select (setg[te] X, +/-0.0), X, fneg(X) -> fabs
|
||||
if ((CC == ISD::SETGE || CC == ISD::SETGT) &&
|
||||
N2 == SetCC->getOperand(0) && N3.getOpcode() == ISD::FNEG &&
|
||||
N3.getOperand(0) == N2)
|
||||
return getNode(ISD::FABS, VT, N2);
|
||||
|
||||
// select (setl[te] X, +/-0.0), fneg(X), X -> fabs
|
||||
if ((CC == ISD::SETLT || CC == ISD::SETLE) &&
|
||||
N3 == SetCC->getOperand(0) && N2.getOpcode() == ISD::FNEG &&
|
||||
N2.getOperand(0) == N3)
|
||||
return getNode(ISD::FABS, VT, N3);
|
||||
}
|
||||
// select (setlt X, 0), A, 0 -> and (sra X, size(X)-1), A
|
||||
if (ConstantSDNode *CN =
|
||||
dyn_cast<ConstantSDNode>(SetCC->getOperand(1)))
|
||||
if (CN->getValue() == 0 && N3C && N3C->getValue() == 0)
|
||||
if (CC == ISD::SETLT) {
|
||||
MVT::ValueType XType = SetCC->getOperand(0).getValueType();
|
||||
MVT::ValueType AType = N2.getValueType();
|
||||
if (XType >= AType) {
|
||||
// and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a
|
||||
// single-bit constant. FIXME: remove once the dag combiner
|
||||
// exists.
|
||||
if (ConstantSDNode *AC = dyn_cast<ConstantSDNode>(N2))
|
||||
if ((AC->getValue() & (AC->getValue()-1)) == 0) {
|
||||
unsigned ShCtV = Log2_64(AC->getValue());
|
||||
ShCtV = MVT::getSizeInBits(XType)-ShCtV-1;
|
||||
SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy());
|
||||
SDOperand Shift = getNode(ISD::SRL, XType,
|
||||
SetCC->getOperand(0), ShCt);
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N2);
|
||||
}
|
||||
|
||||
|
||||
SDOperand Shift = getNode(ISD::SRA, XType, SetCC->getOperand(0),
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N2);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ISD::BRCOND:
|
||||
if (N2C)
|
||||
@ -1491,6 +1438,65 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
SDOperand N1, SDOperand N2, SDOperand N3,
|
||||
SDOperand N4, SDOperand N5) {
|
||||
if (ISD::SELECT_CC == Opcode) {
|
||||
assert(N1.getValueType() == N2.getValueType() &&
|
||||
"LHS and RHS of condition must have same type!");
|
||||
assert(N3.getValueType() == N4.getValueType() &&
|
||||
"True and False arms of SelectCC must have same type!");
|
||||
|
||||
ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
|
||||
ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val);
|
||||
ConstantSDNode *N4C = dyn_cast<ConstantSDNode>(N4.Val);
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N5)->get();
|
||||
|
||||
// Check to see if we can simplify the select into an fabs node
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2)) {
|
||||
// Allow either -0.0 or 0.0
|
||||
if (CFP->getValue() == 0.0) {
|
||||
// select (setg[te] X, +/-0.0), X, fneg(X) -> fabs
|
||||
if ((CC == ISD::SETGE || CC == ISD::SETGT) &&
|
||||
N1 == N3 && N4.getOpcode() == ISD::FNEG &&
|
||||
N1 == N4.getOperand(0))
|
||||
return getNode(ISD::FABS, VT, N1);
|
||||
|
||||
// select (setl[te] X, +/-0.0), fneg(X), X -> fabs
|
||||
if ((CC == ISD::SETLT || CC == ISD::SETLE) &&
|
||||
N1 == N4 && N3.getOpcode() == ISD::FNEG &&
|
||||
N3.getOperand(0) == N4)
|
||||
return getNode(ISD::FABS, VT, N4);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we can perform the "gzip trick", transforming
|
||||
// select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A
|
||||
if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() &&
|
||||
MVT::isInteger(N1.getValueType()) &&
|
||||
MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) {
|
||||
MVT::ValueType XType = N1.getValueType();
|
||||
MVT::ValueType AType = N3.getValueType();
|
||||
if (XType >= AType) {
|
||||
// and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a
|
||||
// single-bit constant. FIXME: remove once the dag combiner
|
||||
// exists.
|
||||
if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) {
|
||||
unsigned ShCtV = Log2_64(N3C->getValue());
|
||||
ShCtV = MVT::getSizeInBits(XType)-ShCtV-1;
|
||||
SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy());
|
||||
SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt);
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N3);
|
||||
}
|
||||
SDOperand Shift = getNode(ISD::SRA, XType, N1,
|
||||
getConstant(MVT::getSizeInBits(XType)-1,
|
||||
TLI.getShiftAmountTy()));
|
||||
if (XType > AType)
|
||||
Shift = getNode(ISD::TRUNCATE, AType, Shift);
|
||||
return getNode(ISD::AND, AType, Shift, N3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SDOperand> Ops;
|
||||
Ops.reserve(5);
|
||||
Ops.push_back(N1);
|
||||
|
Loading…
Reference in New Issue
Block a user