From patchwork Tue Apr 5 16:34:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1613510 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=P5vem4HX; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KXtYN6lyZz9sFk for ; Wed, 6 Apr 2022 02:35:36 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5F6213857829 for ; Tue, 5 Apr 2022 16:35:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5F6213857829 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1649176534; bh=7a8q4o65cahWTx5gnSZtP6EP5B6/Sb5TxsjceaY2XeU=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=P5vem4HXi0nGwARGcaDWm8AceHBPZXgxrs10zDPClTBDZ8OJuFHKvu+sr+w4gdSHX 1FEdSkAN+fjZfgb8xkoShpzf6NqGSiUk/2srURRqPHxUtDO7jMEqVsUcYg200McewJ fcSlCud2S6VdHfaTi+optPOc9kOhApmkDshcCXBE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id BB01D3857830 for ; Tue, 5 Apr 2022 16:34:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BB01D3857830 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7802223A for ; Tue, 5 Apr 2022 09:34:31 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.88]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 067093F718 for ; Tue, 5 Apr 2022 09:34:30 -0700 (PDT) To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [pushed] aarch64: Fix -fpack-struct + [PR103147] Date: Tue, 05 Apr 2022 17:34:29 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Sandiford via Gcc-patches From: Richard Sandiford Reply-To: Richard Sandiford Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This PR is about -fpack-struct causing a crash when is included. The new register_tuple_type code was expecting a normal unpacked structure layout instead of a packed one. For SVE we got around this by temporarily suppressing -fpack-struct, so that the tuple types always have their normal ABI. However: (a) The SVE ACLE tuple types are defined to be abstract. The fact that GCC uses structures is an internal implementation detail. (b) In contrast, the ACLE explicitly defines the Advanced SIMD tuple types to be particular structures. (c) Clang and previous versions of GCC are consistent in applying -fpack-struct to these tuple structures. This patch therefore honours -fpack-struct and -fpack-struct=. It also adds tests for some other combinations, such as -mgeneral-regs-only and -fpack-struct -mstrict-align. Tested on aarch64-linux-gnu & pushed. Richard gcc/ PR target/103147 * config/aarch64/aarch64-protos.h (aarch64_simd_switcher): New class. * config/aarch64/aarch64-sve-builtins.h (sve_switcher): Inherit from aarch64_simd_switcher. * config/aarch64/aarch64-builtins.cc (aarch64_simd_tuple_modes): New variable. (aarch64_lookup_simd_builtin_type): Use it instead of TYPE_MODE. (register_tuple_type): Add more asserts. Expect the alignment of the structure to be subject to flag_pack_struct and maximum_field_alignment. Set aarch64_simd_tuple_modes. (aarch64_simd_switcher::aarch64_simd_switcher): New function. (aarch64_simd_switcher::~aarch64_simd_switcher): Likewise. (handle_arm_neon_h): Hold an aarch64_simd_switcher throughout. (aarch64_general_init_builtins): Hold an aarch64_simd_switcher while calling aarch64_init_simd_builtins. * config/aarch64/aarch64-sve-builtins.cc (sve_switcher::sve_switcher) (sve_switcher::~sve_switcher): Remove code now performed by aarch64_simd_switcher. gcc/testsuite/ PR target/103147 * gcc.target/aarch64/pr103147-1.c: New test. * gcc.target/aarch64/pr103147-2.c: Likewise. * gcc.target/aarch64/pr103147-3.c: Likewise. * gcc.target/aarch64/pr103147-4.c: Likewise. * gcc.target/aarch64/pr103147-5.c: Likewise. * gcc.target/aarch64/pr103147-6.c: Likewise. * gcc.target/aarch64/pr103147-7.c: Likewise. * gcc.target/aarch64/pr103147-8.c: Likewise. * gcc.target/aarch64/pr103147-9.c: Likewise. * gcc.target/aarch64/pr103147-10.c: Likewise. * g++.target/aarch64/pr103147-1.C: Likewise. * g++.target/aarch64/pr103147-2.C: Likewise. * g++.target/aarch64/pr103147-3.C: Likewise. * g++.target/aarch64/pr103147-4.C: Likewise. * g++.target/aarch64/pr103147-5.C: Likewise. * g++.target/aarch64/pr103147-6.C: Likewise. * g++.target/aarch64/pr103147-7.C: Likewise. * g++.target/aarch64/pr103147-8.C: Likewise. * g++.target/aarch64/pr103147-9.C: Likewise. * g++.target/aarch64/pr103147-10.C: Likewise. --- gcc/config/aarch64/aarch64-builtins.cc | 49 ++++++++--- gcc/config/aarch64/aarch64-protos.h | 13 +++ gcc/config/aarch64/aarch64-sve-builtins.cc | 11 +-- gcc/config/aarch64/aarch64-sve-builtins.h | 4 +- gcc/testsuite/g++.target/aarch64/pr103147-1.C | 12 +++ .../g++.target/aarch64/pr103147-10.C | 88 +++++++++++++++++++ gcc/testsuite/g++.target/aarch64/pr103147-2.C | 12 +++ gcc/testsuite/g++.target/aarch64/pr103147-3.C | 12 +++ gcc/testsuite/g++.target/aarch64/pr103147-4.C | 12 +++ gcc/testsuite/g++.target/aarch64/pr103147-5.C | 12 +++ gcc/testsuite/g++.target/aarch64/pr103147-6.C | 3 + gcc/testsuite/g++.target/aarch64/pr103147-7.C | 3 + gcc/testsuite/g++.target/aarch64/pr103147-8.C | 3 + gcc/testsuite/g++.target/aarch64/pr103147-9.C | 10 +++ gcc/testsuite/gcc.target/aarch64/pr103147-1.c | 12 +++ .../gcc.target/aarch64/pr103147-10.c | 84 ++++++++++++++++++ gcc/testsuite/gcc.target/aarch64/pr103147-2.c | 12 +++ gcc/testsuite/gcc.target/aarch64/pr103147-3.c | 12 +++ gcc/testsuite/gcc.target/aarch64/pr103147-4.c | 12 +++ gcc/testsuite/gcc.target/aarch64/pr103147-5.c | 12 +++ gcc/testsuite/gcc.target/aarch64/pr103147-6.c | 3 + gcc/testsuite/gcc.target/aarch64/pr103147-7.c | 3 + gcc/testsuite/gcc.target/aarch64/pr103147-8.c | 3 + gcc/testsuite/gcc.target/aarch64/pr103147-9.c | 10 +++ 24 files changed, 382 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-1.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-10.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-2.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-3.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-4.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-5.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-6.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-7.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-8.C create mode 100644 gcc/testsuite/g++.target/aarch64/pr103147-9.C create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-10.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-2.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-3.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-4.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-5.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-6.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-7.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-8.c create mode 100644 gcc/testsuite/gcc.target/aarch64/pr103147-9.c diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 5217dbdb2ac..6ebeee75d0a 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -716,6 +716,7 @@ static GTY(()) struct aarch64_simd_type_info aarch64_simd_types [] = { }; #undef ENTRY +static machine_mode aarch64_simd_tuple_modes[ARM_NEON_H_TYPES_LAST][3]; static GTY(()) tree aarch64_simd_tuple_types[ARM_NEON_H_TYPES_LAST][3]; static GTY(()) tree aarch64_simd_intOI_type_node = NULL_TREE; @@ -844,7 +845,7 @@ aarch64_lookup_simd_builtin_type (machine_mode mode, return aarch64_simd_types[i].itype; if (aarch64_simd_tuple_types[i][0] != NULL_TREE) for (int j = 0; j < 3; j++) - if (TYPE_MODE (aarch64_simd_tuple_types[i][j]) == mode + if (aarch64_simd_tuple_modes[i][j] == mode && aarch64_simd_types[i].q == q) return aarch64_simd_tuple_types[i][j]; } @@ -1297,8 +1298,10 @@ register_tuple_type (unsigned int num_vectors, unsigned int type_index) } unsigned int alignment - = (known_eq (GET_MODE_SIZE (type->mode), 16) ? 128 : 64); - gcc_assert (TYPE_MODE_RAW (array_type) == TYPE_MODE (array_type) + = known_eq (GET_MODE_SIZE (type->mode), 16) ? 128 : 64; + machine_mode tuple_mode = TYPE_MODE_RAW (array_type); + gcc_assert (VECTOR_MODE_P (tuple_mode) + && TYPE_MODE (array_type) == tuple_mode && TYPE_ALIGN (array_type) == alignment); tree field = build_decl (input_location, FIELD_DECL, @@ -1309,14 +1312,13 @@ register_tuple_type (unsigned int num_vectors, unsigned int type_index) make_array_slice (&field, 1)); gcc_assert (TYPE_MODE_RAW (t) == TYPE_MODE (t) - && TYPE_ALIGN (t) == alignment); - - if (num_vectors == 2) - aarch64_simd_tuple_types[type_index][0] = t; - else if (num_vectors == 3) - aarch64_simd_tuple_types[type_index][1] = t; - else if (num_vectors == 4) - aarch64_simd_tuple_types[type_index][2] = t; + && (flag_pack_struct + || maximum_field_alignment + || (TYPE_MODE_RAW (t) == tuple_mode + && TYPE_ALIGN (t) == alignment))); + + aarch64_simd_tuple_modes[type_index][num_vectors - 2] = tuple_mode; + aarch64_simd_tuple_types[type_index][num_vectors - 2] = t; } static bool @@ -1325,10 +1327,31 @@ aarch64_scalar_builtin_type_p (aarch64_simd_type t) return (t == Poly8_t || t == Poly16_t || t == Poly64_t || t == Poly128_t); } +/* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD + set. */ +aarch64_simd_switcher::aarch64_simd_switcher (unsigned int extra_flags) + : m_old_isa_flags (aarch64_isa_flags), + m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY) +{ + /* Changing the ISA flags should be enough here. We shouldn't need to + pay the compile-time cost of a full target switch. */ + aarch64_isa_flags = AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags; + global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; +} + +aarch64_simd_switcher::~aarch64_simd_switcher () +{ + if (m_old_general_regs_only) + global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY; + aarch64_isa_flags = m_old_isa_flags; +} + /* Implement #pragma GCC aarch64 "arm_neon.h". */ void handle_arm_neon_h (void) { + aarch64_simd_switcher simd; + /* Register the AdvSIMD vector tuple types. */ for (unsigned int i = 0; i < ARM_NEON_H_TYPES_LAST; i++) for (unsigned int count = 2; count <= 4; ++count) @@ -1703,8 +1726,10 @@ aarch64_general_init_builtins (void) aarch64_init_bf16_types (); - if (TARGET_SIMD) + { + aarch64_simd_switcher simd; aarch64_init_simd_builtins (); + } aarch64_init_crc32_builtins (); aarch64_init_builtin_rsqrt (); diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 46bade28ed6..c6f13ee836c 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -746,6 +746,19 @@ const unsigned int AARCH64_BUILTIN_SHIFT = 1; /* Mask that selects the aarch64_builtin_class part of a function code. */ const unsigned int AARCH64_BUILTIN_CLASS = (1 << AARCH64_BUILTIN_SHIFT) - 1; +/* RAII class for enabling enough features to define built-in types + and implement the arm_neon.h pragma. */ +class aarch64_simd_switcher +{ +public: + aarch64_simd_switcher (unsigned int extra_flags = 0); + ~aarch64_simd_switcher (); + +private: + unsigned long m_old_isa_flags; + bool m_old_general_regs_only; +}; + void aarch64_post_cfi_startproc (void); poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned); int aarch64_get_condition_code (rtx); diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 5d1348afa88..9d78b270e47 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -871,20 +871,14 @@ registered_function_hasher::equal (value_type value, const compare_type &key) } sve_switcher::sve_switcher () - : m_old_isa_flags (aarch64_isa_flags) + : aarch64_simd_switcher (AARCH64_FL_F16 | AARCH64_FL_SVE) { /* Changing the ISA flags and have_regs_of_mode should be enough here. We shouldn't need to pay the compile-time cost of a full target switch. */ - aarch64_isa_flags = (AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16 - | AARCH64_FL_SVE); - m_old_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = 0; - m_old_general_regs_only = TARGET_GENERAL_REGS_ONLY; - global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; - memcpy (m_old_have_regs_of_mode, have_regs_of_mode, sizeof (have_regs_of_mode)); for (int i = 0; i < NUM_MACHINE_MODES; ++i) @@ -896,9 +890,6 @@ sve_switcher::~sve_switcher () { memcpy (have_regs_of_mode, m_old_have_regs_of_mode, sizeof (have_regs_of_mode)); - if (m_old_general_regs_only) - global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY; - aarch64_isa_flags = m_old_isa_flags; maximum_field_alignment = m_old_maximum_field_alignment; } diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index 48cae9a97a4..24594d58497 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -651,16 +651,14 @@ public: /* RAII class for enabling enough SVE features to define the built-in types and implement the arm_sve.h pragma. */ -class sve_switcher +class sve_switcher : public aarch64_simd_switcher { public: sve_switcher (); ~sve_switcher (); private: - unsigned long m_old_isa_flags; unsigned int m_old_maximum_field_alignment; - bool m_old_general_regs_only; bool m_old_have_regs_of_mode[MAX_MACHINE_MODE]; }; diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-1.C b/gcc/testsuite/g++.target/aarch64/pr103147-1.C new file mode 100644 index 00000000000..4264c17f89a --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-1.C @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct" } */ + +#include + +static_assert(alignof(int32x2_t) == 8, "int32x2_t alignment"); +static_assert(alignof(int32x4_t) == 16, "int32x4_t alignment"); +static_assert(alignof(int32x2x2_t) == 1, "int32x2x2_t alignment"); +static_assert(alignof(int32x4x2_t) == 1, "int32x4x2_t alignment"); +static_assert(alignof(int32x2x3_t) == 1, "int32x2x3_t alignment"); +static_assert(alignof(int32x4x3_t) == 1, "int32x4x3_t alignment"); +static_assert(alignof(int32x2x4_t) == 1, "int32x2x4_t alignment"); +static_assert(alignof(int32x4x4_t) == 1, "int32x4x4_t alignment"); diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-10.C b/gcc/testsuite/g++.target/aarch64/pr103147-10.C new file mode 100644 index 00000000000..914fdf9c692 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-10.C @@ -0,0 +1,88 @@ +/* { dg-options "-O2 -fpack-struct -mstrict-align" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include + +extern "C" { + +/* +** ld2: +** ... +** ld2 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld2 (int32x4x2_t *a, int32_t *b) +{ + *a = vld2q_s32 (b); +} + +/* +** ld3: +** ... +** ld3 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld3 (int32x4x3_t *a, int32_t *b) +{ + *a = vld3q_s32 (b); +} + +/* +** ld4: +** ... +** ld4 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld4 (int32x4x4_t *a, int32_t *b) +{ + *a = vld4q_s32 (b); +} + +/* +** ret: +** ... +** ldp q0, q1, \[x0\] +** ldr q2, \[x0, #?32\] +** ... +*/ +int32x4x3_t +ret (int32x4_t *ptr) +{ + return (int32x4x3_t) { ptr[0], ptr[1], ptr[2] }; +} + +/* +** arg: +** ... +** stp d0, d1, \[x0\] +** ... +*/ +void +arg (int32x2x2_t arg, int32x2_t *ptr) +{ + ptr[0] = arg.val[0]; + ptr[1] = arg.val[1]; +} + +} diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-2.C b/gcc/testsuite/g++.target/aarch64/pr103147-2.C new file mode 100644 index 00000000000..565f2d237b3 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-2.C @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=1" } */ + +#include + +static_assert(alignof(int32x2_t) == 8, "int32x2_t alignment"); +static_assert(alignof(int32x4_t) == 16, "int32x4_t alignment"); +static_assert(alignof(int32x2x2_t) == 1, "int32x2x2_t alignment"); +static_assert(alignof(int32x4x2_t) == 1, "int32x4x2_t alignment"); +static_assert(alignof(int32x2x3_t) == 1, "int32x2x3_t alignment"); +static_assert(alignof(int32x4x3_t) == 1, "int32x4x3_t alignment"); +static_assert(alignof(int32x2x4_t) == 1, "int32x2x4_t alignment"); +static_assert(alignof(int32x4x4_t) == 1, "int32x4x4_t alignment"); diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-3.C b/gcc/testsuite/g++.target/aarch64/pr103147-3.C new file mode 100644 index 00000000000..579ca3770d8 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-3.C @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=2" } */ + +#include + +static_assert(alignof(int32x2_t) == 8, "int32x2_t alignment"); +static_assert(alignof(int32x4_t) == 16, "int32x4_t alignment"); +static_assert(alignof(int32x2x2_t) == 2, "int32x2x2_t alignment"); +static_assert(alignof(int32x4x2_t) == 2, "int32x4x2_t alignment"); +static_assert(alignof(int32x2x3_t) == 2, "int32x2x3_t alignment"); +static_assert(alignof(int32x4x3_t) == 2, "int32x4x3_t alignment"); +static_assert(alignof(int32x2x4_t) == 2, "int32x2x4_t alignment"); +static_assert(alignof(int32x4x4_t) == 2, "int32x4x4_t alignment"); diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-4.C b/gcc/testsuite/g++.target/aarch64/pr103147-4.C new file mode 100644 index 00000000000..752a47cd061 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-4.C @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=8" } */ + +#include + +static_assert(alignof(int32x2_t) == 8, "int32x2_t alignment"); +static_assert(alignof(int32x4_t) == 16, "int32x4_t alignment"); +static_assert(alignof(int32x2x2_t) == 8, "int32x2x2_t alignment"); +static_assert(alignof(int32x4x2_t) == 8, "int32x4x2_t alignment"); +static_assert(alignof(int32x2x3_t) == 8, "int32x2x3_t alignment"); +static_assert(alignof(int32x4x3_t) == 8, "int32x4x3_t alignment"); +static_assert(alignof(int32x2x4_t) == 8, "int32x2x4_t alignment"); +static_assert(alignof(int32x4x4_t) == 8, "int32x4x4_t alignment"); diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-5.C b/gcc/testsuite/g++.target/aarch64/pr103147-5.C new file mode 100644 index 00000000000..fbcdfd45e9e --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-5.C @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=16" } */ + +#include + +static_assert(alignof(int32x2_t) == 8, "int32x2_t alignment"); +static_assert(alignof(int32x4_t) == 16, "int32x4_t alignment"); +static_assert(alignof(int32x2x2_t) == 8, "int32x2x2_t alignment"); +static_assert(alignof(int32x4x2_t) == 16, "int32x4x2_t alignment"); +static_assert(alignof(int32x2x3_t) == 8, "int32x2x3_t alignment"); +static_assert(alignof(int32x4x3_t) == 16, "int32x4x3_t alignment"); +static_assert(alignof(int32x2x4_t) == 8, "int32x2x4_t alignment"); +static_assert(alignof(int32x4x4_t) == 16, "int32x4x4_t alignment"); diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-6.C b/gcc/testsuite/g++.target/aarch64/pr103147-6.C new file mode 100644 index 00000000000..15a606f976c --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-6.C @@ -0,0 +1,3 @@ +/* { dg-options "-mgeneral-regs-only" } */ + +#include diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-7.C b/gcc/testsuite/g++.target/aarch64/pr103147-7.C new file mode 100644 index 00000000000..40a7e4d6ffc --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-7.C @@ -0,0 +1,3 @@ +/* { dg-options "-fpack-struct" } */ + +#pragma GCC aarch64 "arm_neon.h" diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-8.C b/gcc/testsuite/g++.target/aarch64/pr103147-8.C new file mode 100644 index 00000000000..65459945c70 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-8.C @@ -0,0 +1,3 @@ +/* { dg-options "-mgeneral-regs-only" } */ + +#pragma GCC aarch64 "arm_neon.h" diff --git a/gcc/testsuite/g++.target/aarch64/pr103147-9.C b/gcc/testsuite/g++.target/aarch64/pr103147-9.C new file mode 100644 index 00000000000..2d60c7dda60 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/pr103147-9.C @@ -0,0 +1,10 @@ +/* { dg-options "-mgeneral-regs-only" } */ +/* { dg-excess-errors "arm_neon.h" } */ + +#include + +int32x4x4_t +test (int32_t *ptr) /* { dg-error "-mgeneral-regs-only" } */ +{ + return vld4q_s32 (ptr); +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-1.c b/gcc/testsuite/gcc.target/aarch64/pr103147-1.c new file mode 100644 index 00000000000..7b1f6414099 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-1.c @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct" } */ + +#include + +int assert1[__alignof__(int32x2_t) == 8 ? 1 : -1]; +int assert2[__alignof__(int32x4_t) == 16 ? 1 : -1]; +int assert3[__alignof__(int32x2x2_t) == 1 ? 1 : -1]; +int assert4[__alignof__(int32x4x2_t) == 1 ? 1 : -1]; +int assert5[__alignof__(int32x2x3_t) == 1 ? 1 : -1]; +int assert6[__alignof__(int32x4x3_t) == 1 ? 1 : -1]; +int assert7[__alignof__(int32x2x4_t) == 1 ? 1 : -1]; +int assert8[__alignof__(int32x4x4_t) == 1 ? 1 : -1]; diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-10.c b/gcc/testsuite/gcc.target/aarch64/pr103147-10.c new file mode 100644 index 00000000000..b2c34e4155d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-10.c @@ -0,0 +1,84 @@ +/* { dg-options "-O2 -fpack-struct -mstrict-align" } */ +/* { dg-final { check-function-bodies "**" "" "" } } */ + +#include + +/* +** ld2: +** ... +** ld2 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld2 (int32x4x2_t *a, int32_t *b) +{ + *a = vld2q_s32 (b); +} + +/* +** ld3: +** ... +** ld3 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld3 (int32x4x3_t *a, int32_t *b) +{ + *a = vld3q_s32 (b); +} + +/* +** ld4: +** ... +** ld4 .* +** ... +** ( +** strb .* +** | +** bl memcpy +** ) +** ... +*/ +void +ld4 (int32x4x4_t *a, int32_t *b) +{ + *a = vld4q_s32 (b); +} + +/* +** ret: +** ... +** ldp q0, q1, \[x0\] +** ldr q2, \[x0, #?32\] +** ... +*/ +int32x4x3_t +ret (int32x4_t *ptr) +{ + return (int32x4x3_t) { ptr[0], ptr[1], ptr[2] }; +} + +/* +** arg: +** ... +** stp d0, d1, \[x0\] +** ... +*/ +void +arg (int32x2x2_t arg, int32x2_t *ptr) +{ + ptr[0] = arg.val[0]; + ptr[1] = arg.val[1]; +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-2.c b/gcc/testsuite/gcc.target/aarch64/pr103147-2.c new file mode 100644 index 00000000000..a6775f3e399 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-2.c @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=1" } */ + +#include + +int assert1[__alignof__(int32x2_t) == 8 ? 1 : -1]; +int assert2[__alignof__(int32x4_t) == 16 ? 1 : -1]; +int assert3[__alignof__(int32x2x2_t) == 1 ? 1 : -1]; +int assert4[__alignof__(int32x4x2_t) == 1 ? 1 : -1]; +int assert5[__alignof__(int32x2x3_t) == 1 ? 1 : -1]; +int assert6[__alignof__(int32x4x3_t) == 1 ? 1 : -1]; +int assert7[__alignof__(int32x2x4_t) == 1 ? 1 : -1]; +int assert8[__alignof__(int32x4x4_t) == 1 ? 1 : -1]; diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-3.c b/gcc/testsuite/gcc.target/aarch64/pr103147-3.c new file mode 100644 index 00000000000..ff76e25dc55 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-3.c @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=2" } */ + +#include + +int assert1[__alignof__(int32x2_t) == 8 ? 1 : -1]; +int assert2[__alignof__(int32x4_t) == 16 ? 1 : -1]; +int assert3[__alignof__(int32x2x2_t) == 2 ? 1 : -1]; +int assert4[__alignof__(int32x4x2_t) == 2 ? 1 : -1]; +int assert5[__alignof__(int32x2x3_t) == 2 ? 1 : -1]; +int assert6[__alignof__(int32x4x3_t) == 2 ? 1 : -1]; +int assert7[__alignof__(int32x2x4_t) == 2 ? 1 : -1]; +int assert8[__alignof__(int32x4x4_t) == 2 ? 1 : -1]; diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-4.c b/gcc/testsuite/gcc.target/aarch64/pr103147-4.c new file mode 100644 index 00000000000..93331cf8c0a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-4.c @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=8" } */ + +#include + +int assert1[__alignof__(int32x2_t) == 8 ? 1 : -1]; +int assert2[__alignof__(int32x4_t) == 16 ? 1 : -1]; +int assert3[__alignof__(int32x2x2_t) == 8 ? 1 : -1]; +int assert4[__alignof__(int32x4x2_t) == 8 ? 1 : -1]; +int assert5[__alignof__(int32x2x3_t) == 8 ? 1 : -1]; +int assert6[__alignof__(int32x4x3_t) == 8 ? 1 : -1]; +int assert7[__alignof__(int32x2x4_t) == 8 ? 1 : -1]; +int assert8[__alignof__(int32x4x4_t) == 8 ? 1 : -1]; diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-5.c b/gcc/testsuite/gcc.target/aarch64/pr103147-5.c new file mode 100644 index 00000000000..a534bcb7c3f --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-5.c @@ -0,0 +1,12 @@ +/* { dg-options "-fpack-struct=16" } */ + +#include + +int assert1[__alignof__(int32x2_t) == 8 ? 1 : -1]; +int assert2[__alignof__(int32x4_t) == 16 ? 1 : -1]; +int assert3[__alignof__(int32x2x2_t) == 8 ? 1 : -1]; +int assert4[__alignof__(int32x4x2_t) == 16 ? 1 : -1]; +int assert5[__alignof__(int32x2x3_t) == 8 ? 1 : -1]; +int assert6[__alignof__(int32x4x3_t) == 16 ? 1 : -1]; +int assert7[__alignof__(int32x2x4_t) == 8 ? 1 : -1]; +int assert8[__alignof__(int32x4x4_t) == 16 ? 1 : -1]; diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-6.c b/gcc/testsuite/gcc.target/aarch64/pr103147-6.c new file mode 100644 index 00000000000..15a606f976c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-6.c @@ -0,0 +1,3 @@ +/* { dg-options "-mgeneral-regs-only" } */ + +#include diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-7.c b/gcc/testsuite/gcc.target/aarch64/pr103147-7.c new file mode 100644 index 00000000000..40a7e4d6ffc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-7.c @@ -0,0 +1,3 @@ +/* { dg-options "-fpack-struct" } */ + +#pragma GCC aarch64 "arm_neon.h" diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-8.c b/gcc/testsuite/gcc.target/aarch64/pr103147-8.c new file mode 100644 index 00000000000..65459945c70 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-8.c @@ -0,0 +1,3 @@ +/* { dg-options "-mgeneral-regs-only" } */ + +#pragma GCC aarch64 "arm_neon.h" diff --git a/gcc/testsuite/gcc.target/aarch64/pr103147-9.c b/gcc/testsuite/gcc.target/aarch64/pr103147-9.c new file mode 100644 index 00000000000..2d60c7dda60 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr103147-9.c @@ -0,0 +1,10 @@ +/* { dg-options "-mgeneral-regs-only" } */ +/* { dg-excess-errors "arm_neon.h" } */ + +#include + +int32x4x4_t +test (int32_t *ptr) /* { dg-error "-mgeneral-regs-only" } */ +{ + return vld4q_s32 (ptr); +}