Skip to content

Commit 5553320

Browse files
committed
[GlobalISel] Add G_ROTR and G_ROTL opcodes for rotates.
Differential Revision: https://reviews.llvm.org/D99383
1 parent 23f657c commit 5553320

File tree

8 files changed

+69
-0
lines changed

8 files changed

+69
-0
lines changed

llvm/docs/GlobalISel/GenericOpcode.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ G_SHL, G_LSHR, G_ASHR
301301

302302
Shift the bits of a scalar left or right inserting zeros (sign-bit for G_ASHR).
303303

304+
G_ROTR, G_ROTL
305+
^^^^^^^^^^^^^^
306+
307+
Rotate the bits right (G_ROTR) or left (G_ROTL).
308+
304309
G_ICMP
305310
^^^^^^
306311

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,18 @@ class MachineIRBuilder {
18561856
return buildInstr(TargetOpcode::G_UBFX, {Dst}, {Src, LSB, Width});
18571857
}
18581858

1859+
/// Build and insert \p Dst = G_ROTR \p Src, \p Amt
1860+
MachineInstrBuilder buildRotateRight(const DstOp &Dst, const SrcOp &Src,
1861+
const SrcOp &Amt) {
1862+
return buildInstr(TargetOpcode::G_ROTR, {Dst}, {Src, Amt});
1863+
}
1864+
1865+
/// Build and insert \p Dst = G_ROTL \p Src, \p Amt
1866+
MachineInstrBuilder buildRotateLeft(const DstOp &Dst, const SrcOp &Src,
1867+
const SrcOp &Amt) {
1868+
return buildInstr(TargetOpcode::G_ROTL, {Dst}, {Src, Amt});
1869+
}
1870+
18591871
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
18601872
ArrayRef<SrcOp> SrcOps,
18611873
Optional<unsigned> Flags = None);

llvm/include/llvm/Support/TargetOpcodes.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,12 @@ HANDLE_TARGET_OPCODE(G_FSHL)
432432
// Generic funnel right shift
433433
HANDLE_TARGET_OPCODE(G_FSHR)
434434

435+
// Generic right rotate
436+
HANDLE_TARGET_OPCODE(G_ROTR)
437+
438+
// Generic left rotate
439+
HANDLE_TARGET_OPCODE(G_ROTL)
440+
435441
/// Generic integer-base comparison, also applicable to vectors of integers.
436442
HANDLE_TARGET_OPCODE(G_ICMP)
437443

llvm/include/llvm/Target/GenericOpcodes.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,20 @@ def G_FSHR : GenericInstruction {
362362
let hasSideEffects = false;
363363
}
364364

365+
/// Rotate bits right.
366+
def G_ROTR : GenericInstruction {
367+
let OutOperandList = (outs type0:$dst);
368+
let InOperandList = (ins type0:$src1, type1:$src2);
369+
let hasSideEffects = false;
370+
}
371+
372+
/// Rotate bits left.
373+
def G_ROTL : GenericInstruction {
374+
let OutOperandList = (outs type0:$dst);
375+
let InOperandList = (ins type0:$src1, type1:$src2);
376+
let hasSideEffects = false;
377+
}
378+
365379
// Generic integer comparison.
366380
def G_ICMP : GenericInstruction {
367381
let OutOperandList = (outs type0:$dst);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ def : GINodeEquiv<G_FMAXNUM, fmaxnum>;
141141
def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
142142
def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>;
143143
def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
144+
def : GINodeEquiv<G_ROTR, rotr>;
145+
def : GINodeEquiv<G_ROTL, rotl>;
144146

145147
def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
146148
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,6 +1578,17 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
15781578
}
15791579
break;
15801580
}
1581+
case TargetOpcode::G_ROTR:
1582+
case TargetOpcode::G_ROTL: {
1583+
LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
1584+
LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
1585+
if (Src1Ty.isVector() != Src2Ty.isVector()) {
1586+
report("Rotate requires operands to be either all scalars or all vectors",
1587+
MI);
1588+
break;
1589+
}
1590+
break;
1591+
}
15811592

15821593
default:
15831594
break;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@
291291
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
292292
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
293293
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
294+
# DEBUG-NEXT: G_ROTR (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
295+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
296+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
297+
# DEBUG-NEXT: G_ROTL (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
298+
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
299+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
294300
# DEBUG-NEXT: G_ICMP (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
295301
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
296302
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# RUN: not --crash llc -march=arm64 -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
2+
# REQUIRES: aarch64-registered-target
3+
---
4+
name: test_uniform
5+
body: |
6+
bb.0:
7+
%src:_(<2 x s64>) = G_IMPLICIT_DEF
8+
%amt:_(s64) = G_IMPLICIT_DEF
9+
10+
; CHECK: Rotate requires operands to be either all scalars or all vectors
11+
%rotr:_(<2 x s64>) = G_ROTR %src, %amt
12+
13+
...

0 commit comments

Comments
 (0)