Since https://github.com/ARM-software/acle/pull/276 the ACLE defines attributes to better describe the use of a given SME state. Previously the attributes merely described the possibility of it being 'shared' or 'preserved', whereas the new attributes have more semantics and also describe how the data flows through the program. For ZT0 we already had to add new LLVM IR attributes: * aarch64_new_zt0 * aarch64_in_zt0 * aarch64_out_zt0 * aarch64_inout_zt0 * aarch64_preserves_zt0 We have now done the same for ZA, such that we add: * aarch64_new_za (previously `aarch64_pstate_za_new`) * aarch64_in_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_out_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_inout_za (more specific variation of `aarch64_pstate_za_shared`) * aarch64_preserves_za (previously `aarch64_pstate_za_shared, aarch64_pstate_za_preserved`) This explicitly removes 'pstate' from the name, because with SME2 and the new ACLE attributes there is a difference between "sharing ZA" (sharing the ZA matrix register with the caller) and "sharing PSTATE.ZA" (sharing either the ZA or ZT0 register, both part of PSTATE.ZA with the caller).
347 lines
8.8 KiB
LLVM
347 lines
8.8 KiB
LLVM
; RUN: mlir-translate -import-llvm -split-input-file %s --verify-diagnostics | FileCheck %s
|
|
|
|
; CHECK: llvm.func internal @func_internal
|
|
define internal void @func_internal() {
|
|
ret void
|
|
}
|
|
|
|
; CHECK: llvm.func internal spir_funccc @spir_func_internal()
|
|
define internal spir_func void @spir_func_internal() {
|
|
ret void
|
|
}
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_readnone
|
|
; CHECK-SAME: attributes {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
|
|
; CHECK: llvm.return
|
|
define void @func_readnone() readnone {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @func_readnone_indirect
|
|
; CHECK-SAME: attributes {memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>}
|
|
declare void @func_readnone_indirect() #0
|
|
attributes #0 = { readnone }
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_arg_attrs
|
|
; CHECK-SAME: !llvm.ptr {llvm.byval = i64}
|
|
; CHECK-SAME: !llvm.ptr {llvm.byref = i64}
|
|
; CHECK-SAME: !llvm.ptr {llvm.noalias}
|
|
; CHECK-SAME: !llvm.ptr {llvm.readonly}
|
|
; CHECK-SAME: !llvm.ptr {llvm.nest}
|
|
; CHECK-SAME: i32 {llvm.signext}
|
|
; CHECK-SAME: i64 {llvm.zeroext}
|
|
; CHECK-SAME: !llvm.ptr {llvm.align = 64 : i64, llvm.noundef}
|
|
; CHECK-SAME: !llvm.ptr {llvm.dereferenceable = 12 : i64}
|
|
; CHECK-SAME: !llvm.ptr {llvm.dereferenceable_or_null = 42 : i64}
|
|
; CHECK-SAME: f64 {llvm.inreg}
|
|
; CHECK-SAME: !llvm.ptr {llvm.nocapture}
|
|
; CHECK-SAME: !llvm.ptr {llvm.nofree}
|
|
; CHECK-SAME: !llvm.ptr {llvm.nonnull}
|
|
; CHECK-SAME: !llvm.ptr {llvm.preallocated = f64}
|
|
; CHECK-SAME: !llvm.ptr {llvm.returned}
|
|
; CHECK-SAME: !llvm.ptr {llvm.alignstack = 32 : i64}
|
|
; CHECK-SAME: !llvm.ptr {llvm.writeonly}
|
|
define ptr @func_arg_attrs(
|
|
ptr byval(i64) %arg0,
|
|
ptr byref(i64) %arg1,
|
|
ptr noalias %arg4,
|
|
ptr readonly %arg5,
|
|
ptr nest %arg6,
|
|
i32 signext %arg7,
|
|
i64 zeroext %arg8,
|
|
ptr align(64) noundef %arg9,
|
|
ptr dereferenceable(12) %arg10,
|
|
ptr dereferenceable_or_null(42) %arg11,
|
|
double inreg %arg12,
|
|
ptr nocapture %arg13,
|
|
ptr nofree %arg14,
|
|
ptr nonnull %arg15,
|
|
ptr preallocated(double) %arg16,
|
|
ptr returned %arg17,
|
|
ptr alignstack(32) %arg18,
|
|
ptr writeonly %arg19) {
|
|
ret ptr %arg17
|
|
}
|
|
|
|
; CHECK-LABEL: @sret
|
|
; CHECK-SAME: !llvm.ptr {llvm.sret = i64}
|
|
define void @sret(ptr sret(i64) %arg0) {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @inalloca
|
|
; CHECK-SAME: !llvm.ptr {llvm.inalloca = i64}
|
|
define void @inalloca(ptr inalloca(i64) %arg0) {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @allocator
|
|
; CHECK-SAME: i64 {llvm.allocalign}
|
|
; CHECK-SAME: ptr {llvm.allocptr}
|
|
declare ptr @allocator(i64 allocalign, ptr allocptr)
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_noalias
|
|
; CHECK-SAME: !llvm.ptr {llvm.noalias}
|
|
declare noalias ptr @func_res_attr_noalias()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_nonnull
|
|
; CHECK-SAME: !llvm.ptr {llvm.nonnull}
|
|
declare nonnull ptr @func_res_attr_nonnull()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_signext
|
|
; CHECK-DAG: llvm.noundef
|
|
; CHECK-DAG: llvm.signext
|
|
declare noundef signext i32 @func_res_attr_signext()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_zeroext
|
|
; CHECK-SAME: i32 {llvm.zeroext}
|
|
declare zeroext i32 @func_res_attr_zeroext()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_align
|
|
; CHECK-SAME: !llvm.ptr {llvm.align = 16 : i64}
|
|
declare align(16) ptr @func_res_attr_align()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_noundef
|
|
; CHECK-SAME: !llvm.ptr {llvm.noundef}
|
|
declare noundef ptr @func_res_attr_noundef()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_dereferenceable
|
|
; CHECK-SAME: !llvm.ptr {llvm.dereferenceable = 42 : i64}
|
|
declare dereferenceable(42) ptr @func_res_attr_dereferenceable()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_dereferenceable_or_null
|
|
; CHECK-SAME: !llvm.ptr {llvm.dereferenceable_or_null = 42 : i64}
|
|
declare dereferenceable_or_null(42) ptr @func_res_attr_dereferenceable_or_null()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_res_attr_inreg
|
|
; CHECK-SAME: !llvm.ptr {llvm.inreg}
|
|
declare inreg ptr @func_res_attr_inreg()
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @entry_count
|
|
; CHECK-SAME: attributes {function_entry_count = 4242 : i64}
|
|
define void @entry_count() !prof !1 {
|
|
ret void
|
|
}
|
|
|
|
!1 = !{!"function_entry_count", i64 4242}
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_memory
|
|
; CHECK-SAME: attributes {memory = #llvm.memory_effects<other = readwrite, argMem = none, inaccessibleMem = readwrite>}
|
|
; CHECK: llvm.return
|
|
define void @func_memory() memory(readwrite, argmem: none) {
|
|
ret void
|
|
}
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @passthrough_combined
|
|
; CHECK-SAME: attributes {passthrough = [
|
|
; CHECK-DAG: ["alignstack", "16"]
|
|
; CHECK-DAG: "noinline"
|
|
; CHECK-DAG: "probe-stack"
|
|
; CHECK-DAG: ["alloc-family", "malloc"]
|
|
; CHECK: llvm.return
|
|
define void @passthrough_combined() alignstack(16) noinline "probe-stack" "alloc-family"="malloc" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @passthrough_string_only
|
|
; CHECK-SAME: attributes {passthrough = ["no-enum-attr"]}
|
|
; CHECK: llvm.return
|
|
define void @passthrough_string_only() "no-enum-attr" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: llvm.func hidden @hidden()
|
|
define hidden void @hidden() {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: llvm.func protected @protected()
|
|
define protected void @protected() {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @streaming_func
|
|
; CHECK-SAME: attributes {arm_streaming}
|
|
define void @streaming_func() "aarch64_pstate_sm_enabled" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @locally_streaming_func
|
|
; CHECK-SAME: attributes {arm_locally_streaming}
|
|
define void @locally_streaming_func() "aarch64_pstate_sm_body" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @streaming_compatible_func
|
|
; CHECK-SAME: attributes {arm_streaming_compatible}
|
|
define void @streaming_compatible_func() "aarch64_pstate_sm_compatible" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @arm_new_za_func
|
|
; CHECK-SAME: attributes {arm_new_za}
|
|
define void @arm_new_za_func() "aarch64_new_za" {
|
|
ret void
|
|
}
|
|
|
|
|
|
; CHECK-LABEL: @arm_in_za_func
|
|
; CHECK-SAME: attributes {arm_in_za}
|
|
define void @arm_in_za_func() "aarch64_in_za" {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @arm_out_za_func
|
|
; CHECK-SAME: attributes {arm_out_za}
|
|
define void @arm_out_za_func() "aarch64_out_za" {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @arm_inout_za_func
|
|
; CHECK-SAME: attributes {arm_inout_za}
|
|
define void @arm_inout_za_func() "aarch64_inout_za" {
|
|
ret void
|
|
}
|
|
|
|
; CHECK-LABEL: @arm_preserves_za_func
|
|
; CHECK-SAME: attributes {arm_preserves_za}
|
|
define void @arm_preserves_za_func() "aarch64_preserves_za" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @section_func
|
|
; CHECK-SAME: attributes {section = ".section.name"}
|
|
define void @section_func() section ".section.name" {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: local_unnamed_addr @local_unnamed_addr_func
|
|
define void @local_unnamed_addr_func() local_unnamed_addr {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: unnamed_addr @unnamed_addr_func
|
|
declare void @unnamed_addr_func() unnamed_addr
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @align_func
|
|
; CHECK-SAME: attributes {alignment = 2 : i64}
|
|
define void @align_func() align 2 {
|
|
ret void
|
|
}
|
|
|
|
// -----
|
|
|
|
; CHECK-LABEL: @align_decl
|
|
; CHECK-SAME: attributes {alignment = 64 : i64}
|
|
declare void @align_decl() align 64
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_unsafe_fp_math_true
|
|
; CHECK-SAME: attributes {unsafe_fp_math = true}
|
|
declare void @func_attr_unsafe_fp_math_true() "unsafe-fp-math"="true"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_unsafe_fp_math_false
|
|
; CHECK-SAME: attributes {unsafe_fp_math = false}
|
|
declare void @func_attr_unsafe_fp_math_false() "unsafe-fp-math"="false"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_infs_fp_math_true
|
|
; CHECK-SAME: attributes {no_infs_fp_math = true}
|
|
declare void @func_attr_no_infs_fp_math_true() "no-infs-fp-math"="true"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_infs_fp_math_false
|
|
; CHECK-SAME: attributes {no_infs_fp_math = false}
|
|
declare void @func_attr_no_infs_fp_math_false() "no-infs-fp-math"="false"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_nans_fp_math_true
|
|
; CHECK-SAME: attributes {no_nans_fp_math = true}
|
|
declare void @func_attr_no_nans_fp_math_true() "no-nans-fp-math"="true"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_nans_fp_math_false
|
|
; CHECK-SAME: attributes {no_nans_fp_math = false}
|
|
declare void @func_attr_no_nans_fp_math_false() "no-nans-fp-math"="false"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_approx_func_fp_math_true
|
|
; CHECK-SAME: attributes {approx_func_fp_math = true}
|
|
declare void @func_attr_approx_func_fp_math_true() "approx-func-fp-math"="true"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_approx_func_fp_math_false
|
|
; CHECK-SAME: attributes {approx_func_fp_math = false}
|
|
declare void @func_attr_approx_func_fp_math_false() "approx-func-fp-math"="false"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_true
|
|
; CHECK-SAME: attributes {no_signed_zeros_fp_math = true}
|
|
declare void @func_attr_no_signed_zeros_fp_math_true() "no-signed-zeros-fp-math"="true"
|
|
|
|
; // -----
|
|
|
|
; CHECK-LABEL: @func_attr_no_signed_zeros_fp_math_false
|
|
; CHECK-SAME: attributes {no_signed_zeros_fp_math = false}
|
|
declare void @func_attr_no_signed_zeros_fp_math_false() "no-signed-zeros-fp-math"="false"
|