Skip to content

Commit a2c9f7d

Browse files
authored
[Xtensa] Implement lowering SELECT_CC/BRCC for Xtensa FP Option. (#145544)
Also minor format changes in disassembler test for Xtensa FP Option.
1 parent 7cc8fe2 commit a2c9f7d

File tree

8 files changed

+753
-121
lines changed

8 files changed

+753
-121
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 105 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,18 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
110110

111111
setOperationAction(ISD::BR_CC, MVT::i32, Legal);
112112
setOperationAction(ISD::BR_CC, MVT::i64, Expand);
113-
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
114113

115114
setOperationAction(ISD::SELECT, MVT::i32, Expand);
116115
setOperationAction(ISD::SELECT, MVT::f32, Expand);
117116
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
118-
setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
117+
118+
if (Subtarget.hasSingleFloat()) {
119+
setOperationAction(ISD::BR_CC, MVT::f32, Legal);
120+
setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
121+
} else {
122+
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
123+
setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);
124+
}
119125

120126
setOperationAction(ISD::SETCC, MVT::i32, Expand);
121127
setOperationAction(ISD::SETCC, MVT::f32, Expand);
@@ -841,21 +847,68 @@ static unsigned getBranchOpcode(ISD::CondCode Cond) {
841847
}
842848
}
843849

850+
static std::pair<unsigned, unsigned> getFPBranchKind(ISD::CondCode Cond) {
851+
switch (Cond) {
852+
case ISD::SETUNE:
853+
return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
854+
case ISD::SETUO:
855+
return std::make_pair(Xtensa::BT, Xtensa::UN_S);
856+
case ISD::SETO:
857+
return std::make_pair(Xtensa::BF, Xtensa::UN_S);
858+
case ISD::SETUEQ:
859+
return std::make_pair(Xtensa::BT, Xtensa::UEQ_S);
860+
case ISD::SETULE:
861+
return std::make_pair(Xtensa::BT, Xtensa::ULE_S);
862+
case ISD::SETULT:
863+
return std::make_pair(Xtensa::BT, Xtensa::ULT_S);
864+
case ISD::SETEQ:
865+
case ISD::SETOEQ:
866+
return std::make_pair(Xtensa::BT, Xtensa::OEQ_S);
867+
case ISD::SETNE:
868+
return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
869+
case ISD::SETLE:
870+
case ISD::SETOLE:
871+
return std::make_pair(Xtensa::BT, Xtensa::OLE_S);
872+
case ISD::SETLT:
873+
case ISD::SETOLT:
874+
return std::make_pair(Xtensa::BT, Xtensa::OLT_S);
875+
case ISD::SETGE:
876+
return std::make_pair(Xtensa::BF, Xtensa::OLT_S);
877+
case ISD::SETGT:
878+
return std::make_pair(Xtensa::BF, Xtensa::OLE_S);
879+
default:
880+
llvm_unreachable("Invalid condition!");
881+
}
882+
}
883+
844884
SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
845885
SelectionDAG &DAG) const {
846886
SDLoc DL(Op);
847-
EVT Ty = Op.getOperand(0).getValueType();
887+
EVT Ty = Op.getValueType();
848888
SDValue LHS = Op.getOperand(0);
849889
SDValue RHS = Op.getOperand(1);
850890
SDValue TrueValue = Op.getOperand(2);
851891
SDValue FalseValue = Op.getOperand(3);
852892
ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
853893

854-
unsigned BrOpcode = getBranchOpcode(CC);
855-
SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
894+
if (LHS.getValueType() == MVT::i32) {
895+
unsigned BrOpcode = getBranchOpcode(CC);
896+
SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
856897

857-
return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
858-
FalseValue, TargetCC);
898+
SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
899+
FalseValue, TargetCC, Op->getFlags());
900+
return Res;
901+
}
902+
assert(LHS.getValueType() == MVT::f32 &&
903+
"We expect MVT::f32 type of the LHS Operand in SELECT_CC");
904+
unsigned BrOpcode;
905+
unsigned CmpOpCode;
906+
std::tie(BrOpcode, CmpOpCode) = getFPBranchKind(CC);
907+
SDValue TargetCC = DAG.getConstant(CmpOpCode, DL, MVT::i32);
908+
SDValue TargetBC = DAG.getConstant(BrOpcode, DL, MVT::i32);
909+
return DAG.getNode(XtensaISD::SELECT_CC_FP, DL, Ty,
910+
{LHS, RHS, TrueValue, FalseValue, TargetCC, TargetBC},
911+
Op->getFlags());
859912
}
860913

