[llvm] r178621 - Add 64-bit compare + branch for SPARC v9.

Jakob Stoklund Olesen stoklund at 2pi.dk
Tue Apr 2 21:41:44 PDT 2013


Author: stoklund
Date: Tue Apr  2 23:41:44 2013
New Revision: 178621

URL: http://llvm.org/viewvc/llvm-project?rev=178621&view=rev
Log:
Add 64-bit compare + branch for SPARC v9.

The same compare instruction is used for 32-bit and 64-bit compares. It
sets two different sets of flags: icc and xcc.

This patch adds a conditional branch instruction using the xcc flags for
64-bit compares.

Added:
    llvm/trunk/test/CodeGen/SPARC/64cond.ll
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/lib/Target/Sparc/SparcRegisterInfo.td

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=178621&r1=178620&r2=178621&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Tue Apr  2 23:41:44 2013
@@ -824,6 +824,10 @@ SparcTargetLowering::SparcTargetLowering
   setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
   setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
 
+  if (Subtarget->is64Bit()) {
+    setOperationAction(ISD::BR_CC, MVT::i64, Custom);
+  }
+
   // FIXME: There are instructions available for ATOMIC_FENCE
   // on SparcV8 and later.
   setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
@@ -893,6 +897,7 @@ const char *SparcTargetLowering::getTarg
   case SPISD::CMPICC:     return "SPISD::CMPICC";
   case SPISD::CMPFCC:     return "SPISD::CMPFCC";
   case SPISD::BRICC:      return "SPISD::BRICC";
+  case SPISD::BRXCC:      return "SPISD::BRXCC";
   case SPISD::BRFCC:      return "SPISD::BRFCC";
   case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC";
   case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC";
@@ -1029,12 +1034,13 @@ static SDValue LowerBR_CC(SDValue Op, Se
 
   // Get the condition flag.
   SDValue CompareFlag;
-  if (LHS.getValueType() == MVT::i32) {
-    EVT VTs[] = { MVT::i32, MVT::Glue };
+  if (LHS.getValueType().isInteger()) {
+    EVT VTs[] = { LHS.getValueType(), MVT::Glue };
     SDValue Ops[2] = { LHS, RHS };
     CompareFlag = DAG.getNode(SPISD::CMPICC, dl, VTs, Ops, 2).getValue(1);
     if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
-    Opc = SPISD::BRICC;
+    // 32-bit compares use the icc flags, 64-bit uses the xcc flags.
+    Opc = LHS.getValueType() == MVT::i32 ? SPISD::BRICC : SPISD::BRXCC;
   } else {
     CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
     if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);

Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.h?rev=178621&r1=178620&r2=178621&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.h (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.h Tue Apr  2 23:41:44 2013
@@ -24,9 +24,10 @@ namespace llvm {
   namespace SPISD {
     enum {
       FIRST_NUMBER = ISD::BUILTIN_OP_END,
-      CMPICC,      // Compare two GPR operands, set icc.
+      CMPICC,      // Compare two GPR operands, set icc+xcc.
       CMPFCC,      // Compare two FP operands, set fcc.
       BRICC,       // Branch to dest on icc condition
+      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_FCC,  // Select between two values using the current FCC flags.

Modified: llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td?rev=178621&r1=178620&r2=178621&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td Tue Apr  2 23:41:44 2013
@@ -161,6 +161,8 @@ def : Pat<(sube i64:$a, i64:$b), (SUBXrr
 def : Pat<(addc i64:$a, i64:$b), (ADDCCrr $a, $b)>;
 def : Pat<(subc i64:$a, i64:$b), (SUBCCrr $a, $b)>;
 
+def : Pat<(SPcmpicc i64:$a, i64:$b), (SUBCCrr $a, $b)>;
+
 // Register-immediate instructions.
 
 def : Pat<(and i64:$a, (i64 simm13:$b)), (ANDri $a, (as_i32imm $b))>;
@@ -170,6 +172,8 @@ def : Pat<(xor i64:$a, (i64 simm13:$b)),
 def : Pat<(add i64:$a, (i64 simm13:$b)), (ADDri $a, (as_i32imm $b))>;
 def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
 
+def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (SUBCCri $a, (as_i32imm $b))>;
+
 } // Predicates = [Is64Bit]
 
 
@@ -239,3 +243,20 @@ def : Pat<(truncstorei32 i64:$src, ADDRr
 def : Pat<(truncstorei32 i64:$src, ADDRri:$addr), (STri  ADDRri:$addr, $src)>;
 
 } // Predicates = [Is64Bit]
+
+
+//===----------------------------------------------------------------------===//
+// 64-bit Conditionals.
+//===----------------------------------------------------------------------===//
+//
+// Flag-setting instructions like subcc and addcc set both icc and xcc flags.
+// The icc flags correspond to the 32-bit result, and the xcc are for the
+// full 64-bit result.
+//
+// We reuse CMPICC SDNodes for compares, but use new BRXCC branch nodes for
+// 64-bit compares. See LowerBR_CC.
+
+let Uses = [ICC] in
+def BPXCC : BranchSP<0, (ins brtarget:$dst, CCOp:$cc),
+                     "bp$cc %xcc, $dst",
+                     [(SPbrxcc bb:$dst, imm:$cc)]>;

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=178621&r1=178620&r2=178621&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Tue Apr  2 23:41:44 2013
@@ -104,6 +104,7 @@ SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCis
 def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutGlue]>;
 def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;
 def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
+def SPbrxcc : SDNode<"SPISD::BRXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 
 def SPhi    : SDNode<"SPISD::Hi", SDTIntUnaryOp>;

Modified: llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td?rev=178621&r1=178620&r2=178621&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcRegisterInfo.td Tue Apr  2 23:41:44 2013
@@ -43,7 +43,7 @@ class Rd<bits<5> num, string n, list<Reg
 }
 
 // Control Registers
-def ICC : SparcCtrlReg<"ICC">;
+def ICC : SparcCtrlReg<"ICC">; // This represents icc and xcc in 64-bit code.
 def FCC : SparcCtrlReg<"FCC">;
 
 // Y register

Added: llvm/trunk/test/CodeGen/SPARC/64cond.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/64cond.ll?rev=178621&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/64cond.ll (added)
+++ llvm/trunk/test/CodeGen/SPARC/64cond.ll Tue Apr  2 23:41:44 2013
@@ -0,0 +1,34 @@
+; RUN: llc < %s -march=sparcv9 | FileCheck %s
+; Testing 64-bit conditionals.
+
+; CHECK: cmpri
+; CHECK: subcc %i1, 1
+; CHECK: bpe %xcc,
+define void @cmpri(i64* %p, i64 %x) {
+entry:
+  %tobool = icmp eq i64 %x, 1
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:
+  store i64 %x, i64* %p, align 8
+  br label %if.end
+
+if.end:
+  ret void
+}
+
+; CHECK: cmprr
+; CHECK: subcc %i1, %i2
+; CHECK: bpgu %xcc,
+define void @cmprr(i64* %p, i64 %x, i64 %y) {
+entry:
+  %tobool = icmp ugt i64 %x, %y
+  br i1 %tobool, label %if.end, label %if.then
+
+if.then:
+  store i64 %x, i64* %p, align 8
+  br label %if.end
+
+if.end:
+  ret void
+}





More information about the llvm-commits mailing list