summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authortstellar <tstellar@91177308-0d34-0410-b5e6-96231b3b80d8>2012-10-09 18:49:05 +0000
committertstellar <tstellar@91177308-0d34-0410-b5e6-96231b3b80d8>2012-10-09 18:49:05 +0000
commit76b2b25443fb89754214b0cd2928d7d57e8e5c99 (patch)
treebad433a93272c85d646af6364dd76a5f66ce1f4c /lib
parent6b24b44a2fa24c9987b9b8d753fa8ffa841e11ac (diff)
R600: Prefer lowering SELECT_CC to CND* instructions over SET* instructions
SET* instructions are more expensive, because in some cases they require additional instructions to convert their result to the correct type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/R600/@165527 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/AMDGPU/R600ISelLowering.cpp92
1 files changed, 50 insertions, 42 deletions
diff --git a/lib/Target/AMDGPU/R600ISelLowering.cpp b/lib/Target/AMDGPU/R600ISelLowering.cpp
index be92f74b25..121f49426e 100644
--- a/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -550,6 +550,56 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
// LHS and RHS are guaranteed to be the same value type
EVT CompareVT = LHS.getValueType();
+ // Check if we can lower this to a native operation.
+
+ // Try to lower to a CND* instruction:
+ // CND* instructions requires RHS to be zero. Some SELECT_CC nodes that
+ // can be lowered to CND* instructions can also be lowered to SET*
+ // instructions. CND* instructions are cheaper, because they dont't
+ // require additional instructions to convert their result to the correct
+ // value type, so this check should be first.
+ if (isZero(LHS) || isZero(RHS)) {
+ SDValue Cond = (isZero(LHS) ? RHS : LHS);
+ SDValue Zero = (isZero(LHS) ? LHS : RHS);
+ ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
+ if (CompareVT != VT) {
+ // Bitcast True / False to the correct types. This will end up being
+ // a nop, but it allows us to define only a single pattern in the
+ // .TD files for each CND* instruction rather than having to have
+ // one pattern for integer True/False and one for fp True/False
+ True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
+ False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
+ }
+ if (isZero(LHS)) {
+ CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
+ }
+
+ switch (CCOpcode) {
+ case ISD::SETONE:
+ case ISD::SETUNE:
+ 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);
+ Temp = True;
+ True = False;
+ False = Temp;
+ break;
+ default:
+ break;
+ }
+ SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
+ Cond, Zero,
+ True, False,
+ DAG.getCondCode(CCOpcode));
+ return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
+ }
+
+ // Try to lower to a SET* instruction:
// We need all the operands of SELECT_CC to have the same value type, so if
// necessary we need to change True and False to be the same type as LHS and
// RHS, and then convert the result of the select_cc back to the correct type.
@@ -592,48 +642,6 @@ SDValue R600TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
if (isHWTrueValue(False) && isHWFalseValue(True)) {
}
- // Check if we can lower this to a native operation.
- // CND* instructions requires all operands to have the same type,
- // and RHS to be zero.
-
- if (isZero(LHS) || isZero(RHS)) {
- SDValue Cond = (isZero(LHS) ? RHS : LHS);
- SDValue Zero = (isZero(LHS) ? LHS : RHS);
- ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
- if (CompareVT != VT) {
- True = DAG.getNode(ISD::BITCAST, DL, CompareVT, True);
- False = DAG.getNode(ISD::BITCAST, DL, CompareVT, False);
- }
- if (isZero(LHS)) {
- CCOpcode = ISD::getSetCCSwappedOperands(CCOpcode);
- }
-
- switch (CCOpcode) {
- case ISD::SETONE:
- case ISD::SETUNE:
- 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);
- Temp = True;
- True = False;
- False = Temp;
- break;
- default:
- break;
- }
- SDValue SelectNode = DAG.getNode(ISD::SELECT_CC, DL, CompareVT,
- Cond, Zero,
- True, False,
- DAG.getCondCode(CCOpcode));
- return DAG.getNode(ISD::BITCAST, DL, VT, SelectNode);
- }
-
-
// If we make it this for it means we have no native instructions to handle
// this SELECT_CC, so we must lower it.
SDValue HWTrue, HWFalse;