[llvm] r178737 - Add SPARC v9 support for select on 64-bit compares.

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed Apr 3 20:08:01 PDT 2013


Author: stoklund
Date: Wed Apr  3 22:08:00 2013
New Revision: 178737

URL: http://llvm.org/viewvc/llvm-project?rev=178737&view=rev
Log:
Add SPARC v9 support for select on 64-bit compares.

This requires v9 cmov instructions using the %xcc flags instead of the
%icc flags.

Still missing:
- Select floats on %xcc flags.
- Select i64 on %fcc flags.

Modified:
    llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/trunk/lib/Target/Sparc/SparcISelLowering.h
    llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
    llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
    llvm/trunk/test/CodeGen/SPARC/64cond.ll

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=178737&r1=178736&r2=178737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Wed Apr  3 22:08:00 2013
@@ -826,6 +826,7 @@ SparcTargetLowering::SparcTargetLowering
 
   if (Subtarget->is64Bit()) {
     setOperationAction(ISD::BR_CC, MVT::i64, Custom);
+    setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
   }
 
   // FIXME: There are instructions available for ATOMIC_FENCE
@@ -900,6 +901,7 @@ const char *SparcTargetLowering::getTarg
   case SPISD::BRXCC:      return "SPISD::BRXCC";
   case SPISD::BRFCC:      return "SPISD::BRFCC";
   case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
+  case SPISD::SELECT_XCC: return "SPISD::SELECT_XCC";
   case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
   case SPISD::Hi:         return "SPISD::Hi";
   case SPISD::Lo:         return "SPISD::Lo";
@@ -926,6 +928,7 @@ void SparcTargetLowering::computeMaskedB
   switch (Op.getOpcode()) {
   default: break;
   case SPISD::SELECT_ICC:
+  case SPISD::SELECT_XCC:
   case SPISD::SELECT_FCC:
     DAG.ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);
     DAG.ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);
