Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/docs/GlobalISel/GenericOpcode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,13 @@ undefined.
%2:_(s33) = G_CTLZ_ZERO_UNDEF %1
%2:_(s33) = G_CTTZ_ZERO_UNDEF %1

Compute the absolute difference (signed and unsigned), e.g. abs(x-y).

.. code-block:: none

%0:_(s33) = G_ABDS %2, %3
%1:_(s33) = G_ABDU %4, %5

Floating Point Operations
-------------------------

Expand Down
28 changes: 28 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,34 @@ class MachineIRBuilder {
return buildInstr(TargetOpcode::G_MUL, {Dst}, {Src0, Src1}, Flags);
}

/// Build and insert \p Res = G_ABDS \p Op0, \p Op1
///
/// G_ABDS return the signed absolute difference of \p Op0 and \p Op1.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
/// with the same (scalar or vector) type).
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildAbds(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1) {
return buildInstr(TargetOpcode::G_ABDS, {Dst}, {Src0, Src1});
}

/// Build and insert \p Res = G_ABDU \p Op0, \p Op1
///
/// G_ABDU return the unsigned absolute difference of \p Op0 and \p Op1.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Res, \p Op0 and \p Op1 must be generic virtual registers
/// with the same (scalar or vector) type).
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildAbdu(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1) {
return buildInstr(TargetOpcode::G_ABDU, {Dst}, {Src0, Src1});
}

MachineInstrBuilder buildUMulH(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1,
std::optional<unsigned> Flags = std::nullopt) {
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/Support/TargetOpcodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,12 @@ HANDLE_TARGET_OPCODE(G_OR)
/// Generic bitwise exclusive-or instruction.
HANDLE_TARGET_OPCODE(G_XOR)

/// Generic absolute difference signed instruction.
HANDLE_TARGET_OPCODE(G_ABDS)

/// Generic absolute difference unsigned instruction.
HANDLE_TARGET_OPCODE(G_ABDU)


HANDLE_TARGET_OPCODE(G_IMPLICIT_DEF)

Expand Down
16 changes: 16 additions & 0 deletions llvm/include/llvm/Target/GenericOpcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,22 @@ def G_ASHR : GenericInstruction {
let hasSideEffects = false;
}

// Generic absolute difference signed.
def G_ABDS : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
let hasSideEffects = false;
let isCommutable = true;
}

// Generic absolute difference unsigned.
def G_ABDU : GenericInstruction {
let OutOperandList = (outs type0:$dst);
let InOperandList = (ins type0:$src1, type0:$src2);
let hasSideEffects = false;
let isCommutable = true;
}

/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
/// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
def G_FSHL : GenericInstruction {
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,31 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {

break;
}
case TargetOpcode::G_ABDS:
case TargetOpcode::G_ABDU: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
LLT SrcTy2 = MRI->getType(MI->getOperand(2).getReg());

if ((DstTy.isVector() != SrcTy.isVector()) ||
(DstTy.isVector() &&
DstTy.getElementCount() != SrcTy.getElementCount())) {
report("Generic vector abds/abdu must preserve number of lanes", MI);
break;
}

if (SrcTy != SrcTy2) {
report("Generic abds/abdu must have same input types", MI);
break;
}

if (DstTy != SrcTy) {
report("Generic abds/abdu must have same input and output types", MI);
break;
}

break;
}
case TargetOpcode::G_SCMP:
case TargetOpcode::G_UCMP: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@
# DEBUG-NEXT: .. the first uncovered type index: 1, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
#
# DEBUG-NEXT: G_ABDS (opcode 65): 1 type index, 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_ABDU (opcode 66): 1 type index, 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_IMPLICIT_DEF (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. the first uncovered type index: {{[0-9]+}}, OK
# DEBUG-NEXT: .. the first uncovered imm index: {{[0-9]+}}, OK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@
# 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_ABDS (opcode 65): 1 type index, 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_ABDU (opcode 66): 1 type index, 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_IMPLICIT_DEF (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
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/MachineVerifier/test_abd_su.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# RUN: not --crash llc -verify-machineinstrs -mtriple=arm64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s
# REQUIRES: aarch64-registered-target

---
name: g_abd_su
body: |
bb.0:

%23:_(<2 x s32>) = G_IMPLICIT_DEF
%24:_(<2 x s32>) = G_IMPLICIT_DEF
; CHECK: Generic vector abds/abdu must preserve number of lanes
%5:_(s1) = G_ABDU %23, %24

%15:_(s32) = G_CONSTANT i32 0
%16:_(s64) = G_CONSTANT i64 2
; CHECK: Generic abds/abdu must have same input types
%17:_(s1) = G_ABDU %15, %16

%18:_(s64) = G_CONSTANT i64 0
%19:_(s64) = G_CONSTANT i64 2
; CHECK: Generic abds/abdu must have same input and output types
%20:_(s1) = G_ABDU %18, %19

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe check vector of pointer since that manages to always break

...

2 changes: 1 addition & 1 deletion llvm/test/TableGen/GlobalISelEmitter.td
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ def : Pat<(frag GPR32:$src1, complex:$src2, complex:$src3),
// R00O-NEXT: GIM_Reject,
// R00O: // Label [[DEFAULT_NUM]]: @[[DEFAULT]]
// R00O-NEXT: GIM_Reject,
// R00O-NEXT: }; // Size: 1832 bytes
// R00O-NEXT: }; // Size: 1840 bytes

def INSNBOB : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3, GPR32:$src4),
[(set GPR32:$dst,
Expand Down
Loading