Skip to content

[Xtensa] Implement lowering SELECT_CC/BRCC for Xtensa FP Option. #145544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

andreisfr
Copy link
Contributor

Also minor format changes in disassembler test for Xtensa FP Option.

Also minor format changes in disassembler test for Xtensa FP Option.
@llvmbot llvmbot added mc Machine (object) code backend:Xtensa labels Jun 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-backend-xtensa

@llvm/pr-subscribers-mc

Author: Andrei Safronov (andreisfr)

Changes

Also minor format changes in disassembler test for Xtensa FP Option.


Patch is 39.39 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/145544.diff

8 Files Affected:

  • (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+131-12)
  • (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.h (+5)
  • (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp (+27)
  • (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+27-1)
  • (modified) llvm/lib/Target/Xtensa/XtensaOperators.td (+7-3)
  • (modified) llvm/test/CodeGen/Xtensa/float-arith.ll (+20-1)
  • (added) llvm/test/CodeGen/Xtensa/select-cc-fp.ll (+457)
  • (modified) llvm/test/MC/Disassembler/Xtensa/fp.txt (+104-104)
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index d51c573282da7..641cdde31ebcc 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -110,12 +110,18 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
 
   setOperationAction(ISD::BR_CC, MVT::i32, Legal);
   setOperationAction(ISD::BR_CC, MVT::i64, Expand);
-  setOperationAction(ISD::BR_CC, MVT::f32, Expand);
 
   setOperationAction(ISD::SELECT, MVT::i32, Expand);
   setOperationAction(ISD::SELECT, MVT::f32, Expand);
   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
-  setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
+
+  if (Subtarget.hasSingleFloat()) {
+    setOperationAction(ISD::BR_CC, MVT::f32, Legal);
+    setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
+  } else {
+    setOperationAction(ISD::BR_CC, MVT::f32, Expand);
+    setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
+  }
 
   setOperationAction(ISD::SETCC, MVT::i32, Expand);
   setOperationAction(ISD::SETCC, MVT::f32, Expand);
@@ -841,21 +847,94 @@ static unsigned getBranchOpcode(ISD::CondCode Cond) {
   }
 }
 
+static void GetFPBranchKind(ISD::CondCode Cond, unsigned &BrKind,
+                            unsigned &CmpKind) {
+  switch (Cond) {
+  case ISD::SETUNE:
+    BrKind = Xtensa::BF;
+    CmpKind = Xtensa::OEQ_S;
+    break;
+  case ISD::SETUO:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::UN_S;
+    break;
+  case ISD::SETO:
+    BrKind = Xtensa::BF;
+    CmpKind = Xtensa::UN_S;
+    break;
+  case ISD::SETUEQ:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::UEQ_S;
+    break;
+  case ISD::SETULE:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::ULE_S;
+    break;
+  case ISD::SETULT:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::ULT_S;
+    break;
+  case ISD::SETEQ:
+  case ISD::SETOEQ:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::OEQ_S;
+    break;
+  case ISD::SETNE:
+    BrKind = Xtensa::BF;
+    CmpKind = Xtensa::OEQ_S;
+    break;
+  case ISD::SETLE:
+  case ISD::SETOLE:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::OLE_S;
+    break;
+  case ISD::SETLT:
+  case ISD::SETOLT:
+    BrKind = Xtensa::BT;
+    CmpKind = Xtensa::OLT_S;
+    break;
+  case ISD::SETGE:
+    BrKind = Xtensa::BF;
+    CmpKind = Xtensa::OLT_S;
+    break;
+  case ISD::SETGT:
+    BrKind = Xtensa::BF;
+    CmpKind = Xtensa::OLE_S;
+    break;
+  default:
+    llvm_unreachable("Invalid condition!");
+    break;
+  }
+}
+
 SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
                                              SelectionDAG &DAG) const {
   SDLoc DL(Op);
-  EVT Ty = Op.getOperand(0).getValueType();
+  EVT Ty = Op.getValueType();
   SDValue LHS = Op.getOperand(0);
   SDValue RHS = Op.getOperand(1);
   SDValue TrueValue = Op.getOperand(2);
   SDValue FalseValue = Op.getOperand(3);
   ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
 
-  unsigned BrOpcode = getBranchOpcode(CC);
-  SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
+  if (LHS.getValueType() == MVT::i32) {
+    unsigned BrOpcode = getBranchOpcode(CC);
+    SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
 
-  return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
-                     FalseValue, TargetCC);
+    SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
+                              FalseValue, TargetCC);
+    return Res;
+  } else {
+    assert(LHS.getValueType() == MVT::f32 &&
+           "We expect MVT::f32 type of the LHS Operand in SELECT_CC");
+    unsigned BrOpcode;
+    unsigned CmpOpCode;
+    GetFPBranchKind(CC, BrOpcode, CmpOpCode);
+    SDValue TargetCC = DAG.getConstant(CmpOpCode, DL, MVT::i32);
+    SDValue TargetBC = DAG.getConstant(BrOpcode, DL, MVT::i32);
+    return DAG.getNode(XtensaISD::SELECT_CC_FP, DL, Ty,
+                       {LHS, RHS, TrueValue, FalseValue, TargetCC, TargetBC});
+  }
 }
 
 SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
