[SPARC] Don't emit deprecated FP branches when targeting v9
authorKoakuma <koachan@protonmail.com>
Thu, 17 Nov 2022 01:56:17 +0000 (20:56 -0500)
committerBrad Smith <brad@comstyle.com>
Thu, 17 Nov 2022 01:56:17 +0000 (20:56 -0500)
Don't emit deprecated v8-style FP compares & branches when targeting v9
processors.

For now, always use %fcc0, because currently the allocator requires allocatable
registers to also be spillable, which isn't the case with v9 FCC registers.

The work to enable allocation over the entire FCC register file will be done in
a future patch.

Fixes bug #17834

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D135515

llvm/lib/Target/Sparc/SparcISelLowering.cpp
llvm/lib/Target/Sparc/SparcISelLowering.h
llvm/lib/Target/Sparc/SparcInstrInfo.td
llvm/test/CodeGen/SPARC/2011-01-11-CC.ll
llvm/test/CodeGen/SPARC/64cond.ll

index 68cd43d..2665a8d 100644 (file)
@@ -1927,12 +1927,16 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case SPISD::FIRST_NUMBER:    break;
   case SPISD::CMPICC:          return "SPISD::CMPICC";
   case SPISD::CMPFCC:          return "SPISD::CMPFCC";
+  case SPISD::CMPFCC_V9:
+    return "SPISD::CMPFCC_V9";
   case SPISD::BRICC:           return "SPISD::BRICC";
   case SPISD::BPICC:
     return "SPISD::BPICC";
   case SPISD::BPXCC:
     return "SPISD::BPXCC";
   case SPISD::BRFCC:           return "SPISD::BRFCC";
+  case SPISD::BRFCC_V9:
+    return "SPISD::BRFCC_V9";
   case SPISD::SELECT_ICC:      return "SPISD::SELECT_ICC";
   case SPISD::SELECT_XCC:      return "SPISD::SELECT_XCC";
   case SPISD::SELECT_FCC:      return "SPISD::SELECT_FCC";
@@ -1992,15 +1996,14 @@ void SparcTargetLowering::computeKnownBitsForTargetNode
 // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
 static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
                              ISD::CondCode CC, unsigned &SPCC) {
-  if (isNullConstant(RHS) &&
-      CC == ISD::SETNE &&
+  if (isNullConstant(RHS) && CC == ISD::SETNE &&
       (((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)) &&
-      isOneConstant(LHS.getOperand(0)) &&
-      isNullConstant(LHS.getOperand(1))) {
+        (LHS.getOperand(3).getOpcode() == SPISD::CMPFCC ||
+         LHS.getOperand(3).getOpcode() == SPISD::CMPFCC_V9))) &&
+      isOneConstant(LHS.getOperand(0)) && isNullConstant(LHS.getOperand(1))) {
     SDValue CMPCC = LHS.getOperand(3);
     SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
     LHS = CMPCC.getOperand(0);
@@ -2567,9 +2570,10 @@ static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG,
       CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
       Opc = isV9 ? SPISD::BPICC : SPISD::BRICC;
     } else {
-      CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
+      unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
+      CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
-      Opc = SPISD::BRFCC;
+      Opc = isV9 ? SPISD::BRFCC_V9 : SPISD::BRFCC;
     }
   }
   return DAG.getNode(Opc, dl, MVT::Other, Chain, Dest,
@@ -2577,8 +2581,8 @@ static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG,
 }
 
 static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
-                              const SparcTargetLowering &TLI,
-                              bool hasHardQuad) {
+                              const SparcTargetLowering &TLI, bool hasHardQuad,
+                              bool isV9) {
   SDValue LHS = Op.getOperand(0);
   SDValue RHS = Op.getOperand(1);
   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
@@ -2603,7 +2607,8 @@ static SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG,
       CompareFlag = TLI.LowerF128Compare(LHS, RHS, SPCC, dl, DAG);
       Opc = SPISD::SELECT_ICC;
     } else {
-      CompareFlag = DAG.getNode(SPISD::CMPFCC, dl, MVT::Glue, LHS, RHS);
+      unsigned CmpOpc = isV9 ? SPISD::CMPFCC_V9 : SPISD::CMPFCC;
+      CompareFlag = DAG.getNode(CmpOpc, dl, MVT::Glue, LHS, RHS);
       Opc = SPISD::SELECT_FCC;
       if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC);
     }
@@ -3150,8 +3155,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
                                                        hasHardQuad);
   case ISD::BR_CC:
     return LowerBR_CC(Op, DAG, *this, hasHardQuad, isV9);
-  case ISD::SELECT_CC:          return LowerSELECT_CC(Op, DAG, *this,
-                                                      hasHardQuad);
+  case ISD::SELECT_CC:
+    return LowerSELECT_CC(Op, DAG, *this, hasHardQuad, isV9);
   case ISD::VASTART:            return LowerVASTART(Op, DAG, *this);
   case ISD::VAARG:              return LowerVAARG(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,
@@ -3240,6 +3245,8 @@ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
   case SP::SELECT_CC_FP_FCC:
   case SP::SELECT_CC_DFP_FCC:
   case SP::SELECT_CC_QFP_FCC:
+    if (Subtarget->isV9())
+      return expandSelectCC(MI, BB, SP::FBCOND_V9);
     return expandSelectCC(MI, BB, SP::FBCOND);
   }
 }
