mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +00:00
SelectionDAG: Try to expand all condition codes using getCCSwappedOperands()
This is useful for targets like R600, which only support GT, GE, NE, and EQ condition codes as it removes the need to handle unsupported condition codes in target specific code. There are no tests with this commit, but R600 has been updated to take advantage of this new feature, so its existing selectcc tests are now testing the swapped operands path. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191601 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8a9879a448
commit
12d43f9baf
@ -1615,8 +1615,13 @@ bool SelectionDAGLegalize::LegalizeSetCCCondCode(EVT VT,
|
|||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
break;
|
break;
|
||||||
case TargetLowering::Expand: {
|
case TargetLowering::Expand: {
|
||||||
|
ISD::CondCode InvCC = ISD::getSetCCSwappedOperands(CCCode);
|
||||||
|
if (TLI.isCondCodeLegal(InvCC, OpVT)) {
|
||||||
|
std::swap(LHS, RHS);
|
||||||
|
CC = DAG.getCondCode(InvCC);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
|
ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
|
||||||
ISD::CondCode InvCC = ISD::SETCC_INVALID;
|
|
||||||
unsigned Opc = 0;
|
unsigned Opc = 0;
|
||||||
switch (CCCode) {
|
switch (CCCode) {
|
||||||
default: llvm_unreachable("Don't know how to expand this condition!");
|
default: llvm_unreachable("Don't know how to expand this condition!");
|
||||||
@ -1658,15 +1663,9 @@ bool SelectionDAGLegalize::LegalizeSetCCCondCode(EVT VT,
|
|||||||
case ISD::SETLT:
|
case ISD::SETLT:
|
||||||
case ISD::SETNE:
|
case ISD::SETNE:
|
||||||
case ISD::SETEQ:
|
case ISD::SETEQ:
|
||||||
InvCC = ISD::getSetCCSwappedOperands(CCCode);
|
// We only support using the inverted operation, which is computed above
|
||||||
if (TLI.getCondCodeAction(InvCC, OpVT) == TargetLowering::Expand) {
|
// and not a different manner of supporting expanding these cases.
|
||||||
// We only support using the inverted operation and not a
|
llvm_unreachable("Don't know how to expand this condition!");
|
||||||
// different manner of supporting expanding these cases.
|
|
||||||
llvm_unreachable("Don't know how to expand this condition!");
|
|
||||||
}
|
|
||||||
std::swap(LHS, RHS);
|
|
||||||
CC = DAG.getCondCode(InvCC);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue SetCC1, SetCC2;
|
SDValue SetCC1, SetCC2;
|
||||||
|
@ -1645,7 +1645,12 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ensure that the constant occurs on the RHS.
|
// Ensure that the constant occurs on the RHS.
|
||||||
return getSetCC(dl, VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
|
ISD::CondCode SwappedCond = ISD::getSetCCSwappedOperands(Cond);
|
||||||
|
MVT CompVT = N1.getValueType().getSimpleVT();
|
||||||
|
if (!TM.getTargetLowering()->isCondCodeLegal(SwappedCond, CompVT))
|
||||||
|
return SDValue();
|
||||||
|
|
||||||
|
return getSetCC(dl, VT, N2, N1, SwappedCond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,8 +1089,11 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
|||||||
|
|
||||||
// Ensure that the constant occurs on the RHS, and fold constant
|
// Ensure that the constant occurs on the RHS, and fold constant
|
||||||
// comparisons.
|
// comparisons.
|
||||||
if (isa<ConstantSDNode>(N0.getNode()))
|
ISD::CondCode SwappedCC = ISD::getSetCCSwappedOperands(Cond);
|
||||||
return DAG.getSetCC(dl, VT, N1, N0, ISD::getSetCCSwappedOperands(Cond));
|
if (isa<ConstantSDNode>(N0.getNode()) &&
|
||||||
|
(DCI.isBeforeLegalizeOps() ||
|
||||||
|
isCondCodeLegal(SwappedCC, N0.getSimpleValueType())))
|
||||||
|
return DAG.getSetCC(dl, VT, N1, N0, SwappedCC);
|
||||||
|
|
||||||
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
|
if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
|
||||||
const APInt &C1 = N1C->getAPIntValue();
|
const APInt &C1 = N1C->getAPIntValue();
|
||||||
@ -1330,7 +1333,9 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
|||||||
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
|
ISD::CondCode CC = cast<CondCodeSDNode>(N0.getOperand(2))->get();
|
||||||
CC = ISD::getSetCCInverse(CC,
|
CC = ISD::getSetCCInverse(CC,
|
||||||
N0.getOperand(0).getValueType().isInteger());
|
N0.getOperand(0).getValueType().isInteger());
|
||||||
return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
|
if (DCI.isBeforeLegalizeOps() ||
|
||||||
|
isCondCodeLegal(CC, N0.getOperand(0).getSimpleValueType()))
|
||||||
|
return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((N0.getOpcode() == ISD::XOR ||
|
if ((N0.getOpcode() == ISD::XOR ||
|
||||||
@ -1767,16 +1772,22 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
|||||||
if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
|
if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
|
||||||
if (ValueHasExactlyOneBitSet(N1, DAG)) {
|
if (ValueHasExactlyOneBitSet(N1, DAG)) {
|
||||||
Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
|
Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
|
||||||
SDValue Zero = DAG.getConstant(0, N1.getValueType());
|
if (DCI.isBeforeLegalizeOps() ||
|
||||||
return DAG.getSetCC(dl, VT, N0, Zero, Cond);
|
isCondCodeLegal(Cond, N0.getSimpleValueType())) {
|
||||||
|
SDValue Zero = DAG.getConstant(0, N1.getValueType());
|
||||||
|
return DAG.getSetCC(dl, VT, N0, Zero, Cond);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (N1.getOpcode() == ISD::AND)
|
if (N1.getOpcode() == ISD::AND)
|
||||||
if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
|
if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
|
||||||
if (ValueHasExactlyOneBitSet(N0, DAG)) {
|
if (ValueHasExactlyOneBitSet(N0, DAG)) {
|
||||||
Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
|
Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
|
||||||
SDValue Zero = DAG.getConstant(0, N0.getValueType());
|
if (DCI.isBeforeLegalizeOps() ||
|
||||||
return DAG.getSetCC(dl, VT, N1, Zero, Cond);
|
isCondCodeLegal(Cond, N1.getSimpleValueType())) {
|
||||||
|
SDValue Zero = DAG.getConstant(0, N0.getValueType());
|
||||||
|
return DAG.getSetCC(dl, VT, N1, Zero, Cond);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,18 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
|
|||||||
|
|
||||||
computeRegisterProperties();
|
computeRegisterProperties();
|
||||||
|
|
||||||
|
setCondCodeAction(ISD::SETLE, MVT::f32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETLT, MVT::f32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETOLT, MVT::f32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETOLE, MVT::f32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETULT, MVT::f32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETULE, MVT::f32, Expand);
|
||||||
|
|
||||||
|
setCondCodeAction(ISD::SETLE, MVT::i32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETLT, MVT::i32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETULE, MVT::i32, Expand);
|
||||||
|
setCondCodeAction(ISD::SETULT, MVT::i32, Expand);
|
||||||
|
|
||||||
setOperationAction(ISD::FCOS, MVT::f32, Custom);
|
setOperationAction(ISD::FCOS, MVT::f32, Custom);
|
||||||
setOperationAction(ISD::FSIN, MVT::f32, Custom);
|
setOperationAction(ISD::FSIN, MVT::f32, Custom);
|
||||||
|
|
||||||
@ -841,16 +853,19 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
|
|||||||
//
|
//
|
||||||
// SET* can match the following patterns:
|
// SET* can match the following patterns:
|
||||||
//
|
//
|
||||||
// select_cc f32, f32, -1, 0, cc_any
|
// select_cc f32, f32, -1, 0, cc_supported
|
||||||
// select_cc f32, f32, 1.0f, 0.0f, cc_any
|
// select_cc f32, f32, 1.0f, 0.0f, cc_supported
|
||||||
// select_cc i32, i32, -1, 0, cc_any
|
// select_cc i32, i32, -1, 0, cc_supported
|
||||||
//
|
//
|
||||||
|
|
||||||
// Move hardware True/False values to the correct operand.
|
// Move hardware True/False values to the correct operand.
|
||||||
if (isHWTrueValue(False) && isHWFalseValue(True)) {
|
ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
|
||||||
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);
|
std::swap(False, True);
|
||||||
CC = DAG.getCondCode(ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32));
|
CC = DAG.getCondCode(InverseCC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHWTrueValue(True) && isHWFalseValue(False) &&
|
if (isHWTrueValue(True) && isHWFalseValue(False) &&
|
||||||
@ -863,14 +878,34 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
|
|||||||
//
|
//
|
||||||
// CND* can match the following patterns:
|
// CND* can match the following patterns:
|
||||||
//
|
//
|
||||||
// select_cc f32, 0.0, f32, f32, cc_any
|
// select_cc f32, 0.0, f32, f32, cc_supported
|
||||||
// select_cc f32, 0.0, i32, i32, cc_any
|
// select_cc f32, 0.0, i32, i32, cc_supported
|
||||||
// select_cc i32, 0, f32, f32, cc_any
|
// select_cc i32, 0, f32, f32, cc_supported
|
||||||
// select_cc i32, 0, i32, i32, cc_any
|
// select_cc i32, 0, i32, i32, cc_supported
|
||||||
//
|
//
|
||||||
if (isZero(LHS) || isZero(RHS)) {
|
|
||||||
SDValue Cond = (isZero(LHS) ? RHS : LHS);
|
// Try to move the zero value to the RHS
|
||||||
SDValue Zero = (isZero(LHS) ? LHS : RHS);
|
if (isZero(LHS)) {
|
||||||
|
ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
|
||||||
|
// Try swapping the operands
|
||||||
|
ISD::CondCode CCSwapped = ISD::getSetCCSwappedOperands(CCOpcode);
|
||||||
|
if (isCondCodeLegal(CCSwapped, CompareVT.getSimpleVT())) {
|
||||||
|
std::swap(LHS, RHS);
|
||||||
|
CC = DAG.getCondCode(CCSwapped);
|
||||||
|
} else {
|
||||||
|
// Try inverting the conditon and then swapping the operands
|
||||||
|
ISD::CondCode CCInv = ISD::getSetCCInverse(CCOpcode, CompareVT.isInteger());
|
||||||
|
CCSwapped = ISD::getSetCCSwappedOperands(CCInv);
|
||||||
|
if (isCondCodeLegal(CCSwapped, CompareVT.getSimpleVT())) {
|
||||||
|
std::swap(True, False);
|
||||||
|
std::swap(LHS, RHS);
|
||||||
|
CC = DAG.getCondCode(CCSwapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isZero(RHS)) {
|
||||||
|
SDValue Cond = LHS;
|
||||||
|
SDValue Zero = RHS;
|
||||||
ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
|
ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
|
||||||
if (CompareVT != VT) {
|
if (CompareVT != VT) {
|
||||||
// Bitcast True / False to the correct types. This will end up being
|
// Bitcast True / False to the correct types. This will end up being
|
||||||
@ -880,20 +915,11 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
|
|||||||
True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
|
True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
|
||||||
False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
|
False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
|
||||||
}
|
}
|
||||||
if (isZero(LHS)) {
|
|
||||||
CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (CCOpcode) {
|
switch (CCOpcode) {
|
||||||
case ISD::SETONE:
|
case ISD::SETONE:
|
||||||
case ISD::SETUNE:
|
case ISD::SETUNE:
|
||||||
case ISD::SETNE:
|
case ISD::SETNE:
|
||||||
case ISD::SETULE:
|
|
||||||
case ISD::SETULT:
|
|
||||||
case ISD::SETOLE:
|
|
||||||
case ISD::SETOLT:
|
|
||||||
case ISD::SETLE:
|
|
||||||
case ISD::SETLT:
|
|
||||||
CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
|
CCOpcode = ISD::getSetCCInverse(CCOpcode, CompareVT == MVT::i32);
|
||||||
Temp = True;
|
Temp = True;
|
||||||
True = False;
|
True = False;
|
||||||
@ -1567,14 +1593,18 @@ SDValue R600TargetLowering::PerformDAGCombine(SDNode *N,
|
|||||||
ISD::CondCode LHSCC = cast<CondCodeSDNode>(LHS.getOperand(4))->get();
|
ISD::CondCode LHSCC = cast<CondCodeSDNode>(LHS.getOperand(4))->get();
|
||||||
LHSCC = ISD::getSetCCInverse(LHSCC,
|
LHSCC = ISD::getSetCCInverse(LHSCC,
|
||||||
LHS.getOperand(0).getValueType().isInteger());
|
LHS.getOperand(0).getValueType().isInteger());
|
||||||
return DAG.getSelectCC(SDLoc(N),
|
if (DCI.isBeforeLegalizeOps() ||
|
||||||
LHS.getOperand(0),
|
isCondCodeLegal(LHSCC, LHS.getOperand(0).getSimpleValueType()))
|
||||||
LHS.getOperand(1),
|
return DAG.getSelectCC(SDLoc(N),
|
||||||
LHS.getOperand(2),
|
LHS.getOperand(0),
|
||||||
LHS.getOperand(3),
|
LHS.getOperand(1),
|
||||||
LHSCC);
|
LHS.getOperand(2),
|
||||||
|
LHS.getOperand(3),
|
||||||
|
LHSCC);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return SDValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
case AMDGPUISD::EXPORT: {
|
case AMDGPUISD::EXPORT: {
|
||||||
|
@ -2324,54 +2324,6 @@ def KIL : Pat <
|
|||||||
(MASK_WRITE (KILLGT (f32 ZERO), $src0))
|
(MASK_WRITE (KILLGT (f32 ZERO), $src0))
|
||||||
>;
|
>;
|
||||||
|
|
||||||
// SGT Reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_LT),
|
|
||||||
(SGT $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SGE Reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc f32:$src0, f32:$src1, FP_ONE, FP_ZERO, COND_LE),
|
|
||||||
(SGE $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGT_DX10 reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc f32:$src0, f32:$src1, -1, 0, COND_LT),
|
|
||||||
(SETGT_DX10 $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGE_DX10 reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc f32:$src0, f32:$src1, -1, 0, COND_LE),
|
|
||||||
(SETGE_DX10 $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGT_INT reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc i32:$src0, i32:$src1, -1, 0, SETLT),
|
|
||||||
(SETGT_INT $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGE_INT reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc i32:$src0, i32:$src1, -1, 0, SETLE),
|
|
||||||
(SETGE_INT $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGT_UINT reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc i32:$src0, i32:$src1, -1, 0, SETULT),
|
|
||||||
(SETGT_UINT $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// SETGE_UINT reverse args
|
|
||||||
def : Pat <
|
|
||||||
(selectcc i32:$src0, i32:$src1, -1, 0, SETULE),
|
|
||||||
(SETGE_UINT $src1, $src0)
|
|
||||||
>;
|
|
||||||
|
|
||||||
// The next two patterns are special cases for handling 'true if ordered' and
|
// The next two patterns are special cases for handling 'true if ordered' and
|
||||||
// 'true if unordered' conditionals. The assumption here is that the behavior of
|
// 'true if unordered' conditionals. The assumption here is that the behavior of
|
||||||
// SETE and SNE conforms to the Direct3D 10 rules for floating point values
|
// SETE and SNE conforms to the Direct3D 10 rules for floating point values
|
||||||
|
Loading…
Reference in New Issue
Block a user