mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
GlobalISel: Define integer min/max instructions
Doesn't attempt to emit them for anything yet, but some legalizations I want to port use them. llvm-svn: 361061
This commit is contained in:
parent
fab053e3f0
commit
ec6a868f2e
@ -1335,6 +1335,30 @@ public:
|
||||
return buildInstr(TargetOpcode::G_FPTOSI, {Dst}, {Src0});
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_SMIN \p Op0, \p Op1
|
||||
MachineInstrBuilder buildSMin(const DstOp &Dst, const SrcOp &Src0,
|
||||
const SrcOp &Src1) {
|
||||
return buildInstr(TargetOpcode::G_SMIN, {Dst}, {Src0, Src1});
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_SMAX \p Op0, \p Op1
|
||||
MachineInstrBuilder buildSMax(const DstOp &Dst, const SrcOp &Src0,
|
||||
const SrcOp &Src1) {
|
||||
return buildInstr(TargetOpcode::G_SMAX, {Dst}, {Src0, Src1});
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_UMIN \p Op0, \p Op1
|
||||
MachineInstrBuilder buildUMin(const DstOp &Dst, const SrcOp &Src0,
|
||||
const SrcOp &Src1) {
|
||||
return buildInstr(TargetOpcode::G_UMIN, {Dst}, {Src0, Src1});
|
||||
}
|
||||
|
||||
/// Build and insert \p Res = G_UMAX \p Op0, \p Op1
|
||||
MachineInstrBuilder buildUMax(const DstOp &Dst, const SrcOp &Src0,
|
||||
const SrcOp &Src1) {
|
||||
return buildInstr(TargetOpcode::G_UMAX, {Dst}, {Src0, Src1});
|
||||
}
|
||||
|
||||
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
|
||||
ArrayRef<SrcOp> SrcOps,
|
||||
Optional<unsigned> Flags = None);
|
||||
|
@ -497,6 +497,18 @@ HANDLE_TARGET_OPCODE(G_GEP)
|
||||
/// *down* to the given alignment.
|
||||
HANDLE_TARGET_OPCODE(G_PTR_MASK)
|
||||
|
||||
/// Generic signed integer minimum.
|
||||
HANDLE_TARGET_OPCODE(G_SMIN)
|
||||
|
||||
/// Generic signed integer maximum.
|
||||
HANDLE_TARGET_OPCODE(G_SMAX)
|
||||
|
||||
/// Generic unsigned integer maximum.
|
||||
HANDLE_TARGET_OPCODE(G_UMIN)
|
||||
|
||||
/// Generic unsigned integer maximum.
|
||||
HANDLE_TARGET_OPCODE(G_UMAX)
|
||||
|
||||
/// Generic BRANCH instruction. This is an unconditional branch.
|
||||
HANDLE_TARGET_OPCODE(G_BR)
|
||||
|
||||
|
@ -308,6 +308,38 @@ def G_PTR_MASK : GenericInstruction {
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
// Generic signed integer minimum.
|
||||
def G_SMIN : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type0:$src2);
|
||||
let hasSideEffects = 0;
|
||||
let isCommutable = 1;
|
||||
}
|
||||
|
||||
// Generic signed integer maximum.
|
||||
def G_SMAX : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type0:$src2);
|
||||
let hasSideEffects = 0;
|
||||
let isCommutable = 1;
|
||||
}
|
||||
|
||||
// Generic unsigned integer minimum.
|
||||
def G_UMIN : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type0:$src2);
|
||||
let hasSideEffects = 0;
|
||||
let isCommutable = 1;
|
||||
}
|
||||
|
||||
// Generic unsigned integer maximum.
|
||||
def G_UMAX : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type0:$src2);
|
||||
let hasSideEffects = 0;
|
||||
let isCommutable = 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Overflow ops
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -901,7 +901,11 @@ MachineInstrBuilder MachineIRBuilder::buildInstr(unsigned Opc,
|
||||
case TargetOpcode::G_UDIV:
|
||||
case TargetOpcode::G_SDIV:
|
||||
case TargetOpcode::G_UREM:
|
||||
case TargetOpcode::G_SREM: {
|
||||
case TargetOpcode::G_SREM:
|
||||
case TargetOpcode::G_SMIN:
|
||||
case TargetOpcode::G_SMAX:
|
||||
case TargetOpcode::G_UMIN:
|
||||
case TargetOpcode::G_UMAX: {
|
||||
// All these are binary ops.
|
||||
assert(DstOps.size() == 1 && "Invalid Dst");
|
||||
assert(SrcOps.size() == 2 && "Invalid Srcs");
|
||||
|
@ -306,6 +306,18 @@
|
||||
# DEBUG-NEXT: G_PTR_MASK (opcode {{[0-9]+}}): 1 type index
|
||||
# DEBUG: .. the first uncovered type index: 1, OK
|
||||
#
|
||||
# DEBUG: G_SMIN (opcode {{[0-9]+}}): 1 type index
|
||||
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
|
||||
#
|
||||
# DEBUG: G_SMAX (opcode {{[0-9]+}}): 1 type index
|
||||
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
|
||||
#
|
||||
# DEBUG: G_UMIN (opcode {{[0-9]+}}): 1 type index
|
||||
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
|
||||
#
|
||||
# DEBUG: G_UMAX (opcode {{[0-9]+}}): 1 type index
|
||||
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
|
||||
#
|
||||
# DEBUG-NEXT: G_BR (opcode {{[0-9]+}}): 0 type indices
|
||||
# DEBUG: .. type index coverage check SKIPPED: no rules defined
|
||||
#
|
||||
|
@ -253,3 +253,28 @@ TEST_F(GISelMITest, BuildCasts) {
|
||||
|
||||
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
|
||||
}
|
||||
|
||||
TEST_F(GISelMITest, BuildMinMax) {
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
LLT S64 = LLT::scalar(64);
|
||||
SmallVector<unsigned, 4> Copies;
|
||||
collectCopies(Copies, MF);
|
||||
|
||||
B.buildSMin(S64, Copies[0], Copies[1]);
|
||||
B.buildSMax(S64, Copies[0], Copies[1]);
|
||||
B.buildUMin(S64, Copies[0], Copies[1]);
|
||||
B.buildUMax(S64, Copies[0], Copies[1]);
|
||||
|
||||
auto CheckStr = R"(
|
||||
; CHECK: [[COPY0:%[0-9]+]]:_(s64) = COPY $x0
|
||||
; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
|
||||
; CHECK: [[SMIN0:%[0-9]+]]:_(s64) = G_SMIN [[COPY0]]:_, [[COPY1]]:_
|
||||
; CHECK: [[SMAX0:%[0-9]+]]:_(s64) = G_SMAX [[COPY0]]:_, [[COPY1]]:_
|
||||
; CHECK: [[UMIN0:%[0-9]+]]:_(s64) = G_UMIN [[COPY0]]:_, [[COPY1]]:_
|
||||
; CHECK: [[UMAX0:%[0-9]+]]:_(s64) = G_UMAX [[COPY0]]:_, [[COPY1]]:_
|
||||
)";
|
||||
|
||||
EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user