GlobalISel: support translating select instructions.

llvm-svn: 279309
This commit is contained in:
Tim Northover 2016-08-19 20:09:07 +00:00
parent b604622bba
commit 5a28c3642f
7 changed files with 49 additions and 2 deletions

View File

@ -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; }

View File

@ -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.

View File

@ -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
//------------------------------------------------------------------------------

View File

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

View File

@ -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];

View File

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

View File

@ -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
}