@@ -946,7 +949,8 @@ static void LookThroughSetCC(SDValue &LH
   if (isa<ConstantSDNode>(RHS) &&
       cast<ConstantSDNode>(RHS)->isNullValue() &&
       CC == ISD::SETNE &&
-      ((LHS.getOpcode() == SPISD::SELECT_ICC &&
+      (((LHS.getOpcode() == SPISD::SELECT_ICC ||
+         LHS.getOpcode() == SPISD::SELECT_XCC) &&
         LHS.getOperand(3).getOpcode() == SPISD::CMPICC) ||
        (LHS.getOpcode() == SPISD::SELECT_FCC &&
         LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) &&
@@ -1064,12 +1068,13 @@ static SDValue LowerSELECT_CC(SDValue Op
   LookThroughSetCC(LHS, RHS, CC, SPCC);
 
   SDValue CompareFlag;
-  if (LHS.getValueType() == MVT::i32) {
+  if (LHS.getValueType().isInteger()) {
     // subcc returns a value
     EVT VTs[] = { LHS.getValueType(), MVT::Glue };
     SDValue Ops[2] = { LHS, RHS };
     CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
-    Opc = SPISD::SELECT_ICC;
+    Opc = LHS.getValueType() == MVT::i32 ?
+          SPISD::SELECT_ICC : SPISD::SELECT_XCC;
     if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
   } else {
     CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.h?rev=178737&r1=178736&r2=178737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.h Wed Apr  3 22:08:00 2013
@@ -30,6 +30,7 @@ namespace llvm {
       BRXCC,       // Branch to dest on xcc condition (64-bit only).
       BRFCC,       // Branch to dest on fcc condition
       SELECT_ICC,  // Select between two values using the current ICC flags.
+      SELECT_XCC,  // Select between two values using the current XCC flags.
       SELECT_FCC,  // Select between two values using the current FCC flags.
 
       Hi, Lo,      // Hi/Lo operations, typically on a global address.

Modified: llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td?rev=178737&r1=178736&r2=178737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td Wed Apr  3 22:08:00 2013
@@ -19,8 +19,8 @@ let Predicates = [Is64Bit] in {
 // The same integer registers are used for i32 and i64 values.
 // When registers hold i32 values, the high bits are don't care.
 // This give us free trunc and anyext.
-def : Pat<(i64 (anyext i32:$val)), (COPY $val)>;
-def : Pat<(i32 (trunc i64:$val)), (COPY $val)>;
+def : Pat<(i64 (anyext i32:$val)), (COPY_TO_REGCLASS $val, I64Regs)>;
+def : Pat<(i32 (trunc i64:$val)), (COPY_TO_REGCLASS $val, IntRegs)>;
 
 } // Predicates = [Is64Bit]
 
@@ -256,7 +256,30 @@ def : Pat<(truncstorei32 i64:$src, ADDRr
 // We reuse CMPICC SDNodes for compares, but use new BRXCC branch nodes for
 // 64-bit compares. See LowerBR_CC.
 
+let Predicates = [Is64Bit] in {
+
 let Uses = [ICC] in
 def BPXCC : BranchSP<0, (ins brtarget:$dst, CCOp:$cc),
                      "bp$cc %xcc, $dst",
                      [(SPbrxcc bb:$dst, imm:$cc)]>;
+
+// Conditional moves on %xcc.
+let Uses = [ICC], Constraints = "$f = $rd" in {
+def MOVXCCrr : Pseudo<(outs IntRegs:$rd),
+                      (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond),
+                      "mov$cond %xcc, $rs2, $rd",
+                      [(set i32:$rd,
+                       (SPselectxcc i32:$rs2, i32:$f, imm:$cond))]>;
+def MOVXCCri : Pseudo<(outs IntRegs:$rd),
+                      (ins i32imm:$i, IntRegs:$f, CCOp:$cond),
+                      "mov$cond %xcc, $i, $rd",
+                      [(set i32:$rd,
+                       (SPselecticc simm11:$i, i32:$f, imm:$cond))]>;
+} // Uses, Constraints
+
+def : Pat<(SPselectxcc i64:$t, i64:$f, imm:$cond),
+          (MOVXCCrr $t, $f, imm:$cond)>;
+def : Pat<(SPselectxcc (i64 simm11:$t), i64:$f, imm:$cond),
+          (MOVXCCri (as_i32imm $t), $f, imm:$cond)>;
+
+} // Predicates = [Is64Bit]

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=178737&r1=178736&r2=178737&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Wed Apr  3 22:08:00 2013
@@ -114,6 +114,7 @@ def SPftoi  : SDNode<"SPISD::FTOI", SDTS
 def SPitof  : SDNode<"SPISD::ITOF", SDTSPITOF>;
 
 def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>;
+def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>;
 def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc, [SDNPInGlue]>;
 
 //  These are target-independent nodes, but have target-specific formats.

Modified: llvm/trunk/test/CodeGen/SPARC/64cond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/64cond.ll?rev=178737&r1=178736&r2=178737&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/64cond.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/64cond.ll Wed Apr  3 22:08:00 2013
@@ -32,3 +32,25 @@ if.then:
 if.end:
   ret void
 }
+
+; CHECK: selecti32_xcc
+; CHECK: subcc %i0, %i1
+; CHECK: movg %xcc, %i2, %i3
+; CHECK: or %g0, %i3, %i0
+define i32 @selecti32_xcc(i64 %x, i64 %y, i32 %a, i32 %b) {
+entry:
+  %tobool = icmp sgt i64 %x, %y
+  %rv = select i1 %tobool, i32 %a, i32 %b
+  ret i32 %rv
+}
+
+; CHECK: selecti64_xcc
+; CHECK: subcc %i0, %i1
+; CHECK: movg %xcc, %i2, %i3
+; CHECK: or %g0, %i3, %i0
+define i64 @selecti64_xcc(i64 %x, i64 %y, i64 %a, i64 %b) {
+entry:
+  %tobool = icmp sgt i64 %x, %y
+  %rv = select i1 %tobool, i64 %a, i64 %b
+  ret i64 %rv
+}





More information about the llvm-commits mailing list