forked from OSchip/llvm-project
[GlobalISel] Add G_ROTR and G_ROTL opcodes for rotates.
Differential Revision: https://reviews.llvm.org/D99383
This commit is contained in:
parent
23f657c165
commit
55533203d7
|
@ -301,6 +301,11 @@ G_SHL, G_LSHR, G_ASHR
|
|||
|
||||
Shift the bits of a scalar left or right inserting zeros (sign-bit for G_ASHR).
|
||||
|
||||
G_ROTR, G_ROTL
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Rotate the bits right (G_ROTR) or left (G_ROTL).
|
||||
|
||||
G_ICMP
|
||||
^^^^^^
|
||||
|
||||
|
|
|
@ -1856,6 +1856,18 @@ public:
|
|||
return buildInstr(TargetOpcode::G_UBFX, {Dst}, {Src, LSB, Width});
|
||||
}
|
||||
|
||||
/// Build and insert \p Dst = G_ROTR \p Src, \p Amt
|
||||
MachineInstrBuilder buildRotateRight(const DstOp &Dst, const SrcOp &Src,
|
||||
const SrcOp &Amt) {
|
||||
return buildInstr(TargetOpcode::G_ROTR, {Dst}, {Src, Amt});
|
||||
}
|
||||
|
||||
/// Build and insert \p Dst = G_ROTL \p Src, \p Amt
|
||||
MachineInstrBuilder buildRotateLeft(const DstOp &Dst, const SrcOp &Src,
|
||||
const SrcOp &Amt) {
|
||||
return buildInstr(TargetOpcode::G_ROTL, {Dst}, {Src, Amt});
|
||||
}
|
||||
|
||||
virtual MachineInstrBuilder buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
|
||||
ArrayRef<SrcOp> SrcOps,
|
||||
Optional<unsigned> Flags = None);
|
||||
|
|
|
@ -432,6 +432,12 @@ HANDLE_TARGET_OPCODE(G_FSHL)
|
|||
// Generic funnel right shift
|
||||
HANDLE_TARGET_OPCODE(G_FSHR)
|
||||
|
||||
// Generic right rotate
|
||||
HANDLE_TARGET_OPCODE(G_ROTR)
|
||||
|
||||
// Generic left rotate
|
||||
HANDLE_TARGET_OPCODE(G_ROTL)
|
||||
|
||||
/// Generic integer-base comparison, also applicable to vectors of integers.
|
||||
HANDLE_TARGET_OPCODE(G_ICMP)
|
||||
|
||||
|
|
|
@ -362,6 +362,20 @@ def G_FSHR : GenericInstruction {
|
|||
let hasSideEffects = false;
|
||||
}
|
||||
|
||||
/// Rotate bits right.
|
||||
def G_ROTR : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type1:$src2);
|
||||
let hasSideEffects = false;
|
||||
}
|
||||
|
||||
/// Rotate bits left.
|
||||
def G_ROTL : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins type0:$src1, type1:$src2);
|
||||
let hasSideEffects = false;
|
||||
}
|
||||
|
||||
// Generic integer comparison.
|
||||
def G_ICMP : GenericInstruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
|
|
|
@ -141,6 +141,8 @@ def : GINodeEquiv<G_FMAXNUM, fmaxnum>;
|
|||
def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
|
||||
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_STRICT_FADD, strict_fadd>;
|
||||
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
|
||||
|
|
|
@ -1578,6 +1578,17 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TargetOpcode::G_ROTR:
|
||||
case TargetOpcode::G_ROTL: {
|
||||
LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
|
||||
LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
|
||||
if (Src1Ty.isVector() != Src2Ty.isVector()) {
|
||||
report("Rotate requires operands to be either all scalars or all vectors",
|
||||
MI);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -291,6 +291,12 @@
|
|||
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
|
||||
# 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_ROTR (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_ROTL (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_ICMP (opcode {{[0-9]+}}): 2 type indices, 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
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# RUN: not --crash llc -march=arm64 -verify-machineinstrs -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
|
||||
# REQUIRES: aarch64-registered-target
|
||||
---
|
||||
name: test_uniform
|
||||
body: |
|
||||
bb.0:
|
||||
%src:_(<2 x s64>) = G_IMPLICIT_DEF
|
||||
%amt:_(s64) = G_IMPLICIT_DEF
|
||||
|
||||
; CHECK: Rotate requires operands to be either all scalars or all vectors
|
||||
%rotr:_(<2 x s64>) = G_ROTR %src, %amt
|
||||
|
||||
...
|
Loading…
Reference in New Issue