Skip to content

Commit af8e09d

Browse files
author
Jessica Paquette
committed
[GlobalISel] Add G_LLROUND
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
1 parent 0afd10b commit af8e09d

File tree

8 files changed

+61
-10
lines changed

8 files changed

+61
-10
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,8 @@ G_INTRINSIC_ROUND
573573

574574
Returns the operand rounded to the nearest integer.
575575

576-
G_LROUND
577-
^^^^^^^^
576+
G_LROUND, G_LLROUND
577+
^^^^^^^^^^^^^^^^^^^
578578

579579
Returns the source operand rounded to the nearest integer with ties away from
580580
zero.
@@ -584,7 +584,7 @@ See the LLVM LangRef entry on '``llvm.lround.*'`` for details on behaviour.
584584
.. code-block:: none
585585
586586
%rounded_32:_(s32) = G_LROUND %round_me:_(s64)
587-
%rounded_64:_(s64) = G_LROUND %round_me:_(s64)
587+
%rounded_64:_(s64) = G_LLROUND %round_me:_(s64)
588588
589589
Vector Specific Operations
590590
--------------------------

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,7 @@ HANDLE_TARGET_OPCODE(G_UMAX)
653653
HANDLE_TARGET_OPCODE(G_ABS)
654654

655655
HANDLE_TARGET_OPCODE(G_LROUND)
656+
HANDLE_TARGET_OPCODE(G_LLROUND)
656657

657658
/// Generic BRANCH instruction. This is an unconditional branch.
658659
HANDLE_TARGET_OPCODE(G_BR)

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ def G_LROUND: GenericInstruction {
238238
let hasSideEffects = false;
239239
}
240240

241+
def G_LLROUND: GenericInstruction {
242+
let OutOperandList = (outs type0:$dst);
243+
let InOperandList = (ins type1:$src);
244+
let hasSideEffects = false;
245+
}
246+
241247
//------------------------------------------------------------------------------
242248
// Binary ops.
243249
//------------------------------------------------------------------------------

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
145145
def : GINodeEquiv<G_ROTR, rotr>;
146146
def : GINodeEquiv<G_ROTL, rotl>;
147147
def : GINodeEquiv<G_LROUND, lround>;
148+
def : GINodeEquiv<G_LLROUND, llround>;
148149

149150
def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
150151
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ namespace {
210210
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
211211
void visitMachineBundleBefore(const MachineInstr *MI);
212212

213+
/// Verify that all of \p MI's virtual register operands are scalars.
214+
/// \returns True if all virtual register operands are scalar. False
215+
/// otherwise.
216+
bool verifyAllRegOpsScalar(const MachineInstr &MI,
217+
const MachineRegisterInfo &MRI);
213218
bool verifyVectorElementMatch(LLT Ty0, LLT Ty1, const MachineInstr *MI);
214219
void verifyPreISelGenericInstruction(const MachineInstr *MI);
215220
void visitMachineInstrBefore(const MachineInstr *MI);
@@ -849,6 +854,21 @@ void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
849854
}
850855
}
851856

857+
bool MachineVerifier::verifyAllRegOpsScalar(const MachineInstr &MI,
858+
const MachineRegisterInfo &MRI) {
859+
if (none_of(MI.explicit_operands(), [&MRI](const MachineOperand &Op) {
860+
if (!Op.isReg())
861+
return false;
862+
const auto Reg = Op.getReg();
863+
if (Reg.isPhysical())
864+
return false;
865+
return !MRI.getType(Reg).isScalar();
866+
}))
867+
return true;
868+
report("All register operands must have scalar types", &MI);
869+
return false;
870+
}
871+
852872
/// Check that types are consistent when two operands need to have the same
853873
/// number of vector elements.
854874
/// \return true if the types are valid.
@@ -1614,14 +1634,11 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
16141634
}
16151635
break;
16161636
}
1617-
1637+
case TargetOpcode::G_LLROUND:
16181638
case TargetOpcode::G_LROUND: {
1619-
if (!MRI->getType(MI->getOperand(0).getReg()).isScalar() ||
1620-
!MRI->getType(MI->getOperand(1).getReg()).isScalar())
1621-
report("lround only supports scalars", MI);
1639+
verifyAllRegOpsScalar(*MI, *MRI);
16221640
break;
16231641
}
1624-
16251642
default:
16261643
break;
16271644
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@
529529
# DEBUG-NEXT: G_LROUND (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
530530
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
531531
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
532+
# DEBUG-NEXT: G_LLROUND (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
533+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
534+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
532535
# DEBUG-NEXT: G_BR (opcode {{[0-9]+}}): 0 type indices, 0 imm indices
533536
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
534537
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#RUN: not --crash llc -march=aarch64 -o - -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
2+
# REQUIRES: aarch64-registered-target
3+
4+
---
5+
name: test_llround
6+
legalized: true
7+
regBankSelected: false
8+
selected: false
9+
tracksRegLiveness: true
10+
liveins:
11+
body: |
12+
bb.0:
13+
liveins: $x0, $q0
14+
%ptr:_(p0) = COPY $x0
15+
%vector:_(<2 x s64>) = COPY $q0
16+
17+
; CHECK: Bad machine code: All register operands must have scalar types
18+
; CHECK: instruction: %no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
19+
%no_ptrs:_(s64) = G_LROUND %ptr:_(p0)
20+
21+
; CHECK: Bad machine code: All register operands must have scalar types
22+
; CHECK: instruction: %no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)
23+
%no_vectors:_(s64) = G_LROUND %vector:_(<2 x s64>)

llvm/test/MachineVerifier/test_g_lround.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ body: |
1414
%ptr:_(p0) = COPY $x0
1515
%vector:_(<2 x s64>) = COPY $q0
1616
17-
; CHECK: Bad machine code: lround only supports scalars
17+
; CHECK: Bad machine code: All register operands must have scalar types
1818
; CHECK: instruction: %no_ptrs:_(s32) = G_LROUND %ptr:_(p0)
1919
%no_ptrs:_(s32) = G_LROUND %ptr:_(p0)
2020
21-
; CHECK: Bad machine code: lround only supports scalars
21+
; CHECK: Bad machine code: All register operands must have scalar types
2222
; CHECK: instruction: %no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)
2323
%no_vectors:_(s32) = G_LROUND %vector:_(<2 x s64>)

0 commit comments

Comments
 (0)