Skip to content
Snippets Groups Projects
Commit 594264e9 authored by Tamar Christina's avatar Tamar Christina
Browse files

AArch64: Fix vector re-interpretation between partial SIMD modes

While writing a patch series I started getting incorrect codegen out from
VEC_PERM on partial struct types.

It turns out that this was happening because the TARGET_CAN_CHANGE_MODE_CLASS
implementation has a slight bug in it.  The hook only checked for SIMD to
Partial but never Partial to SIMD.   This resulted in incorrect subregs to be
generated from the fallback code in VEC_PERM_EXPR expansions.

I have unfortunately not been able to trigger it using a standalone testcase as
the mid-end optimizes away the permute every time I try to describe a permute
that would result in the bug.

The patch now rejects any conversion of partial SIMD struct types, unless they
are both partial structures of the same number of registers or one is a SIMD
type who's size is less than 8 bytes.

gcc/ChangeLog:

	* config/aarch64/aarch64.cc (aarch64_can_change_mode_class): Restrict
	conversions between partial struct types properly.
parent 17ae956c
No related branches found
No related tags found
No related merge requests found
...@@ -26731,9 +26731,10 @@ aarch64_can_change_mode_class (machine_mode from, ...@@ -26731,9 +26731,10 @@ aarch64_can_change_mode_class (machine_mode from,
bool from_pred_p = (from_flags & VEC_SVE_PRED); bool from_pred_p = (from_flags & VEC_SVE_PRED);
bool to_pred_p = (to_flags & VEC_SVE_PRED); bool to_pred_p = (to_flags & VEC_SVE_PRED);
   
bool from_full_advsimd_struct_p = (from_flags == (VEC_ADVSIMD | VEC_STRUCT));
bool to_partial_advsimd_struct_p = (to_flags == (VEC_ADVSIMD | VEC_STRUCT bool to_partial_advsimd_struct_p = (to_flags == (VEC_ADVSIMD | VEC_STRUCT
| VEC_PARTIAL)); | VEC_PARTIAL));
bool from_partial_advsimd_struct_p = (from_flags == (VEC_ADVSIMD | VEC_STRUCT
| VEC_PARTIAL));
   
/* Don't allow changes between predicate modes and other modes. /* Don't allow changes between predicate modes and other modes.
Only predicate registers can hold predicate modes and only Only predicate registers can hold predicate modes and only
...@@ -26755,9 +26756,10 @@ aarch64_can_change_mode_class (machine_mode from, ...@@ -26755,9 +26756,10 @@ aarch64_can_change_mode_class (machine_mode from,
|| GET_MODE_UNIT_SIZE (from) != GET_MODE_UNIT_SIZE (to))) || GET_MODE_UNIT_SIZE (from) != GET_MODE_UNIT_SIZE (to)))
return false; return false;
   
/* Don't allow changes between partial and full Advanced SIMD structure /* Don't allow changes between partial and other registers only if
modes. */ one is a normal SIMD register, allow only if not larger than 64-bit. */
if (from_full_advsimd_struct_p && to_partial_advsimd_struct_p) if ((to_partial_advsimd_struct_p ^ from_partial_advsimd_struct_p)
&& (known_gt (GET_MODE_SIZE (to), 8) || known_gt (GET_MODE_SIZE (to), 8)))
return false; return false;
   
if (maybe_ne (BITS_PER_SVE_VECTOR, 128u)) if (maybe_ne (BITS_PER_SVE_VECTOR, 128u))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment