Skip to content

Commit ce92b2f

Browse files
authored
[Xtensa] Implement lowering SELECT_CC, SETCC. (#97017)
1 parent 00fd188 commit ce92b2f

File tree

7 files changed

+1579
-36
lines changed

7 files changed

+1579
-36
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,19 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
8585
// indirect jump.
8686
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
8787

88-
setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32);
8988
setOperationAction(ISD::BR_CC, MVT::i32, Legal);
9089
setOperationAction(ISD::BR_CC, MVT::i64, Expand);
9190
setOperationAction(ISD::BR_CC, MVT::f32, Expand);
9291

92+
setOperationAction(ISD::SELECT, MVT::i32, Expand);
93+
setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
94+
setOperationAction(ISD::SETCC, MVT::i32, Expand);
95+
96+
setCondCodeAction(ISD::SETGT, MVT::i32, Expand);
97+
setCondCodeAction(ISD::SETLE, MVT::i32, Expand);
98+
setCondCodeAction(ISD::SETUGT, MVT::i32, Expand);
99+
setCondCodeAction(ISD::SETULE, MVT::i32, Expand);
100+
93101
// Implement custom stack allocations
94102
setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
95103
// Implement custom stack save and restore
@@ -514,6 +522,50 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
514522
return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
515523
}
516524

525+
static unsigned getBranchOpcode(ISD::CondCode Cond) {
526+
switch (Cond) {
527+
case ISD::SETEQ:
528+
return Xtensa::BEQ;
529+
case ISD::SETNE:
530+
return Xtensa::BNE;
531+
case ISD::SETLT:
532+
return Xtensa::BLT;
533+
case ISD::SETLE:
534+
return Xtensa::BGE;
535+
case ISD::SETGT:
536+
return Xtensa::BLT;
537+
case ISD::SETGE:
538+
return Xtensa::BGE;
539+
case ISD::SETULT:
540+
return Xtensa::BLTU;
541+
case ISD::SETULE:
542+
return Xtensa::BGEU;
543+
case ISD::SETUGT:
544+
return Xtensa::BLTU;
545+
case ISD::SETUGE:
546+
return Xtensa::BGEU;
547+
default:
548+
llvm_unreachable("Unknown branch kind");
549+
}
550+
}
551+
552+
SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
553+
SelectionDAG &DAG) const {
554+
SDLoc DL(Op);
555+
EVT Ty = Op.getOperand(0).getValueType();
556+
SDValue LHS = Op.getOperand(0);
557+
SDValue RHS = Op.getOperand(1);
558+
SDValue TrueValue = Op.getOperand(2);
559+
SDValue FalseValue = Op.getOperand(3);
560+
ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
561+
562+
unsigned BrOpcode = getBranchOpcode(CC);
563+
SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
564+
565+
return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
566+
FalseValue, TargetCC);
567+
}
568+
517569
SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
518570
SelectionDAG &DAG) const {
519571
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
@@ -676,6 +728,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
676728
return LowerJumpTable(Op, DAG);
677729
case ISD::ConstantPool:
678730
return LowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
731+
case ISD::SELECT_CC:
732+
return LowerSELECT_CC(Op, DAG);
679733
case ISD::STACKSAVE:
680734
return LowerSTACKSAVE(Op, DAG);
681735
case ISD::STACKRESTORE:
@@ -697,6 +751,86 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
697751
return "XtensaISD::PCREL_WRAPPER";
698752
case XtensaISD::RET:
699753
return "XtensaISD::RET";
754+
case XtensaISD::SELECT_CC:
755+
return "XtensaISD::SELECT_CC";
700756
}
701757
return nullptr;
702758
}
759+
760+
//===----------------------------------------------------------------------===//
761+
// Custom insertion
762+
//===----------------------------------------------------------------------===//
763+
764+
MachineBasicBlock *
765+
XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
766+
MachineBasicBlock *MBB) const {
767+
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
768+
DebugLoc DL = MI.getDebugLoc();
769+
770+
MachineOperand &LHS = MI.getOperand(1);
771+
MachineOperand &RHS = MI.getOperand(2);
772+
MachineOperand &TrueValue = MI.getOperand(3);
773+
MachineOperand &FalseValue = MI.getOperand(4);
774+
unsigned BrKind = MI.getOperand(5).getImm();
775+
776+
// To "insert" a SELECT_CC instruction, we actually have to insert
777+
// CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
778+
// operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
779+
// is passed from MMB and FalseValue is passed from CopyMBB.
780+
// MBB
781+
// | \
782+
// | CopyMBB
783+
// | /
784+
// SinkMBB
785+
// The incoming instruction knows the
786+
// destination vreg to set, the condition code register to branch on, the
787+
// true/false values to select between, and a branch opcode to use.
788+
const BasicBlock *LLVM_BB = MBB->getBasicBlock();
789+
MachineFunction::iterator It = ++MBB->getIterator();
790+
791+
MachineFunction *F = MBB->getParent();
792+
MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
793+
MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
794+
795+
F->insert(It, CopyMBB);
796+
F->insert(It, SinkMBB);
797+
798+
// Transfer the remainder of MBB and its successor edges to SinkMBB.
799+
SinkMBB->splice(SinkMBB->begin(), MBB,
800+
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
801+
SinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
802+
803+
MBB->addSuccessor(CopyMBB);
804+
MBB->addSuccessor(SinkMBB);
805+
806+
BuildMI(MBB, DL, TII.get(BrKind))
807+
.addReg(LHS.getReg())
808+
.addReg(RHS.getReg())
809+
.addMBB(SinkMBB);
810+
811+
CopyMBB->addSuccessor(SinkMBB);
812+
813+
// SinkMBB:
814+
// %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
815+
// ...
816+
817+
BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
818+
MI.getOperand(0).getReg())
819+
.addReg(FalseValue.getReg())
820+
.addMBB(CopyMBB)
821+
.addReg(TrueValue.getReg())
822+
.addMBB(MBB);
823+
824+
MI.eraseFromParent(); // The pseudo instruction is gone now.
825+
return SinkMBB;
826+
}
827+
828+
MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
829+
MachineInstr &MI, MachineBasicBlock *MBB) const {
830+
switch (MI.getOpcode()) {
831+
case Xtensa::SELECT:
832+
return emitSelectCC(MI, MBB);
833+
default:
834+
llvm_unreachable("Unexpected instr type to insert");
835+
}
836+
}

