Skip to content

Commit

Permalink
[GlobalISel] Add G_LLROUND
Browse files Browse the repository at this point in the history
Basically the same as G_LROUND. Handles the llvm.llround family of intrinsics.

Also add a helper function to the MachineVerifier for checking if all of the
(virtual register) operands of an instruction are scalars. Seems like a useful
thing to have.

Differential Revision: https://reviews.llvm.org/D108429
  • Loading branch information
Jessica Paquette committed Aug 20, 2021
1 parent 0afd10b commit af8e09d
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 10 deletions.
6 changes: 3 additions & 3 deletions llvm/docs/GlobalISel/GenericOpcode.rst
Expand Up @@ -573,8 +573,8 @@ G_INTRINSIC_ROUND

Returns the operand rounded to the nearest integer.

G_LROUND
^^^^^^^^
G_LROUND, G_LLROUND
^^^^^^^^^^^^^^^^^^^

Returns the source operand rounded to the nearest integer with ties away from
zero.
Expand All @@ -584,7 +584,7 @@ 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)
%rounded_64:_(s64) = G_LLROUND %round_me:_(s64)
Vector Specific Operations
--------------------------
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/TargetOpcodes.def
Expand Up @@ -653,6 +653,7 @@ HANDLE_TARGET_OPCODE(G_UMAX)
HANDLE_TARGET_OPCODE(G_ABS)

HANDLE_TARGET_OPCODE(G_LROUND)
HANDLE_TARGET_OPCODE(G_LLROUND)

/// Generic BRANCH instruction. This is an unconditional branch.
HANDLE_TARGET_OPCODE(G_BR)
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/Target/GenericOpcodes.td
Expand Up @@ -238,6 +238,12 @@ def G_LROUND: GenericInstruction {
let hasSideEffects = false;
}

def G_LLROUND: GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type1:$src);
let hasSideEffects = false;
}

//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
Expand Up @@ -145,6 +145,7 @@ def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
def : GINodeEquiv<G_ROTR, rotr>;
def : GINodeEquiv<G_ROTL, rotl>;
def : GINodeEquiv<G_LROUND, lround>;
def : GINodeEquiv<G_LLROUND, llround>;

def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
Expand Down
27 changes: 22 additions & 5 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Expand Up @@ -210,6 +210,11 @@ namespace {
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineBundleBefore(const MachineInstr *MI);

/// Verify that all of \p MI's virtual register operands are scalars.
/// \returns True if all virtual register operands are scalar. False
/// otherwise.
bool verifyAllRegOpsScalar(const MachineInstr &MI,
const MachineRegisterInfo &MRI);
bool verifyVectorElementMatch(LLT Ty0, LLT Ty1, const MachineInstr *MI);
void verifyPreISelGenericInstruction(const MachineInstr *MI);
void visitMachineInstrBefore(const MachineInstr *MI);
Expand Down Expand Up @@ -849,6 +854,21 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
}
}

bool MachineVerifier::verifyAllRegOpsScalar(const MachineInstr &MI,
const MachineRegisterInfo &MRI) {
if (none_of(MI.explicit_operands(), [&MRI](const MachineOperand &Op) {
if (!Op.isReg())
return false;
const auto Reg = Op.getReg();
if (Reg.isPhysical())
return false;
return !MRI.getType(Reg).isScalar();
}))
return true;
report("All register operands must have scalar types", &MI);
return false;
}

/// Check that types are consistent when two operands need to have the same
/// number of vector elements.
/// \return true if the types are valid.
Expand Down Expand Up @@ -1614,14 +1634,11 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
}
break;
}

case TargetOpcode::G_LLROUND:
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);
verifyAllRegOpsScalar(*MI, *MRI);
break;
}

default:
break;
}
Expand Down
Expand Up @@ -529,6 +529,9 @@
# 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_LLROUND (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
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/MachineVerifier/test_g_llround.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_llround
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: All register operands must have scalar types
; CHECK: instruction: %no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
%no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
; CHECK: Bad machine code: All register operands must have scalar types
; CHECK: instruction: %no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
%no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
4 changes: 2 additions & 2 deletions llvm/test/MachineVerifier/test_g_lround.mir
Expand Up @@ -14,10 +14,10 @@ body: |
%ptr:_(p0) = COPY $x0
%vector:_(<2 x s64>) = COPY $q0
; CHECK: Bad machine code: lround only supports scalars
; CHECK: Bad machine code: All register operands must have scalar types
; 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: Bad machine code: All register operands must have scalar types
; CHECK: instruction: %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)
%no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)

0 comments on commit af8e09d

Please sign in to comment.