[GlobalISel] Add a G_LROUND instruction
authorJessica Paquette <jpaquette@apple.com>
Thu, 19 Aug 2021 22:41:36 +0000 (15:41 -0700)
committerJessica Paquette <jpaquette@apple.com>
Fri, 20 Aug 2021 00:06:24 +0000 (17:06 -0700)
Meant to represent the `@llvm.lround.*` family.

Add the opcode, docs, and verification.

Differential Revision: https://reviews.llvm.org/D108417

llvm/docs/GlobalISel/GenericOpcode.rst
llvm/include/llvm/Support/TargetOpcodes.def
llvm/include/llvm/Target/GenericOpcodes.td
llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
llvm/lib/CodeGen/MachineVerifier.cpp
llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
llvm/test/MachineVerifier/test_g_lround.mir [new file with mode: 0644]

index 4abe069..e08e59e 100644 (file)
@@ -573,6 +573,19 @@ G_INTRINSIC_ROUND
 
 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
 --------------------------
 
index 6ba679b..99603b9 100644 (file)
@@ -652,6 +652,8 @@ HANDLE_TARGET_OPCODE(G_UMAX)
 /// 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)
 
index 4d0b91e..28aecd4 100644 (file)
@@ -232,6 +232,12 @@ def G_ISNAN: GenericInstruction {
   let hasSideEffects = false;
 }
 
+def G_LROUND: GenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type1:$src);
+  let hasSideEffects = false;
+}
+
 //------------------------------------------------------------------------------
 // Binary ops.
 //------------------------------------------------------------------------------
index 8a50524..647b694 100644 (file)
@@ -144,6 +144,7 @@ def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>;
 def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
 def : GINodeEquiv<G_ROTR, rotr>;
 def : GINodeEquiv<G_ROTL, rotl>;
+def : GINodeEquiv<G_LROUND, lround>;
 
 def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
 def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
index b527833..b15e488 100644 (file)
@@ -1615,6 +1615,13 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
     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;
   }
index ea35308..3bf999e 100644 (file)
 # 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 (file)
index 0000000..2f999b4
--- /dev/null
@@ -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>)