index 3978126..b382bef 100644 (file)
@@ -23,12 +23,14 @@ namespace llvm {
   namespace SPISD {
   enum NodeType : unsigned {
     FIRST_NUMBER = ISD::BUILTIN_OP_END,
-    CMPICC, // Compare two GPR operands, set icc+xcc.
-    CMPFCC, // Compare two FP operands, set fcc.
-    BRICC,  // Branch to dest on icc condition
-    BPICC,  // Branch to dest on icc condition, with prediction (64-bit only).
-    BPXCC,  // Branch to dest on xcc condition, with prediction (64-bit only).
-    BRFCC,  // Branch to dest on fcc condition
+    CMPICC,    // Compare two GPR operands, set icc+xcc.
+    CMPFCC,    // Compare two FP operands, set fcc.
+    CMPFCC_V9, // Compare two FP operands, set fcc (v9 variant).
+    BRICC,     // Branch to dest on icc condition
+    BPICC,    // Branch to dest on icc condition, with prediction (64-bit only).
+    BPXCC,    // Branch to dest on xcc condition, with prediction (64-bit only).
+    BRFCC,    // Branch to dest on fcc condition
+    BRFCC_V9, // Branch to dest on fcc condition (v9 variant).
     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.
index c06535f..6b15933 100644 (file)
@@ -241,10 +241,12 @@ SDTypeProfile<1, 2, [SDTCisPtrTy<0>, SDTCisPtrTy<1>]>;
 
 def SPcmpicc : SDNode<"SPISD::CMPICC", SDTSPcmpicc, [SDNPOutGlue]>;
 def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutGlue]>;
+def SPcmpfccv9 : SDNode<"SPISD::CMPFCC_V9", SDTSPcmpfcc, [SDNPOutGlue]>;
 def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 def SPbpicc : SDNode<"SPISD::BPICC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 def SPbpxcc : SDNode<"SPISD::BPXCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
+def SPbrfccv9 : SDNode<"SPISD::BRFCC_V9", SDTSPbrcc, [SDNPHasChain, SDNPInGlue]>;
 
 def SPhi    : SDNode<"SPISD::Hi", SDTIntUnaryOp>;
 def SPlo    : SDNode<"SPISD::Lo", SDTIntUnaryOp>;
@@ -962,6 +964,19 @@ let Uses = [FCC0] in {
                              "fb$cond,a $imm22", []>;
 }
 
+// Variants of FBCOND that uses V9 opcode
+let Predicates = [HasV9], Uses = [FCC0], cc = 0,
+    isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in {
+  def FBCOND_V9  : F2_3<0b101, 0, 1, (outs),
+                    (ins bprtarget:$imm19, CCOp:$cond),
+                    "fb$cond %fcc0, $imm19",
+                    [(SPbrfccv9 bb:$imm19, imm:$cond)], IIC_fpu_normal_instr>;
+  def FBCONDA_V9 : F2_3<0b101, 1, 1, (outs),
+                    (ins bprtarget:$imm19, CCOp:$cond),
+                    "fb$cond,a %fcc0, $imm19",
+                    [(SPbrfccv9 bb:$imm19, imm:$cond)], IIC_fpu_normal_instr>;
+}
+
 let Predicates = [HasV9] in
   defm BPF : FPredBranch;
 
@@ -1408,6 +1423,31 @@ let Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in {
                    Requires<[HasHardQuad]>;
 }
 
+// A.13 Floating-Point Compare (SPARC v9)
+// Note that these always write to %fcc0 instead of having its destination
+// allocated automatically.
+// This avoids complications with the scheduler sometimes wanting to spill
+// the contents of an FCC, since SPARC v9 doesn't have facilities to spill
+// an individual FCC.
+
+let Predicates = [HasV9], Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in {
+  def FCMPS_V9  : F3_3c<2, 0b110101, 0b001010001,
+                   (outs), (ins FPRegs:$rs1, FPRegs:$rs2),
+                   "fcmps %fcc0, $rs1, $rs2",
+                   [(SPcmpfccv9 f32:$rs1, f32:$rs2)],
+                   IIC_fpu_fast_instr>;
+  def FCMPD_V9  : F3_3c<2, 0b110101, 0b001010010,
+                   (outs), (ins DFPRegs:$rs1, DFPRegs:$rs2),
+                   "fcmpd %fcc0, $rs1, $rs2",
+                   [(SPcmpfccv9 f64:$rs1, f64:$rs2)],
+                   IIC_fpu_fast_instr>;
+  def FCMPQ_V9  : F3_3c<2, 0b110101, 0b001010011,
+                   (outs), (ins QFPRegs:$rs1, QFPRegs:$rs2),
+                   "fcmpq %fcc0, $rs1, $rs2",
+                   [(SPcmpfccv9 f128:$rs1, f128:$rs2)]>,
+                   Requires<[HasHardQuad]>;
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions for Thread Local Storage(TLS).
 //===----------------------------------------------------------------------===//
index a779ebb..6135b8f 100644 (file)
@@ -118,10 +118,10 @@ entry:
 ; V8:       {{fbule|fbg}} .LBB
 
 ; V9-LABEL: test_float_cc
-; V9:       fcmpd
-; V9:       {{fbl|fbuge}} .LBB
-; V9:       fcmpd
-; V9:       {{fbule|fbg}} .LBB
+; V9:       fcmpd %fcc0
+; V9:       {{fbl|fbuge}} %fcc0, .LBB
+; V9:       fcmpd %fcc0
+; V9:       {{fbule|fbg}} %fcc0, .LBB
 
    %0 = fcmp uge double %a, 0.000000e+00
    br i1 %0, label %loop, label %loop.2
index 6deeae8..ffdb10a 100644 (file)
@@ -68,7 +68,7 @@ entry:
 
 ; CHECK: selecti64_fcc
 ; CHECK: mov %i3, %i0
-; CHECK: fcmps %f1, %f3
+; CHECK: fcmps %fcc0, %f1, %f3
 ; CHECK: movul %fcc0, %i2, %i0
 ; CHECK: restore
 define i64 @selecti64_fcc(float %x, float %y, i64 %a, i64 %b) {