-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -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); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Losing flags from the original select? |
||||||||||
return Res; | ||||||||||
} else { | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||||||||||
|
@@ -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)) { | ||||||||||
Comment on lines
+1565
to
+1566
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
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: | ||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -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)>; | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
//===----------------------------------------------------------------------===// | ||||||||
// Region Protection feature instructions | ||||||||
//===----------------------------------------------------------------------===// | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove dead break