@@ -1408,6 +1487,8 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
     return "XtensaISD::RETW";
   case XtensaISD::SELECT_CC:
     return "XtensaISD::SELECT_CC";
+  case XtensaISD::SELECT_CC_FP:
+    return "XtensaISD::SELECT_CC_FP";
   case XtensaISD::SRCL:
     return "XtensaISD::SRCL";
   case XtensaISD::SRCR:
@@ -1450,7 +1531,6 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
   MachineOperand &RHS = MI.getOperand(2);
   MachineOperand &TrueValue = MI.getOperand(3);
   MachineOperand &FalseValue = MI.getOperand(4);
-  unsigned BrKind = MI.getOperand(5).getImm();
 
   // To "insert" a SELECT_CC instruction, we actually have to insert
   // CopyMBB and SinkMBB  blocks and add branch to MBB. We build phi
@@ -1482,10 +1562,25 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
   MBB->addSuccessor(CopyMBB);
   MBB->addSuccessor(SinkMBB);
 
-  BuildMI(MBB, DL, TII.get(BrKind))
-      .addReg(LHS.getReg())
-      .addReg(RHS.getReg())
-      .addMBB(SinkMBB);
+  if ((MI.getOpcode() == Xtensa::SELECT_CC_FP_FP) ||
+      (MI.getOpcode() == Xtensa::SELECT_CC_FP_INT)) {
+    unsigned CmpKind = MI.getOperand(5).getImm();
+    unsigned BrKind = MI.getOperand(6).getImm();
+    MCPhysReg BReg = Xtensa::B0;
+
+    BuildMI(MBB, DL, TII.get(CmpKind), BReg)
+        .addReg(LHS.getReg())
+        .addReg(RHS.getReg());
+    BuildMI(MBB, DL, TII.get(BrKind))
+        .addReg(BReg, RegState::Kill)
+        .addMBB(SinkMBB);
+  } else {
+    unsigned BrKind = MI.getOperand(5).getImm();
+    BuildMI(MBB, DL, TII.get(BrKind))
+        .addReg(LHS.getReg())
+        .addReg(RHS.getReg())
+        .addMBB(SinkMBB);
+  }
 
   CopyMBB->addSuccessor(SinkMBB);
 
