Skip to content

Commit

Permalink
[SME2] Add LUTI2 and LUTI4 quad Builtins and Intrinsics (#73317)
Browse files Browse the repository at this point in the history
See ARM-software/acle#217

Patch by: Hassnaa Hamdi <hassnaa.hamdi@arm.com>
  • Loading branch information
MDevereau committed Dec 6, 2023
1 parent b3f0fa8 commit 6704d6a
Show file tree
Hide file tree
Showing 11 changed files with 766 additions and 7 deletions.
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/arm_sme.td
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,18 @@ let TargetGuard = "sme2" in {
let TargetGuard = "sme2" in {
def SVLDR_ZT : Inst<"svldr_zt", "viQ", "", MergeNone, "aarch64_sme_ldr_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA], [ImmCheck<0, ImmCheck0_0>]>;
def SVSTR_ZT : Inst<"svstr_zt", "vi%", "", MergeNone, "aarch64_sme_str_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>]>;
}

//
// Zero ZT0
//
let TargetGuard = "sme2" in {
def SVZERO_ZT : Inst<"svzero_zt", "vi", "", MergeNone, "aarch64_sme_zero_zt", [IsOverloadNone, IsStreamingCompatible, IsSharedZA], [ImmCheck<0, ImmCheck0_0>]>;
}

// lookup table expand four contiguous registers
//
let TargetGuard = "sme2" in {
def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>;
def SVLUTI4_LANE_ZT_X4 : Inst<"svluti4_lane_zt_{d}_x4", "4.di[i", "sUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x4", [IsStreaming, IsSharedZA, IsPreservesZA], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_1>]>;
}
1 change: 1 addition & 0 deletions clang/include/clang/Basic/arm_sve_sme_incl.td
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
// m: uint32_t
// n: uint64_t

// [: svuint8_t
// t: svint32_t
// z: svuint32_t
// g: svuint64_t
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_imm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,52 @@ void test_str_zt(void *base) __arm_streaming_compatible __arm_shared_za __arm_pr
svstr_zt(1, base); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
}