llvm/lib/Target/Xtensa/XtensaISelLowering.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ enum {
3333
// Wraps a TargetGlobalAddress that should be loaded using PC-relative
3434
// accesses. Operand 0 is the address.
3535
PCREL_WRAPPER,
36-
RET
36+
RET,
37+
38+
// Select with condition operator - This selects between a true value and
39+
// a false value (ops #2 and #3) based on the boolean result of comparing
40+
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
41+
// condition code in op #4
42+
SELECT_CC,
3743
};
3844
}
3945

@@ -44,6 +50,13 @@ class XtensaTargetLowering : public TargetLowering {
4450
explicit XtensaTargetLowering(const TargetMachine &TM,
4551
const XtensaSubtarget &STI);
4652

53+
EVT getSetCCResultType(const DataLayout &, LLVMContext &,
54+
EVT VT) const override {
55+
if (!VT.isVector())
56+
return MVT::i32;
57+
return VT.changeVectorElementTypeToInteger();
58+
}
59+
4760
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
4861

4962
const char *getTargetNodeName(unsigned Opcode) const override;
@@ -71,6 +84,10 @@ class XtensaTargetLowering : public TargetLowering {
7184

7285
const XtensaSubtarget &getSubtarget() const { return Subtarget; }
7386

87+
MachineBasicBlock *
88+
EmitInstrWithCustomInserter(MachineInstr &MI,
89+
MachineBasicBlock *BB) const override;
90+
7491
private:
7592
const XtensaSubtarget &Subtarget;
7693

@@ -86,6 +103,8 @@ class XtensaTargetLowering : public TargetLowering {
86103

87104
SDValue LowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
88105

106+
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
107+
89108
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
90109

91110
SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
@@ -95,6 +114,9 @@ class XtensaTargetLowering : public TargetLowering {
95114
SDValue getAddrPCRel(SDValue Op, SelectionDAG &DAG) const;
96115

97116
CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const;
117+
118+
MachineBasicBlock *emitSelectCC(MachineInstr &MI,
119+
MachineBasicBlock *BB) const;
98120
};
99121

100122
} // end namespace llvm

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,6 @@ def BBSI : RRI8_Inst<0x07, (outs),
416416
let imm8 = target;
417417
}
418418

419-
def : Pat<(brcc SETGT, AR:$s, AR:$t, bb:$target),
420-
(BLT AR:$t, AR:$s, bb:$target)>;
421-
def : Pat<(brcc SETUGT, AR:$s, AR:$t, bb:$target),
422-
(BLTU AR:$t, AR:$s, bb:$target)>;
423-
def : Pat<(brcc SETLE, AR:$s, AR:$t, bb:$target),
424-
(BGE AR:$t, AR:$s, bb:$target)>;
425-
def : Pat<(brcc SETULE, AR:$s, AR:$t, bb:$target),
426-
(BGEU AR:$t, AR:$s, bb:$target)>;
427-
428419
//===----------------------------------------------------------------------===//
429420
// Call and jump instructions
430421
//===----------------------------------------------------------------------===//
@@ -574,3 +565,12 @@ let Defs = [SP], Uses = [SP] in {
574565
"#ADJCALLSTACKUP",
575566
[(Xtensa_callseq_end timm:$amt1, timm:$amt2)]>;
576567
}
568+
569+
//===----------------------------------------------------------------------===//
570+
// Generic select instruction
571+
//===----------------------------------------------------------------------===//
572+
let usesCustomInserter = 1 in {
573+
def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond),
574+
"!select $dst, $lhs, $rhs, $t, $f, $cond",
575+
[(set i32:$dst, (Xtensa_select_cc i32:$lhs, i32:$rhs, i32:$t, i32:$f, imm:$cond))]>;
576+
}

llvm/lib/Target/Xtensa/XtensaOperators.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ def SDT_XtensaWrapPtr : SDTypeProfile<1, 1,
1919

2020
def SDT_XtensaBrJT : SDTypeProfile<0, 2,
2121
[SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
22+
23+
def SDT_XtensaSelectCC : SDTypeProfile<1, 5,
24+
[SDTCisSameAs<0, 1>,
25+
SDTCisSameAs<2, 3>,
26+
SDTCisVT<5, i32>]>;
2227
//===----------------------------------------------------------------------===//
2328
// Node definitions
2429
//===----------------------------------------------------------------------===//
@@ -38,3 +43,6 @@ def Xtensa_callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XtensaCallSeqEnd,
3843
SDNPOutGlue]>;
3944

4045
def Xtensa_brjt: SDNode<"XtensaISD::BR_JT", SDT_XtensaBrJT, [SDNPHasChain]>;
46+
47+
def Xtensa_select_cc: SDNode<"XtensaISD::SELECT_CC", SDT_XtensaSelectCC,
48+
[SDNPInGlue]>;

0 commit comments

Comments
 (0)