861914
SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
@@ -1408,6 +1461,8 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
14081461
return "XtensaISD::RETW";
14091462
case XtensaISD::SELECT_CC:
14101463
return "XtensaISD::SELECT_CC";
1464+
case XtensaISD::SELECT_CC_FP:
1465+
return "XtensaISD::SELECT_CC_FP";
14111466
case XtensaISD::SRCL:
14121467
return "XtensaISD::SRCL";
14131468
case XtensaISD::SRCR:
@@ -1450,7 +1505,6 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
14501505
MachineOperand &RHS = MI.getOperand(2);
14511506
MachineOperand &TrueValue = MI.getOperand(3);
14521507
MachineOperand &FalseValue = MI.getOperand(4);
1453-
unsigned BrKind = MI.getOperand(5).getImm();
14541508

14551509
// To "insert" a SELECT_CC instruction, we actually have to insert
14561510
// CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
@@ -1482,10 +1536,25 @@ XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
14821536
MBB->addSuccessor(CopyMBB);
14831537
MBB->addSuccessor(SinkMBB);
14841538

1485-
BuildMI(MBB, DL, TII.get(BrKind))
1486-
.addReg(LHS.getReg())
1487-
.addReg(RHS.getReg())
1488-
.addMBB(SinkMBB);
1539+
if (MI.getOpcode() == Xtensa::SELECT_CC_FP_FP ||
1540+
MI.getOpcode() == Xtensa::SELECT_CC_FP_INT) {
1541+
unsigned CmpKind = MI.getOperand(5).getImm();
1542+
unsigned BrKind = MI.getOperand(6).getImm();
1543+
MCPhysReg BReg = Xtensa::B0;
1544+
1545+
BuildMI(MBB, DL, TII.get(CmpKind), BReg)
1546+
.addReg(LHS.getReg())
1547+
.addReg(RHS.getReg());
1548+
BuildMI(MBB, DL, TII.get(BrKind))
1549+
.addReg(BReg, RegState::Kill)
1550+
.addMBB(SinkMBB);
1551+
} else {
1552+
unsigned BrKind = MI.getOperand(5).getImm();
1553+
BuildMI(MBB, DL, TII.get(BrKind))
1554+
.addReg(LHS.getReg())
1555+
.addReg(RHS.getReg())
1556+
.addMBB(SinkMBB);
1557+
}
14891558

14901559
CopyMBB->addSuccessor(SinkMBB);
14911560

@@ -1510,6 +1579,30 @@ MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
15101579
const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
15111580

