forked from OSchip/llvm-project
GlobalISel: support translating select instructions.
llvm-svn: 279309
This commit is contained in:
parent
b604622bba
commit
5a28c3642f
|
@ -153,6 +153,8 @@ private:
|
|||
|
||||
bool translateInsertValue(const User &U);
|
||||
|
||||
bool translateSelect(const User &U);
|
||||
|
||||
/// Translate return (ret) instruction.
|
||||
/// The target needs to implement CallLowering::lowerReturn for
|
||||
/// this to succeed.
|
||||
|
@ -263,7 +265,6 @@ private:
|
|||
bool translateCleanupPad(const User &U) { return false; }
|
||||
bool translateCatchPad(const User &U) { return false; }
|
||||
bool translateFCmp(const User &U) { return false; }
|
||||
bool translateSelect(const User &U) { return false; }
|
||||
bool translateUserOp1(const User &U) { return false; }
|
||||
bool translateUserOp2(const User &U) { return false; }
|
||||
bool translateVAArg(const User &U) { return false; }
|
||||
|
|
|
@ -301,13 +301,21 @@ public:
|
|||
/// \return The newly created instruction.
|
||||
MachineInstrBuilder buildTrunc(LLT Ty, unsigned Res, unsigned Op);
|
||||
|
||||
/// Build and insert either a G_ICMP
|
||||
/// Build and insert a G_ICMP
|
||||
///
|
||||
/// \pre setBasicBlock or setMI must have been called.
|
||||
///
|
||||
/// \return a MachineInstrBuilder for the newly created instruction.
|
||||
MachineInstrBuilder buildICmp(ArrayRef<LLT> Tys, CmpInst::Predicate Pred,
|
||||
unsigned Res, unsigned Op0, unsigned Op1);
|
||||
|
||||
/// Build and insert a \p Res = G_SELECT { \p Ty, s1 } \p Tst, \p Op0, \p Op1
|
||||
///
|
||||
/// \pre setBasicBlock or setMI must have been called.
|
||||
///
|
||||
/// \return a MachineInstrBuilder for the newly created instruction.
|
||||
MachineInstrBuilder buildSelect(LLT Ty, unsigned Res, unsigned Tst,
|
||||
unsigned Op0, unsigned Op1);
|
||||
};
|
||||
|
||||
} // End namespace llvm.
|
||||
|
|
|
@ -191,6 +191,13 @@ def G_ICMP : Instruction {
|
|||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
// Generic select
|
||||
def G_SELECT : Instruction {
|
||||
let OutOperandList = (outs unknown:$dst);
|
||||
let InOperandList = (ins unknown:$tst, unknown:$src1, unknown:$src2);
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Overflow ops
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -262,6 +262,9 @@ HANDLE_TARGET_OPCODE(G_ASHR)
|
|||
/// Generic integer-base comparison, also applicable to vectors of integers.
|
||||
HANDLE_TARGET_OPCODE(G_ICMP)
|
||||
|
||||
/// Generic select.
|
||||
HANDLE_TARGET_OPCODE(G_SELECT)
|
||||
|
||||
/// Generic unsigned add instruction, consuming the normal operands plus a carry
|
||||
/// flag, and similarly producing the result and a carry flag.
|
||||
HANDLE_TARGET_OPCODE(G_UADDE)
|
||||
|
|
|
@ -236,6 +236,13 @@ bool IRTranslator::translateInsertValue(const User &U) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IRTranslator::translateSelect(const User &U) {
|
||||
MIRBuilder.buildSelect(
|
||||
LLT{*U.getType()}, getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)),
|
||||
getOrCreateVReg(*U.getOperand(1)), getOrCreateVReg(*U.getOperand(2)));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IRTranslator::translateBitCast(const User &U) {
|
||||
if (LLT{*U.getOperand(0)->getType()} == LLT{*U.getType()}) {
|
||||
unsigned &Reg = ValToVReg[&U];
|
||||
|
|
|
@ -216,3 +216,13 @@ MachineInstrBuilder MachineIRBuilder::buildICmp(ArrayRef<LLT> Tys,
|
|||
.addUse(Op0)
|
||||
.addUse(Op1);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildSelect(LLT Ty, unsigned Res,
|
||||
unsigned Tst,
|
||||
unsigned Op0, unsigned Op1) {
|
||||
return buildInstr(TargetOpcode::G_SELECT, {Ty, LLT::scalar(1)})
|
||||
.addDef(Res)
|
||||
.addUse(Tst)
|
||||
.addUse(Op0)
|
||||
.addUse(Op1);
|
||||
}
|
||||
|
|
|
@ -729,3 +729,14 @@ define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
|
|||
store %struct.nested %res, %struct.nested* %addr
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: name: test_select
|
||||
; CHECK: [[TST:%[0-9]+]](1) = COPY %w0
|
||||
; CHECK: [[LHS:%[0-9]+]](32) = COPY %w1
|
||||
; CHECK: [[RHS:%[0-9]+]](32) = COPY %w2
|
||||
; CHECK: [[RES:%[0-9]+]](32) = G_SELECT { s32, s1 } [[TST]], [[LHS]], [[RHS]]
|
||||
; CHECK: %w0 = COPY [[RES]]
|
||||
define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
|
||||
%res = select i1 %tst, i32 %lhs, i32 %rhs
|
||||
ret i32 %res
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue