[llvm] [Xtensa] Implement lowering SELECT_CC/BRCC for Xtensa FP Option. (PR #145544)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 24 09:20:11 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: Andrei Safronov (andreisfr)
<details>
<summary>Changes</summary>
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
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/145544
More information about the llvm-commits
mailing list