@@ -1510,6 +1605,30 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
   const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
 
   switch (MI.getOpcode()) {
+  case Xtensa::BRCC_FP: {
+    MachineOperand &Cond = MI.getOperand(0);
+    MachineOperand &LHS = MI.getOperand(1);
+    MachineOperand &RHS = MI.getOperand(2);
+    MachineBasicBlock *TargetBB = MI.getOperand(3).getMBB();
+    unsigned BrKind = 0;
+    unsigned CmpKind = 0;
+    ISD::CondCode CondCode = (ISD::CondCode)Cond.getImm();
+    unsigned BReg = Xtensa::B0;
+
+    GetFPBranchKind(CondCode, BrKind, CmpKind);
+    BuildMI(*MBB, MI, DL, TII.get(CmpKind), BReg)
+        .addReg(LHS.getReg())
+        .addReg(RHS.getReg());
+    BuildMI(*MBB, MI, DL, TII.get(BrKind))
+        .addReg(BReg, RegState::Kill)
+        .addMBB(TargetBB);
+
+    MI.eraseFromParent();
+    return MBB;
+  }
+  case Xtensa::SELECT_CC_FP_FP:
+  case Xtensa::SELECT_CC_FP_INT:
+  case Xtensa::SELECT_CC_INT_FP:
   case Xtensa::SELECT:
     return emitSelectCC(MI, MBB);
   case Xtensa::S8I:
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.h b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
index b6f2ebe21c940..e9ccf50041a3d 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.h
@@ -50,6 +50,11 @@ enum {
   // the lhs and rhs (ops #0 and #1) of a conditional expression with the
   // condition code in op #4
   SELECT_CC,
+  // Select with condition operator - This selects between a true value and
+  // a false value (ops #2 and #3) based on the boolean result of comparing
+  // f32 operands lhs and rhs (ops #0 and #1) of a conditional expression
+  // with the condition code in op #4 and boolean branch kind in op #5
+  SELECT_CC_FP,
 
   // SRCL(R) performs shift left(right) of the concatenation of 2 registers
   // and returns high(low) 32-bit part of 64-bit result
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index 896e2f8f1c01c..55c0729a0c9e7 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -261,6 +261,12 @@ bool XtensaInstrInfo::reverseBranchCondition(
   case Xtensa::BGEZ:
     Cond[0].setImm(Xtensa::BLTZ);
     return false;
+  case Xtensa::BF:
+    Cond[0].setImm(Xtensa::BT);
+    return false;
+  case Xtensa::BT:
+    Cond[0].setImm(Xtensa::BF);
+    return false;
   default:
     report_fatal_error("Invalid branch condition!");
   }
@@ -294,6 +300,9 @@ XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
   case Xtensa::BLTZ:
   case Xtensa::BGEZ:
     return MI.getOperand(1).getMBB();
+  case Xtensa::BT:
+  case Xtensa::BF:
+    return MI.getOperand(1).getMBB();
   default:
     llvm_unreachable("Unknown branch opcode");
   }
@@ -329,6 +338,10 @@ bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
   case Xtensa::BGEZ:
     BrOffset -= 4;
     return isIntN(12, BrOffset);
+  case Xtensa::BT:
+  case Xtensa::BF:
+    BrOffset -= 4;
+    return isIntN(8, BrOffset);
   default:
     llvm_unreachable("Unknown branch opcode");
   }
@@ -581,6 +594,10 @@ unsigned XtensaInstrInfo::insertConstBranchAtInst(
   case Xtensa::BGEZ:
     MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
     break;
+  case Xtensa::BT:
+  case Xtensa::BF:
+    MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
+    break;
   default:
     llvm_unreachable("Invalid branch type!");
   }
@@ -641,6 +658,10 @@ unsigned XtensaInstrInfo::insertBranchAtInst(MachineBasicBlock &MBB,
   case Xtensa::BGEZ:
     MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
     break;
+  case Xtensa::BT:
+  case Xtensa::BF:
+    MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
+    break;
   default:
     report_fatal_error("Invalid branch type!");
   }
@@ -689,6 +710,12 @@ bool XtensaInstrInfo::isBranch(const MachineBasicBlock::iterator &MI,
     Target = &MI->getOperand(1);
     return true;
 
+  case Xtensa::BT:
+  case Xtensa::BF:
+    Cond[0].setImm(OpCode);
+    Target = &MI->getOperand(1);
+    return true;
+
   default:
     assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
     return false;
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 1335c6faff6b7..e8381a74de1ef 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -416,7 +416,6 @@ def BBSI : RRI8_Inst<0x07, (outs),
 }
 
 def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>;
