SelectionDAG: Improve legalization of SELECT_CC with illegal condition codes

SelectionDAG will now attempt to inverse an illegal conditon in order to
find a legal one and if that doesn't work, it will attempt to swap the
operands using the inverted condition.

There are no new test cases for this, but a nubmer of the existing R600
tests hit this path.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191602 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tom Stellard 2013-09-28 02:50:43 +00:00
parent 12d43f9baf
commit bbafe422d6
2 changed files with 49 additions and 17 deletions

View File

@ -3664,20 +3664,44 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
Tmp4 = Node->getOperand(3); // False
SDValue CC = Node->getOperand(4);
bool Legalized = LegalizeSetCCCondCode(
getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC, dl);
assert(Legalized && "Can't legalize SELECT_CC with legal condition!");
// If we exapanded the SETCC by swapping LHS and RHS, create a new SELECT_CC
// node and return it.
if (CC.getNode()) {
Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0),
Tmp1, Tmp2, Tmp3, Tmp4, CC);
bool Legalized = false;
// Try to legalize by inverting the condition. This is for targets that
// might support an ordered version of a condition, but not the unordered
// version (or vice versa).
ISD::CondCode InvCC = ISD::getSetCCInverse(cast<CondCodeSDNode>(CC)->get(),
Tmp1.getValueType().isInteger());
if (TLI.isCondCodeLegal(InvCC, Tmp1.getSimpleValueType())) {
// Use the new condition code and swap true and false
Legalized = true;
Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp4, Tmp3, InvCC);
} else {
Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
CC = DAG.getCondCode(ISD::SETNE);
Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2,
Tmp3, Tmp4, CC);
// If The inverse is not legal, then try to swap the arguments using
// the inverse condition code.
ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InvCC);
if (TLI.isCondCodeLegal(SwapInvCC, Tmp1.getSimpleValueType())) {
// The swapped inverse condition is legal, so swap true and false,
// lhs and rhs.
Legalized = true;
Tmp1 = DAG.getSelectCC(dl, Tmp2, Tmp1, Tmp4, Tmp3, SwapInvCC);
}
}
if (!Legalized) {
Legalized = LegalizeSetCCCondCode(
getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC, dl);
assert(Legalized && "Can't legalize SELECT_CC with legal condition!");
// If we exapanded the SETCC by swapping LHS and RHS, create a new
// SELECT_CC node.
if (CC.getNode()) {
Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0),
Tmp1, Tmp2, Tmp3, Tmp4, CC);
} else {
Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
CC = DAG.getCondCode(ISD::SETNE);
Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2,
Tmp3, Tmp4, CC);
}
}
Results.push_back(Tmp1);
break;

View File

@ -862,10 +862,18 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
ISD::CondCode InverseCC =
ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
if (isHWTrueValue(False) && isHWFalseValue(True) &&
isCondCodeLegal(InverseCC, CompareVT.getSimpleVT())) {
std::swap(False, True);
CC = DAG.getCondCode(InverseCC);
if (isHWTrueValue(False) && isHWFalseValue(True)) {
if (isCondCodeLegal(InverseCC, CompareVT.getSimpleVT())) {
std::swap(False, True);
CC = DAG.getCondCode(InverseCC);
} else {
ISD::CondCode SwapInvCC = ISD::getSetCCSwappedOperands(InverseCC);
if (isCondCodeLegal(SwapInvCC, CompareVT.getSimpleVT())) {
std::swap(False, True);
std::swap(LHS, RHS);
CC = DAG.getCondCode(SwapInvCC);
}
}
}
if (isHWTrueValue(True) && isHWFalseValue(False) &&