Skip to content

Commit 897511e

Browse files
committed
[GlobalISel] Add Saturated Truncate Instructions
1 parent 84e5451 commit 897511e

File tree

10 files changed

+187
-64
lines changed

10 files changed

+187
-64
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,33 @@ G_EXTRACT for scalar types, but acts elementwise on vectors.
148148
149149
%1:_(s16) = G_TRUNC %0:_(s32)
150150
151+
G_TRUNC_SSAT_S
152+
^^^^^^^^^^^^^^
153+
154+
Truncate a saturated signed input to a signed result.
155+
156+
.. code-block:: none
157+
158+
%1:_(s16) = G_TRUNC_SSAT_S %0:_(s32)
159+
160+
G_TRUNC_SSAT_U
161+
^^^^^^^^^^^^^^
162+
163+
Truncate a saturated signed input to an unsigned result.
164+
165+
.. code-block:: none
166+
167+
%1:_(s16) = G_TRUNC_SSAT_U %0:_(s32)
168+
169+
G_TRUNC_USAT_U
170+
^^^^^^^^^^^^^^
171+
172+
Truncate a saturated unsigned input to an unsigned result.
173+
174+
.. code-block:: none
175+
176+
%1:_(s16) = G_TRUNC_USAT_U %0:_(s32)
177+
151178
Type Conversions
152179
----------------
153180

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,48 @@ class LLVM_ABI MachineIRBuilder {
809809
MachineInstrBuilder buildZExtInReg(const DstOp &Res, const SrcOp &Op,
810810
int64_t ImmOp);
811811

812+
/// Build and insert \p Res = \p G_TRUNC_SSAT_S \p Op
813+
///
814+
/// G_TRUNC_SSAT_S truncates the saturated signed input, \p Op, to a signed
815+
/// result.
816+
/// ///
817+
/// \pre setBasicBlock or setMI must have been called.
818+
/// \pre \p Res must be a generic virtual register with scalar or vector type.
819+
/// \pre \p Op must be a generic virtual register with scalar or vector type.
820+
///
821+
/// \return The newly created instruction.
822+
MachineInstrBuilder buildTruncSSatS(const DstOp &Res, const SrcOp &Op) {
823+
return buildInstr(TargetOpcode::G_TRUNC_SSAT_S, {Res}, {Op});
824+
}
825+
826+
/// Build and insert \p Res = \p G_TRUNC_SSAT_U \p Op
827+
///
828+
/// G_TRUNC_SSAT_U truncates the saturated signed input, \p Op, to a unsigned
829+
/// result.
830+
/// ///
831+
/// \pre setBasicBlock or setMI must have been called.
832+
/// \pre \p Res must be a generic virtual register with scalar or vector type.
833+
/// \pre \p Op must be a generic virtual register with scalar or vector type.
834+
///
835+
/// \return The newly created instruction.
836+
MachineInstrBuilder buildTruncSSatU(const DstOp &Res, const SrcOp &Op) {
837+
return buildInstr(TargetOpcode::G_TRUNC_SSAT_U, {Res}, {Op});
838+
}
839+
840+
/// Build and insert \p Res = \p G_TRUNC_USAT_U \p Op
841+
///
842+
/// G_TRUNC_SSAT_S truncates the saturated unsigned input, \p Op, to a
843+
/// unsigned result.
844+
/// ///
845+
/// \pre setBasicBlock or setMI must have been called.
846+
/// \pre \p Res must be a generic virtual register with scalar or vector type.
847+
/// \pre \p Op must be a generic virtual register with scalar or vector type.
848+
///
849+
/// \return The newly created instruction.
850+
MachineInstrBuilder buildTruncUSatU(const DstOp &Res, const SrcOp &Op) {
851+
return buildInstr(TargetOpcode::G_TRUNC_USAT_U, {Res}, {Op});
852+
}
853+
812854
/// Build and insert an appropriate cast between two registers of equal size.
813855
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src);
814856

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,15 @@ HANDLE_TARGET_OPCODE(G_ANYEXT)
475475
/// elements of the vector.
476476
HANDLE_TARGET_OPCODE(G_TRUNC)
477477

478+
/// Generic instruction to truncate a saturated signed operand to a signed result.
479+
HANDLE_TARGET_OPCODE(G_TRUNC_SSAT_S)
480+
481+
/// Generic instruction to truncate a saturated signed operand to an unsigned result.
482+
HANDLE_TARGET_OPCODE(G_TRUNC_SSAT_U)
483+
484+
/// Generic instruction to truncate a saturated unsigned operand to an unsigned result.
485+
HANDLE_TARGET_OPCODE(G_TRUNC_USAT_U)
486+
478487
/// Generic integer constant.
479488
HANDLE_TARGET_OPCODE(G_CONSTANT)
480489

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,27 @@ def G_TRUNC : GenericInstruction {
8686
let hasSideEffects = false;
8787
}
8888