-
 //===----------------------------------------------------------------------===//
 // Call and jump instructions
 //===----------------------------------------------------------------------===//
@@ -1310,6 +1309,33 @@ let AddedComplexity = 10 in
 def : Pat<(f32 (load (Xtensa_pcrel_wrapper tconstpool:$in))),
           (WFR (L32R tconstpool:$in))>;
 
+//===----------------------------------------------------------------------===//
+// SelectCC and BranchCC instructions with FP operands
+//===----------------------------------------------------------------------===//
+
+let usesCustomInserter = 1, Predicates = [HasSingleFloat] in {
+  def SELECT_CC_INT_FP : Pseudo<(outs FPR:$dst), (ins AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, i32imm:$cond),
+                               "!select_cc_int_fp $dst, $lhs, $rhs, $t, $f, $cond",
+                               [(set FPR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, imm:$cond))]>;
+  def SELECT_CC_FP_INT : Pseudo<(outs AR:$dst), (ins FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, i32imm:$cond, i32imm:$brkind),
+                               "!select_cc_fp_int $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
+                               [(set AR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, imm:$cond, imm:$brkind))]>;
+  def SELECT_CC_FP_FP : Pseudo<(outs FPR:$dst), (ins FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, i32imm:$cond, i32imm:$brkind),
+                              "!select_cc_fp_fp $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
+                              [(set FPR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, imm:$cond, imm:$brkind))]>;
+}
+
+let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, isBarrier = 1, Predicates = [HasSingleFloat] in {
+  def BRCC_FP : Pseudo<(outs), (ins i32imm:$cond, FPR:$lhs, FPR:$rhs, brtarget:$target),
+                      "!brcc_fp $cond, $lhs, $rhs, $target", []>;
+}
+
+def cond_as_i32imm : SDNodeXForm<cond, [{
+  return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
+}]>;
+
+def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t,  bb:$target), (BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;
+
 //===----------------------------------------------------------------------===//
 // Region Protection feature instructions
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaOperators.td b/llvm/lib/Target/Xtensa/XtensaOperators.td
index fea13c2298d97..a5c6b59d624e1 100644
--- a/llvm/lib/Target/Xtensa/XtensaOperators.td
+++ b/llvm/lib/Target/Xtensa/XtensaOperators.td
@@ -21,14 +21,15 @@ def SDT_XtensaBrJT                : SDTypeProfile<0, 2,
                                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
 
 def SDT_XtensaSelectCC            : SDTypeProfile<1, 5,
-                                                 [SDTCisSameAs<0, 1>,
-                                                  SDTCisSameAs<2, 3>,
+                                                 [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>,
+                                                  SDTCisSameAs<3, 4>,
                                                   SDTCisVT<5, i32>]>;
 
 def SDT_XtensaCmp                 : SDTypeProfile<1, 2, [SDTCisVT<0, v1i1>, SDTCisVT<1, f32>, SDTCisVT<2, f32>]>;
 def SDT_XtensaMADD                : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisVT<0, f32>]>;
 def SDT_XtensaMOVS                : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisVT<0, f32>]>;
-def SDT_XtensaSelectCCFP          : SDTypeProfile<1, 5, [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisVT<5, i32>]>;
+def SDT_XtensaSelectCCFP          : SDTypeProfile<1, 6, [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>,
+                                                         SDTCisVT<5, i32>, SDTCisVT<6, i32>]>;
 
 def SDT_XtensaSRC                 : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
                                                          SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
@@ -87,3 +88,6 @@ def Xtensa_cmpuo      : SDNode<"XtensaISD::CMPUO", SDT_XtensaCmp, [SDNPOutGlue]>
 def Xtensa_madd: SDNode<"XtensaISD::MADD", SDT_XtensaMADD, [SDNPInGlue]>;
 def Xtensa_msub: SDNode<"XtensaISD::MSUB", SDT_XtensaMADD, [SDNPInGlue]>;
 def Xtensa_movs: SDNode<"XtensaISD::MOVS", SDT_XtensaMOVS, [SDNPInGlue]>;