15121581
switch (MI.getOpcode()) {
1582+
case Xtensa::BRCC_FP: {
1583+
MachineOperand &Cond = MI.getOperand(0);
1584+
MachineOperand &LHS = MI.getOperand(1);
1585+
MachineOperand &RHS = MI.getOperand(2);
1586+
MachineBasicBlock *TargetBB = MI.getOperand(3).getMBB();
1587+
unsigned BrKind = 0;
1588+
unsigned CmpKind = 0;
1589+
ISD::CondCode CondCode = (ISD::CondCode)Cond.getImm();
1590+
MCPhysReg BReg = Xtensa::B0;
1591+
1592+
std::tie(BrKind, CmpKind) = getFPBranchKind(CondCode);
1593+
BuildMI(*MBB, MI, DL, TII.get(CmpKind), BReg)
1594+
.addReg(LHS.getReg())
1595+
.addReg(RHS.getReg());
1596+
BuildMI(*MBB, MI, DL, TII.get(BrKind))
1597+
.addReg(BReg, RegState::Kill)
1598+
.addMBB(TargetBB);
1599+
1600+
MI.eraseFromParent();
1601+
return MBB;
1602+
}
1603+
case Xtensa::SELECT_CC_FP_FP:
1604+
case Xtensa::SELECT_CC_FP_INT:
1605+
case Xtensa::SELECT_CC_INT_FP:
15131606
case Xtensa::SELECT:
15141607
return emitSelectCC(MI, MBB);
15151608
case Xtensa::S8I:

llvm/lib/Target/Xtensa/XtensaISelLowering.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ enum {
5050
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
5151
// condition code in op #4
5252
SELECT_CC,
53+
// Select with condition operator - This selects between a true value and
54+
// a false value (ops #2 and #3) based on the boolean result of comparing
55+
// f32 operands lhs and rhs (ops #0 and #1) of a conditional expression
56+
// with the condition code in op #4 and boolean branch kind in op #5
57+
SELECT_CC_FP,
5358

5459
// SRCL(R) performs shift left(right) of the concatenation of 2 registers
5560
// and returns high(low) 32-bit part of 64-bit result

llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ bool XtensaInstrInfo::reverseBranchCondition(
261261
case Xtensa::BGEZ:
262262
Cond[0].setImm(Xtensa::BLTZ);
263263
return false;
264+
case Xtensa::BF:
265+
Cond[0].setImm(Xtensa::BT);
266+
return false;
267+
case Xtensa::BT:
268+
Cond[0].setImm(Xtensa::BF);
269+
return false;
264270
default:
265271
report_fatal_error("Invalid branch condition!");
266272
}
@@ -294,6 +300,9 @@ XtensaInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
294300
case Xtensa::BLTZ:
295301
case Xtensa::BGEZ:
296302
return MI.getOperand(1).getMBB();
303+
case Xtensa::BT:
304+
case Xtensa::BF:
305+
return MI.getOperand(1).getMBB();
297306
default:
298307
llvm_unreachable("Unknown branch opcode");
299308
}
@@ -329,6 +338,10 @@ bool XtensaInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
329338
case Xtensa::BGEZ:
330339
BrOffset -= 4;
331340
return isIntN(12, BrOffset);
341+
case Xtensa::BT:
342+
case Xtensa::BF:
343+
BrOffset -= 4;
344+
return isIntN(8, BrOffset);
332345
default:
333346
llvm_unreachable("Unknown branch opcode");
334347
}
@@ -581,6 +594,10 @@ unsigned XtensaInstrInfo::insertConstBranchAtInst(
581594
case Xtensa::BGEZ:
582595
MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
583596
break;
597+
case Xtensa::BT:
598+
case Xtensa::BF:
599+
MI = BuildMI(MBB, I, DL, get(BR_C)).addImm(offset).addReg(Cond[1].getReg());
600+
break;
584601
default:
585602
llvm_unreachable("Invalid branch type!");
586603
}
@@ -641,6 +658,10 @@ unsigned XtensaInstrInfo::insertBranchAtInst(MachineBasicBlock &MBB,
641658
case Xtensa::BGEZ:
642659
MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
643660
break;
661+
case Xtensa::BT:
662+
case Xtensa::BF:
663+
MI = BuildMI(MBB, I, DL, get(BR_C)).addReg(Cond[1].getReg()).addMBB(TBB);
664+
break;
644665
default:
645666
report_fatal_error("Invalid branch type!");
646667
}
@@ -689,6 +710,12 @@ bool XtensaInstrInfo::isBranch(const MachineBasicBlock::iterator &MI,
689710
Target = &MI->getOperand(1);
690711
return true;
691712

713+
case Xtensa::BT:
714+
case Xtensa::BF:
715+
Cond[0].setImm(OpCode);
716+
Target = &MI->getOperand(1);
717+
return true;
718+
692719
default:
693720
assert(!MI->getDesc().isBranch() && "Unknown branch opcode");
694721
return false;

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,6 @@ def BBSI : RRI8_Inst<0x07, (outs),
416416
}
417417

418418
def : Pat<(brcond AR:$s, bb:$target), (BNEZ AR:$s, bb:$target)>;
419-
420419
//===----------------------------------------------------------------------===//
421420
// Call and jump instructions
422421
//===----------------------------------------------------------------------===//
@@ -1310,6 +1309,34 @@ let AddedComplexity = 10 in
13101309
def : Pat<(f32 (load (Xtensa_pcrel_wrapper tconstpool:$in))),
13111310
(WFR (L32R tconstpool:$in))>;
13121311

1312+
//===----------------------------------------------------------------------===//
1313+
// SelectCC and BranchCC instructions with FP operands
1314+
//===----------------------------------------------------------------------===//
1315+
1316+
let usesCustomInserter = 1, Predicates = [HasSingleFloat] in {
1317+
def SELECT_CC_INT_FP : Pseudo<(outs FPR:$dst), (ins AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, i32imm:$cond),
1318+
"!select_cc_int_fp $dst, $lhs, $rhs, $t, $f, $cond",
1319+
[(set FPR:$dst, (Xtensa_select_cc AR:$lhs, AR:$rhs, FPR:$t, FPR:$f, imm:$cond))]>;
1320+
def SELECT_CC_FP_INT : Pseudo<(outs AR:$dst), (ins FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, i32imm:$cond, i32imm:$brkind),
1321+
"!select_cc_fp_int $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
1322+
[(set AR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, AR:$t, AR:$f, imm:$cond, imm:$brkind))]>;
1323+
def SELECT_CC_FP_FP : Pseudo<(outs FPR:$dst), (ins FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, i32imm:$cond, i32imm:$brkind),
1324+
"!select_cc_fp_fp $dst, $lhs, $rhs, $t, $f, $cond, $brkind",
1325+
[(set FPR:$dst, (Xtensa_select_cc_fp FPR:$lhs, FPR:$rhs, FPR:$t, FPR:$f, imm:$cond, imm:$brkind))]>;
1326+
}
1327+
1328+
let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, isBarrier = 1, Predicates = [HasSingleFloat] in {
1329+
def BRCC_FP : Pseudo<(outs), (ins i32imm:$cond, FPR:$lhs, FPR:$rhs, brtarget:$target),
1330+
"!brcc_fp $cond, $lhs, $rhs, $target", []>;
1331+
}
1332+
1333+
def cond_as_i32imm : SDNodeXForm<cond, [{
1334+
return CurDAG->getTargetConstant(N->get(), SDLoc(N), MVT::i32);
1335+
}]>;
1336+
1337+
def : Pat<(brcc cond:$cond, FPR:$s, FPR:$t, bb:$target),
1338+
(BRCC_FP (cond_as_i32imm $cond), FPR:$s, FPR:$t, bb:$target)>;
1339+
13131340
//===----------------------------------------------------------------------===//
13141341
// Region Protection feature instructions
13151342
//===----------------------------------------------------------------------===//

