1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02: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:
Matt Arsenault 2019-05-17 18:36:31 +00:00
parent fab053e3f0
commit ec6a868f2e
6 changed files with 110 additions and 1 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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