void test_svluti2_lane_zt_x4(svuint8_t zn) __arm_streaming __arm_shared_za __arm_preserves_za {
// Test Reg Offset
svluti2_lane_zt_u8_x4(1, zn, 0); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_u8_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
// Test Reg Offset
svluti2_lane_zt_u16_x4(1, zn, 3); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_u16_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
// Test Reg Offset
svluti2_lane_zt_u32_x4(1, zn, 3); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_u32_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
// Test Reg Offset
svluti2_lane_zt_f16_x4(1, zn, 3); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_f16_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
// Test Reg Offset
svluti2_lane_zt_bf16_x4(1, zn, 3); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_bf16_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
// Test Reg Offset
svluti2_lane_zt_f32_x4(1, zn, 3); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti2_lane_zt_f32_x4(0, zn, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
}

void test_svluti4_lane_zt_x4(svuint8_t zn) __arm_streaming __arm_shared_za __arm_preserves_za {
// Test Reg Offset
svluti4_lane_zt_u16_x4(1, zn, 0); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti4_lane_zt_u16_x4(0, zn, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
// Test Reg Offset
svluti4_lane_zt_u32_x4(1, zn, 1); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti4_lane_zt_u32_x4(0, zn, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
// Test Reg Offset
svluti4_lane_zt_f16_x4(1, zn, 0); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti4_lane_zt_f16_x4(0, zn, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
// Test Reg Offset
svluti4_lane_zt_bf16_x4(1, zn, 0); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti4_lane_zt_bf16_x4(0, zn, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
// Test Reg Offset
svluti4_lane_zt_f32_x4(1, zn, 1); // expected-error {{argument value 1 is outside the valid range [0, 0]}}
// Test index value range
svluti4_lane_zt_f32_x4(0, zn, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
}
6 changes: 6 additions & 0 deletions clang/utils/TableGen/SveEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,12 @@ void SVEType::applyModifier(char Mod) {
BFloat = false;
ElementBitwidth = 64;
break;
case '[':
Signed = false;
Float = false;
BFloat = false;
ElementBitwidth = 8;
break;
case 't':
Signed = true;
Float = false;
Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsAArch64.td
Original file line number Diff line number Diff line change
Expand Up @@ -3548,6 +3548,18 @@ let TargetPrefix = "aarch64" in {
// Zero ZT0
//
def int_aarch64_sme_zero_zt : DefaultAttrsIntrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>, IntrWriteMem]>;

//
// Lookup table expand four registers
//
def int_aarch64_sme_luti2_lane_zt_x4
: DefaultAttrsIntrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
[llvm_i32_ty, llvm_nxv16i8_ty, llvm_i32_ty],
[ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>, IntrReadMem]>;
def int_aarch64_sme_luti4_lane_zt_x4
: DefaultAttrsIntrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
[llvm_i32_ty, llvm_nxv16i8_ty, llvm_i32_ty],
[ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>, IntrReadMem]>;
}

// SVE2.1 - ZIPQ1, ZIPQ2, UZPQ1, UZPQ2
Expand Down
50 changes: 49 additions & 1 deletion llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
}

template <unsigned BaseReg, unsigned Max>
bool ImmToTile(SDValue N, SDValue &Imm) {
bool ImmToReg(SDValue N, SDValue &Imm) {
if (auto *CI = dyn_cast<ConstantSDNode>(N)) {
uint64_t C = CI->getZExtValue();

Expand Down Expand Up @@ -404,6 +404,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
return SelectSVERegRegAddrMode(N, Scale, Base, Offset);
}

void SelectMultiVectorLuti(SDNode *Node, unsigned NumOutVecs, unsigned Opc,
uint32_t MaxImm);

template <unsigned MaxIdx, unsigned Scale>
bool SelectSMETileSlice(SDValue N, SDValue &Vector, SDValue &Offset) {
return SelectSMETileSlice(N, MaxIdx, Vector, Offset, Scale);
Expand Down Expand Up @@ -1864,6 +1867,34 @@ void AArch64DAGToDAGISel::SelectFrintFromVT(SDNode *N, unsigned NumVecs,
SelectUnaryMultiIntrinsic(N, NumVecs, true, Opcode);
}

void AArch64DAGToDAGISel::SelectMultiVectorLuti(SDNode *Node,
unsigned NumOutVecs,
unsigned Opc, uint32_t MaxImm) {
if (ConstantSDNode *Imm = dyn_cast<ConstantSDNode>(Node->getOperand(4)))
if (Imm->getZExtValue() > MaxImm)
return;

SDValue ZtValue;
if (!ImmToReg<AArch64::ZT0, 0>(Node->getOperand(2), ZtValue))
return;
SDValue Ops[] = {ZtValue, Node->getOperand(3), Node->getOperand(4)};
SDLoc DL(Node);
EVT VT = Node->getValueType(0);

SDNode *Instruction =
CurDAG->getMachineNode(Opc, DL, {MVT::Untyped, MVT::Other}, Ops);
SDValue SuperReg = SDValue(Instruction, 0);

for (unsigned I = 0; I < NumOutVecs; ++I)
ReplaceUses(SDValue(Node, I), CurDAG->getTargetExtractSubreg(
AArch64::zsub0 + I, DL, VT, SuperReg));

// Copy chain
unsigned ChainIdx = NumOutVecs;
ReplaceUses(SDValue(Node, ChainIdx), SDValue(Instruction, 1));
CurDAG->RemoveDeadNode(Node);
}

void AArch64DAGToDAGISel::SelectClamp(SDNode *N, unsigned NumVecs,
unsigned Op) {
SDLoc DL(N);
Expand Down Expand Up @@ -5072,6 +5103,23 @@ void AArch64DAGToDAGISel::Select(SDNode *Node) {
MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(true);
return;
}
case Intrinsic::aarch64_sme_luti2_lane_zt_x4: {
if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
Node->getValueType(0),
{AArch64::LUTI2_4ZTZI_B, AArch64::LUTI2_4ZTZI_H,
AArch64::LUTI2_4ZTZI_S}))
// Second Immediate must be <= 3:
SelectMultiVectorLuti(Node, 4, Opc, 3);
return;
}
case Intrinsic::aarch64_sme_luti4_lane_zt_x4: {
if (auto Opc = SelectOpcodeFromVT<SelectTypeKind::AnyType>(
Node->getValueType(0),
{0, AArch64::LUTI4_4ZTZI_H, AArch64::LUTI4_4ZTZI_S}))
// Second Immediate must be <= 1:
SelectMultiVectorLuti(Node, 4, Opc, 1);
return;
}
}
} break;
case ISD::INTRINSIC_WO_CHAIN: {
Expand Down
12 changes: 6 additions & 6 deletions llvm/lib/Target/AArch64/SMEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
//
//===----------------------------------------------------------------------===//

def imm_to_tile8 : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZAB0, 0>", []>;
def imm_to_tile16 : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZAH0, 1>", []>;
def imm_to_tile32 : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZAS0, 3>", []>;
def imm_to_tile64 : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZAD0, 7>", []>;
def imm_to_tile128 : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZAQ0, 15>", []>;
def imm_to_zt : ComplexPattern<i32, 1, "ImmToTile<AArch64::ZT0, 0>", []>;
def imm_to_tile8 : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZAB0, 0>", []>;
def imm_to_tile16 : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZAH0, 1>", []>;
def imm_to_tile32 : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZAS0, 3>", []>;
def imm_to_tile64 : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZAD0, 7>", []>;
def imm_to_tile128 : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZAQ0, 15>", []>;
def imm_to_zt : ComplexPattern<i32, 1, "ImmToReg<AArch64::ZT0, 0>", []>;

def tileslice8 : ComplexPattern<i32 , 2, "SelectSMETileSlice<15, 1>", []>;
def tileslice16 : ComplexPattern<i32 , 2, "SelectSMETileSlice<7, 1>", []>;
Expand Down
66 changes: 66 additions & 0 deletions llvm/test/CodeGen/AArch64/sme2-intrinsics-luti2-lane-x4.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme2 < %s | FileCheck %s

; lookup table expand one register

define {<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @luti2_i8(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_i8:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.b - z3.b }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv16i8(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} %res
}

define {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @luti2_i16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_i16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.h - z3.h }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8i16(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} %res
}

define {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @luti2_i32(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_i32:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.s - z3.s }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv4i32(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>}%res
}

define {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @luti2_f16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_f16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.h - z3.h }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8f16(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} %res
}

define {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @luti2_bf16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_bf16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.h - z3.h }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8bf16(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} %res
}

define {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @luti2_f32(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti2_f32:
; CHECK: // %bb.0:
; CHECK-NEXT: luti2 { z0.s - z3.s }, zt0, z0[3]
; CHECK-NEXT: ret
%res = call {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv4f32(i32 0, <vscale x 16 x i8> %x, i32 3)
ret {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>}%res
}


declare {<vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv16i8(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8i16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv4i32(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8f16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8bf16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @llvm.aarch64.sme.luti2.lane.zt.x4.nxv4f32(i32, <vscale x 16 x i8>, i32)
55 changes: 55 additions & 0 deletions llvm/test/CodeGen/AArch64/sme2-intrinsics-luti4-lane-x4.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sme2 < %s | FileCheck %s

; lookup table expand one register

define {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @luti4_i16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti4_i16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti4 { z0.h - z3.h }, zt0, z0[1]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8i16(i32 0, <vscale x 16 x i8> %x, i32 1)
ret {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} %res
}

define {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @luti4_i32(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti4_i32:
; CHECK: // %bb.0:
; CHECK-NEXT: luti4 { z0.s - z3.s }, zt0, z0[1]
; CHECK-NEXT: ret
%res = call {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv4i32(i32 0, <vscale x 16 x i8> %x, i32 1)
ret {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} %res
}

define {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @luti4_bf16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti4_bf16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti4 { z0.h - z3.h }, zt0, z0[1]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8bf16(i32 0, <vscale x 16 x i8> %x, i32 1)
ret {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} %res
}

define {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @luti4_f16(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti4_f16:
; CHECK: // %bb.0:
; CHECK-NEXT: luti4 { z0.h - z3.h }, zt0, z0[1]
; CHECK-NEXT: ret
%res = call {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8f16(i32 0, <vscale x 16 x i8> %x, i32 1)
ret {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} %res
}

define {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @luti4_f32(<vscale x 16 x i8> %x) {
; CHECK-LABEL: luti4_f32:
; CHECK: // %bb.0:
; CHECK-NEXT: luti4 { z0.s - z3.s }, zt0, z0[1]
; CHECK-NEXT: ret
%res = call {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv4f32(i32 0, <vscale x 16 x i8> %x, i32 1)
ret {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} %res
}

declare {<vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>, <vscale x 8 x i16>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8i16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv4i32(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>, <vscale x 8 x bfloat>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8bf16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>, <vscale x 8 x half>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv8f16(i32, <vscale x 16 x i8>, i32)
declare {<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>} @llvm.aarch64.sme.luti4.lane.zt.x4.nxv4f32(i32, <vscale x 16 x i8>, i32)

0 comments on commit 6704d6a

Please sign in to comment.