llvm/lib/Target/Xtensa/XtensaOperators.td

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ def SDT_XtensaBrJT : SDTypeProfile<0, 2,
2121
[SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
2222

2323
def SDT_XtensaSelectCC : SDTypeProfile<1, 5,
24-
[SDTCisSameAs<0, 1>,
25-
SDTCisSameAs<2, 3>,
24+
[SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>,
25+
SDTCisSameAs<3, 4>,
2626
SDTCisVT<5, i32>]>;
2727

2828
def SDT_XtensaCmp : SDTypeProfile<1, 2, [SDTCisVT<0, v1i1>, SDTCisVT<1, f32>, SDTCisVT<2, f32>]>;
2929
def SDT_XtensaMADD : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisVT<0, f32>]>;
3030
def SDT_XtensaMOVS : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisVT<0, f32>]>;
31-
def SDT_XtensaSelectCCFP : SDTypeProfile<1, 5, [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisVT<5, i32>]>;
31+
def SDT_XtensaSelectCCFP : SDTypeProfile<1, 6, [SDTCisSameAs<0, 3>, SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>,
32+
SDTCisVT<5, i32>, SDTCisVT<6, i32>]>;
3233

3334
def SDT_XtensaSRC : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
3435
SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
@@ -87,3 +88,6 @@ def Xtensa_cmpuo : SDNode<"XtensaISD::CMPUO", SDT_XtensaCmp, [SDNPOutGlue]>
8788
def Xtensa_madd: SDNode<"XtensaISD::MADD", SDT_XtensaMADD, [SDNPInGlue]>;
8889
def Xtensa_msub: SDNode<"XtensaISD::MSUB", SDT_XtensaMADD, [SDNPInGlue]>;
8990
def Xtensa_movs: SDNode<"XtensaISD::MOVS", SDT_XtensaMOVS, [SDNPInGlue]>;
91+
92+
def Xtensa_select_cc_fp: SDNode<"XtensaISD::SELECT_CC_FP", SDT_XtensaSelectCCFP,
93+
[SDNPInGlue]>;

llvm/test/CodeGen/Xtensa/float-arith.ll

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,6 @@ define float @round_f32(float %a) nounwind {
568568
ret float %res
569569
}
570570

571-
572571
define float @fneg_s(float %a) nounwind {
573572
; XTENSA-LABEL: fneg_s:
574573
; XTENSA: # %bb.0:
@@ -601,3 +600,23 @@ define i32 @fptoui(float %f) {
601600
ret i32 %conv
602601
}
603602

603+
define float @copysign_f32(float %a, float %b) {
604+
; XTENSA-LABEL: copysign_f32:
605+
; XTENSA: .cfi_startproc
606+
; XTENSA-NEXT: # %bb.0: # %entry
607+
; XTENSA-NEXT: l32r a8, .LCPI35_0
608+
; XTENSA-NEXT: and a8, a3, a8
609+
; XTENSA-NEXT: l32r a9, .LCPI35_1
610+
; XTENSA-NEXT: and a9, a2, a9
611+
; XTENSA-NEXT: wfr f8, a9
612+
; XTENSA-NEXT: movi a9, 0
613+
; XTENSA-NEXT: beq a8, a9, .LBB35_2
614+
; XTENSA-NEXT: # %bb.1:
615+
; XTENSA-NEXT: neg.s f8, f8
616+
; XTENSA-NEXT: .LBB35_2: # %entry
617+
; XTENSA-NEXT: rfr a2, f8
618+
; XTENSA-NEXT: ret
619+
entry:
620+
%c = call float @llvm.copysign.f32(float %a, float %b)
621+
ret float %c
622+
}

0 commit comments

Comments
 (0)