89+
// Truncate the signed saturated operand to a signed result.
90+
def G_TRUNC_SSAT_S : GenericInstruction {
91+
let OutOperandList = (outs type0:$dst);
92+
let InOperandList = (ins type1:$src);
93+
let hasSideEffects = false;
94+
}
95+
96+
// Truncate the signed saturated operand to an unsigned result.
97+
def G_TRUNC_SSAT_U : GenericInstruction {
98+
let OutOperandList = (outs type0:$dst);
99+
let InOperandList = (ins type1:$src);
100+
let hasSideEffects = false;
101+
}
102+
103+
// Truncate the unsigned saturated operand to an unsigned result.
104+
def G_TRUNC_USAT_U : GenericInstruction {
105+
let OutOperandList = (outs type0:$dst);
106+
let InOperandList = (ins type1:$src);
107+
let hasSideEffects = false;
108+
}
109+
89110
def G_IMPLICIT_DEF : GenericInstruction {
90111
let OutOperandList = (outs type0:$dst);
91112
let InOperandList = (ins);

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,9 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
14241424
case TargetOpcode::G_ZEXT:
14251425
case TargetOpcode::G_ANYEXT:
14261426
case TargetOpcode::G_TRUNC:
1427+
case TargetOpcode::G_TRUNC_SSAT_S:
1428+
case TargetOpcode::G_TRUNC_SSAT_U:
1429+
case TargetOpcode::G_TRUNC_USAT_U:
14271430
case TargetOpcode::G_FPEXT:
14281431
case TargetOpcode::G_FPTRUNC: {
14291432
// Number of operands and presense of types is already checked (and
@@ -1450,6 +1453,9 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
14501453
report("Generic extend has destination type no larger than source", MI);
14511454
break;
14521455
case TargetOpcode::G_TRUNC:
1456+
case TargetOpcode::G_TRUNC_SSAT_S:
1457+
case TargetOpcode::G_TRUNC_SSAT_U:
1458+
case TargetOpcode::G_TRUNC_USAT_U:
14531459
case TargetOpcode::G_FPTRUNC:
14541460
if (DstSize >= SrcSize)
14551461
report("Generic truncate has destination type no smaller than source",

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,15 @@
319319
# DEBUG-NEXT: G_TRUNC (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
320320
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
321321
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
322+
# DEBUG-NEXT: G_TRUNC_SSAT_S (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
323+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
324+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
325+
# DEBUG-NEXT: G_TRUNC_SSAT_U (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
326+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
327+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
328+
# DEBUG-NEXT: G_TRUNC_USAT_U (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
329+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
330+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
322331
# DEBUG-NEXT: G_CONSTANT (opcode {{[0-9]+}}): 1 type index, 0 imm indices
323332
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
324333
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK

llvm/test/CodeGen/RISCV/GlobalISel/legalizer-info-validation.mir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,15 @@
315315
# DEBUG-NEXT: G_TRUNC (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
316316
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
317317
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
318+
# DEBUG-NEXT: G_TRUNC_SSAT_S (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
319+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
320+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
321+
# DEBUG-NEXT: G_TRUNC_SSAT_U (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
322+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
323+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
324+
# DEBUG-NEXT: G_TRUNC_USAT_U (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
325+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
326+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
318327
# DEBUG-NEXT: G_CONSTANT (opcode {{[0-9]+}}): 1 type index, 0 imm indices
319328
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
320329
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK

llvm/test/MC/ELF/mc-dump.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# CHECK-NEXT:0 Data Size:0 []
1313
# CHECK-NEXT: Symbol @0 _start
1414
# CHECK-NEXT:0 Org Offset:3 Value:0
15-
# CHECK-NEXT:3 Relaxable Size:2 <MCInst #1996 <MCOperand Expr:.Ltmp0>>
15+
# CHECK-NEXT:3 Relaxable Size:2 <MCInst #1999 <MCOperand Expr:.Ltmp0>>
1616
# CHECK-NEXT: Fixup @1 Value:.Ltmp0-1 Kind:4001
1717
# CHECK-NEXT:5 Data Size:16 [48,8b,04,25,00,00,00,00,48,8b,04,25,00,00,00,00]
1818
# CHECK-NEXT: Fixup @4 Value:f0@<variant 11> Kind:4017

0 commit comments

Comments
 (0)