+
+def Xtensa_select_cc_fp: SDNode<"XtensaISD::SELECT_CC_FP", SDT_XtensaSelectCCFP,
+                               [SDNPInGlue]>;
diff --git a/llvm/test/CodeGen/Xtensa/float-arith.ll b/llvm/test/CodeGen/Xtensa/float-arith.ll
index 2b7186c44aebf..d9369a50c856f 100644
--- a/llvm/test/CodeGen/Xtensa/float-arith.ll
+++ b/llvm/test/CodeGen/Xtensa/float-arith.ll
@@ -568,7 +568,6 @@ define float @round_f32(float %a) nounwind {
   ret float %res
 }
 
-
 define float @fneg_s(float %a) nounwind {
 ; XTENSA-LABEL: fneg_s:
 ; XTENSA:       # %bb.0:
@@ -601,3 +600,23 @@ define i32 @fptoui(float %f) {
   ret i32 %conv
 }
 
+define float @copysign_f32(float %a, float %b) {
+; XTENSA-LABEL: copysign_f32:
+; XTENSA:         .cfi_startproc
+; XTENSA-NEXT:  # %bb.0: # %entry
+; XTENSA-NEXT:    l32r a8, .LCPI35_0
+; XTENSA-NEXT:    and a8, a3, a8
+; XTENSA-NEXT:    l32r a9, .LCPI35_1
+; XTENSA-NEXT:    and a9, a2, a9
+; XTENSA-NEXT:    wfr f8, a9
+; XTENSA-NEXT:    movi a9, 0
+; XTENSA-NEXT:    beq a8, a9, .LBB35_2
+; XTENSA-NEXT:  # %bb.1:
+; XTENSA-NEXT:    neg.s f8, f8
+; XTENSA-NEXT:  .LBB35_2: # %entry
+; XTENSA-NEXT:    rfr a2, f8
+; XTENSA-NEXT:    ret
+entry:
+  %c = call float @llvm.copysign.f32(float %a, float %b)
+  ret float %c
+}
diff --git a/llvm/test/CodeGen/Xtensa/select-cc-fp.ll b/llvm/test/CodeGen/Xtensa/select-cc-fp.ll
new file mode 100644
index 0000000000000..ee45ef006123c
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/select-cc-fp.ll
@@ -0,0 +1,457 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=xtensa -mattr=+fp -disable-block-placement -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s
+
+define float @brcc_oeq(float %a, float %b) nounwind {
+; CHECK-LABEL: brcc_oeq:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    wfr f8, a3
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    oeq.s b0, f9, f8
+; CHECK-NEXT:    bf b0, .LBB0_2
+; CHECK-NEXT:  # %bb.1: # %t1
+; CHECK-NEXT:    l32r a8, .LCPI0_1
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    add.s f8, f9, f8
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2: # %t2
+; CHECK-NEXT:    l32r a8, .LCPI0_0
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    add.s f8, f8, f9
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+  %wb = fcmp oeq float %a, %b
+  br i1 %wb, label %t1, label %t2
+t1:
+  %t1v = fadd float %a, 4.0
+  br label %exit
+t2:
+  %t2v = fadd float %b, 8.0
+  br label %exit
+exit:
+  %v = phi float [ %t1v, %t1 ], [ %t2v, %t2 ]
+  ret float %v
+}
+
+define float @brcc_ogt(float %a, float %b) nounwind {
+; CHECK-LABEL: brcc_ogt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    wfr f8, a3
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    ule.s b0, f9, f8
+; CHECK-NEXT:    bt b0, .LBB1_2
+; CHECK-NEXT:  # %bb.1: # %t1
+; CHECK-NEXT:    l32r a8, .LCPI1_1
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    add.s f8, f9, f8
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2: # %t2
+; CHECK-NEXT:    l32r a8, .LCPI1_0
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    add.s f8, f8, f9
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+  %wb = fcmp ogt float %a, %b
+  br i1 %wb, label %t1, label %t2
+t1:
+  %t1v = fadd float %a, 4.0
+  br label %exit
+t2:
+  %t2v = fadd float %b, 8.0
+  br label %exit
+exit:
+  %v = phi float [ %t1v, %t1 ], [ %t2v, %t2 ]
+  ret float %v
+}
+
+define float @brcc_oge(float %a, float %b) nounwind {
+; CHECK-LABEL: brcc_oge:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    wfr f8, a3
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    ult.s b0, f9, f8
+; CHECK-NEXT:    bt b0, .LBB2_2
+; CHECK-NEXT:  # %bb.1: # %t1
+; CHECK-NEXT:    l32r a8, .LCPI2_1
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    add.s f8, f9, f8
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB2_2: # %t2
+; CHECK-NEXT:    l32r a8, .LCPI2_0
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    add.s f8, f8, f9
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+  %wb = fcmp oge float %a, %b
+  br i1 %wb, label %t1, label %t2
+t1:
+  %t1v = fadd float %a, 4.0
+  br label %exit
+t2:
+  %t2v = fadd float %b, 8.0
+  br label %exit
+exit:
+  %v = phi float [ %t1v, %t1 ], [ %t2v, %t2 ]
+  ret float %v
+}
+
+define float @brcc_olt(float %a, float %b) nounwind {
+; CHECK-LABEL: brcc_olt:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    wfr f8, a3
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    ule.s b0, f8, f9
+; CHECK-NEXT:    bt b0, .LBB3_2
+; CHECK-NEXT:  # %bb.1: # %t1
+; CHECK-NEXT:    l32r a8, .LCPI3_1
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    add.s f8, f9, f8
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB3_2: # %t2
+; CHECK-NEXT:    l32r a8, .LCPI3_0
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    add.s f8, f8, f9
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+  %wb = fcmp olt float %a, %b
+  br i1 %wb, label %t1, label %t2
+t1:
+  %t1v = fadd float %a, 4.0
+  br label %exit
+t2:
+  %t2v = fadd float %b, 8.0
+  br label %exit
+exit:
+  %v = phi float [ %t1v, %t1 ], [ %t2v, %t2 ]
+  ret float %v
+}
+
+define float @brcc_ole(float %a, float %b) nounwind {
+; CHECK-LABEL: brcc_ole:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    wfr f8, a3
+; CHECK-NEXT:    wfr f9, a2
+; CHECK-NEXT:    ult.s b0, f8, f9
+; CHECK-NEXT:    bt b0, .LBB4_2
+; CHECK-NEXT:  # %bb.1: # %t1
+; CHECK-NEXT:    l32r a8, .LCPI4_1
+; CHECK-NEXT:    wfr f8, a8
+; CHECK-NEXT:    add.s f8, f9, f8
+; CHECK-NEXT:    rfr a2, f8
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB4_2: # %t2
+; CHECK-NEXT:    l32r a8, .LCPI4_0
+; CHECK-NEXT:    wfr f9, a8
+; CHECK-NEXT:    add.s f8, f8, f9
+; CHECK-NEXT...
[truncated]

break;
default:
llvm_unreachable("Invalid condition!");
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove dead break

SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
FalseValue, TargetCC);
return Res;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No else after return

return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
FalseValue, TargetCC);
SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
FalseValue, TargetCC);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Losing flags from the original select?

Comment on lines +1565 to +1566
if ((MI.getOpcode() == Xtensa::SELECT_CC_FP_FP) ||
(MI.getOpcode() == Xtensa::SELECT_CC_FP_INT)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ((MI.getOpcode() == Xtensa::SELECT_CC_FP_FP) ||
(MI.getOpcode() == Xtensa::SELECT_CC_FP_INT)) {
if (MI.getOpcode() == Xtensa::SELECT_CC_FP_FP ||
MI.getOpcode() == Xtensa::SELECT_CC_FP_INT) {

return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
}]>;

def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t, bb:$target), (BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t, bb:$target), (BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;
def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t, bb:$target),
(BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:Xtensa mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants