Skip to content

Commit

Permalink
[Xtensa] Implement lowering SELECT_CC, SETCC. (#97017)
Browse files Browse the repository at this point in the history
  • Loading branch information
andreisfr authored Jul 11, 2024
1 parent 00fd188 commit ce92b2f
Show file tree
Hide file tree
Showing 7 changed files with 1,579 additions and 36 deletions.
136 changes: 135 additions & 1 deletion llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,19 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
// indirect jump.
setOperationAction(ISD::BR_JT, MVT::Other, Custom);

setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32);
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_CC, MVT::i32, Custom);
setOperationAction(ISD::SETCC, MVT::i32, Expand);

setCondCodeAction(ISD::SETGT, MVT::i32, Expand);
setCondCodeAction(ISD::SETLE, MVT::i32, Expand);
setCondCodeAction(ISD::SETUGT, MVT::i32, Expand);
setCondCodeAction(ISD::SETULE, MVT::i32, Expand);

// Implement custom stack allocations
setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
// Implement custom stack save and restore
Expand Down Expand Up @@ -514,6 +522,50 @@ XtensaTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
}

static unsigned getBranchOpcode(ISD::CondCode Cond) {
switch (Cond) {
case ISD::SETEQ:
return Xtensa::BEQ;
case ISD::SETNE:
return Xtensa::BNE;
case ISD::SETLT:
return Xtensa::BLT;
case ISD::SETLE:
return Xtensa::BGE;
case ISD::SETGT:
return Xtensa::BLT;
case ISD::SETGE:
return Xtensa::BGE;
case ISD::SETULT:
return Xtensa::BLTU;
case ISD::SETULE:
return Xtensa::BGEU;
case ISD::SETUGT:
return Xtensa::BLTU;
case ISD::SETUGE:
return Xtensa::BGEU;
default:
llvm_unreachable("Unknown branch kind");
}
}

SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
EVT Ty = Op.getOperand(0).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);

return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
FalseValue, TargetCC);
}

SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
SelectionDAG &DAG) const {
const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
Expand Down Expand Up @@ -676,6 +728,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
return LowerJumpTable(Op, DAG);
case ISD::ConstantPool:
return LowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
case ISD::SELECT_CC:
return LowerSELECT_CC(Op, DAG);
case ISD::STACKSAVE:
return LowerSTACKSAVE(Op, DAG);
case ISD::STACKRESTORE:
Expand All @@ -697,6 +751,86 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
return "XtensaISD::PCREL_WRAPPER";
case XtensaISD::RET:
return "XtensaISD::RET";
case XtensaISD::SELECT_CC:
return "XtensaISD::SELECT_CC";
}
return nullptr;
}

//===----------------------------------------------------------------------===//
// Custom insertion
//===----------------------------------------------------------------------===//

MachineBasicBlock *
XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
MachineBasicBlock *MBB) const {
const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
DebugLoc DL = MI.getDebugLoc();

MachineOperand &LHS = MI.getOperand(1);
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
// operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
// is passed from MMB and FalseValue is passed from CopyMBB.
// MBB
// | \
// | CopyMBB
// | /
// SinkMBB
// The incoming instruction knows the
// destination vreg to set, the condition code register to branch on, the
// true/false values to select between, and a branch opcode to use.
const BasicBlock *LLVM_BB = MBB->getBasicBlock();
MachineFunction::iterator It = ++MBB->getIterator();

MachineFunction *F = MBB->getParent();
MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);

F->insert(It, CopyMBB);
F->insert(It, SinkMBB);

// Transfer the remainder of MBB and its successor edges to SinkMBB.
SinkMBB->splice(SinkMBB->begin(), MBB,
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
SinkMBB->transferSuccessorsAndUpdatePHIs(MBB);

MBB->addSuccessor(CopyMBB);
MBB->addSuccessor(SinkMBB);

BuildMI(MBB, DL, TII.get(BrKind))
.addReg(LHS.getReg())
.addReg(RHS.getReg())
.addMBB(SinkMBB);

CopyMBB->addSuccessor(SinkMBB);

// SinkMBB:
// %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
// ...

BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
MI.getOperand(0).getReg())
.addReg(FalseValue.getReg())
.addMBB(CopyMBB)
.addReg(TrueValue.getReg())
.addMBB(MBB);

MI.eraseFromParent(); // The pseudo instruction is gone now.
return SinkMBB;
}

MachineBasicBlock *XtensaTargetLowering::EmitInstrWithCustomInserter(
MachineInstr &MI, MachineBasicBlock *MBB) const {
switch (MI.getOpcode()) {
case Xtensa::SELECT:
return emitSelectCC(MI, MBB);
default:
llvm_unreachable("Unexpected instr type to insert");
}
}
24 changes: 23 additions & 1 deletion llvm/lib/Target/Xtensa/XtensaISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ enum {
// Wraps a TargetGlobalAddress that should be loaded using PC-relative
// accesses. Operand 0 is the address.
PCREL_WRAPPER,
RET
RET,

// 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
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
// condition code in op #4
SELECT_CC,
};
}

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

EVT getSetCCResultType(const DataLayout &, LLVMContext &,
EVT VT) const override {
if (!VT.isVector())
return MVT::i32;
return VT.changeVectorElementTypeToInteger();
}

bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;

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

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

MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const override;

private:
const XtensaSubtarget &Subtarget;

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

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

SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;

SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;

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

CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const;

MachineBasicBlock *emitSelectCC(MachineInstr &MI,
MachineBasicBlock *BB) const;
};

} // end namespace llvm
Expand Down
18 changes: 9 additions & 9 deletions llvm/lib/Target/Xtensa/XtensaInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -416,15 +416,6 @@ def BBSI : RRI8_Inst<0x07, (outs),
let imm8 = target;
}

def : Pat<(brcc SETGT, AR:$s, AR:$t, bb:$target),
(BLT AR:$t, AR:$s, bb:$target)>;
def : Pat<(brcc SETUGT, AR:$s, AR:$t, bb:$target),
(BLTU AR:$t, AR:$s, bb:$target)>;
def : Pat<(brcc SETLE, AR:$s, AR:$t, bb:$target),
(BGE AR:$t, AR:$s, bb:$target)>;
def : Pat<(brcc SETULE, AR:$s, AR:$t, bb:$target),
(BGEU AR:$t, AR:$s, bb:$target)>;

//===----------------------------------------------------------------------===//
// Call and jump instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -574,3 +565,12 @@ let Defs = [SP], Uses = [SP] in {
"#ADJCALLSTACKUP",
[(Xtensa_callseq_end timm:$amt1, timm:$amt2)]>;
}

//===----------------------------------------------------------------------===//
// Generic select instruction
//===----------------------------------------------------------------------===//
let usesCustomInserter = 1 in {
def SELECT : Pseudo<(outs AR:$dst), (ins AR:$lhs, AR:$rhs, AR:$t, AR:$f, i32imm:$cond),
"!select $dst, $lhs, $rhs, $t, $f, $cond",
[(set i32:$dst, (Xtensa_select_cc i32:$lhs, i32:$rhs, i32:$t, i32:$f, imm:$cond))]>;
}
8 changes: 8 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaOperators.td
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ def SDT_XtensaWrapPtr : SDTypeProfile<1, 1,

def SDT_XtensaBrJT : SDTypeProfile<0, 2,
[SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;

def SDT_XtensaSelectCC : SDTypeProfile<1, 5,
[SDTCisSameAs<0, 1>,
SDTCisSameAs<2, 3>,
SDTCisVT<5, i32>]>;
//===----------------------------------------------------------------------===//
// Node definitions
//===----------------------------------------------------------------------===//
Expand All @@ -38,3 +43,6 @@ def Xtensa_callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XtensaCallSeqEnd,
SDNPOutGlue]>;

def Xtensa_brjt: SDNode<"XtensaISD::BR_JT", SDT_XtensaBrJT, [SDNPHasChain]>;

def Xtensa_select_cc: SDNode<"XtensaISD::SELECT_CC", SDT_XtensaSelectCC,
[SDNPInGlue]>;
Loading

0 comments on commit ce92b2f

Please sign in to comment.