diff --git a/llvm/docs/GlobalISel/GenericOpcode.rst b/llvm/docs/GlobalISel/GenericOpcode.rst --- a/llvm/docs/GlobalISel/GenericOpcode.rst +++ b/llvm/docs/GlobalISel/GenericOpcode.rst @@ -573,6 +573,19 @@ Returns the operand rounded to the nearest integer. +G_LROUND +^^^^^^^^ + +Returns the source operand rounded to the nearest integer with ties away from +zero. + +See the LLVM LangRef entry on '``llvm.lround.*'`` for details on behaviour. + +.. code-block:: none + + %rounded_32:_(s32) = G_LROUND %round_me:_(s64) + %rounded_64:_(s64) = G_LROUND %round_me:_(s64) + Vector Specific Operations -------------------------- diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -652,6 +652,8 @@ /// Generic integer absolute value. HANDLE_TARGET_OPCODE(G_ABS) +HANDLE_TARGET_OPCODE(G_LROUND) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -232,6 +232,12 @@ let hasSideEffects = false; } +def G_LROUND: GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type1:$src); + let hasSideEffects = false; +} + //------------------------------------------------------------------------------ // Binary ops. //------------------------------------------------------------------------------ diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -144,6 +144,7 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1615,6 +1615,13 @@ break; } + case TargetOpcode::G_LROUND: { + if (!MRI->getType(MI->getOperand(0).getReg()).isScalar() || + !MRI->getType(MI->getOperand(1).getReg()).isScalar()) + report("lround only supports scalars", MI); + break; + } + default: break; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -526,6 +526,9 @@ # DEBUG-NEXT: G_ABS (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected # DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected +# DEBUG-NEXT: G_LROUND (opcode {{[0-9]+}}): 2 type indices, 0 imm indices +# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_BR (opcode {{[0-9]+}}): 0 type indices, 0 imm indices # DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined # DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined diff --git a/llvm/test/MachineVerifier/test_g_lround.mir b/llvm/test/MachineVerifier/test_g_lround.mir new file mode 100644 --- /dev/null +++ b/llvm/test/MachineVerifier/test_g_lround.mir @@ -0,0 +1,23 @@ +#RUN: not --crash llc -march=aarch64 -o - -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: aarch64-registered-target + +--- +name: test_lround +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + liveins: $x0, $q0 + %ptr:_(p0) = COPY $x0 + %vector:_(<2 x s64>) = COPY $q0 + + ; CHECK: Bad machine code: lround only supports scalars + ; CHECK: instruction: %no_ptrs:_(s32) = G_LROUND %ptr:_(p0) + %no_ptrs:_(s32) = G_LROUND %ptr:_(p0) + + ; CHECK: Bad machine code: lround only supports scalars + ; CHECK: instruction: %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>) + %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)