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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 131 additions & 12 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
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 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);
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?

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

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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)) {
Comment on lines +1565 to +1566
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) {

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);

Expand All @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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!");
}
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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");
}
Expand Down Expand Up @@ -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!");
}
Expand Down Expand Up @@ -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!");
}
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 27 additions & 1 deletion llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -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)>;
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)>;


//===----------------------------------------------------------------------===//
// Region Protection feature instructions
//===----------------------------------------------------------------------===//
Expand Down
10 changes: 7 additions & 3 deletions llvm/lib/Target/Xtensa/XtensaOperators.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>]>;
Expand Down Expand Up @@ -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]>;
21 changes: 20 additions & 1 deletion llvm/test/CodeGen/Xtensa/float-arith.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
}
Loading
Loading