diff mbox series

AArch64: Add more accurate constraint [PR117292]

Message ID PAWPR08MB898207A7D248847B2B2188D5834F2@PAWPR08MB8982.eurprd08.prod.outlook.com
State New
Headers show
Series AArch64: Add more accurate constraint [PR117292] | expand

Commit Message

Wilco Dijkstra Oct. 25, 2024, 3:53 p.m. UTC
As shown in the PR, reload may only check the constraint in some cases and
and not check the predicate is still valid for the resulting instruction.
To fix the issue, add a new constraint which matches the predicate exactly.

Passes regress & bootstrap, OK for commit?

gcc/ChangeLog:
        PR target/117292
        * config/aarch64/aarch64-simd.md (xor<mode>3<vczle><vczbe>): Use 'De' constraint.
        * config/aarch64/constraints.md (De): Add new constraint.

gcc/testsuite/ChangeLog:
        PR target/117292
        * testsuite/gcc.target/aarch64/sve/single_5.c: Remove xfails.
        * testsuite/gcc.target/aarch64/pr117292.c: New test.

---

Comments

Richard Sandiford Oct. 25, 2024, 4:22 p.m. UTC | #1
Wilco Dijkstra <Wilco.Dijkstra@arm.com> writes:
> As shown in the PR, reload may only check the constraint in some cases and
> and not check the predicate is still valid for the resulting instruction.

Yeah, that's by design.  constraints have to accept a subset of the
predicates.

> To fix the issue, add a new constraint which matches the predicate exactly.
>
> Passes regress & bootstrap, OK for commit?
>
> gcc/ChangeLog:
>         PR target/117292
>         * config/aarch64/aarch64-simd.md (xor<mode>3<vczle><vczbe>): Use 'De' constraint.
>         * config/aarch64/constraints.md (De): Add new constraint.
>
> gcc/testsuite/ChangeLog:
>         PR target/117292
>         * testsuite/gcc.target/aarch64/sve/single_5.c: Remove xfails.
>         * testsuite/gcc.target/aarch64/pr117292.c: New test.

OK, thanks.

Richard

> ---
>
> diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
> index eabfd5f324fce3bd5b8f676ab9c13827b00baa30..c61195f55cca3bbe5b3b34d9c4364fdc7830e6ea 100644
> --- a/gcc/config/aarch64/aarch64-simd.md
> +++ b/gcc/config/aarch64/aarch64-simd.md
> @@ -1151,7 +1151,7 @@ (define_insn "xor<mode>3<vczle><vczbe>"
>    "TARGET_SIMD"
>    {@ [ cons: =0 , 1 , 2  ]
>       [ w        , w , w  ] eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
> -     [ w        , 0 , Do ] << aarch64_output_simd_xor_imm (operands[2], <bitsize>);
> +     [ w        , 0 , De ] << aarch64_output_simd_xor_imm (operands[2], <bitsize>);
>    }
>    [(set_attr "type" "neon_logic<q>")]
>  )
> diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
> index 3f9fd92a1911e0b18a163dc6c4c2c97c871458e0..647941c3c5a37d8411f931cf00440c0240c91c0a 100644
> --- a/gcc/config/aarch64/constraints.md
> +++ b/gcc/config/aarch64/constraints.md
> @@ -472,6 +472,12 @@ (define_constraint "Db"
>   (and (match_code "const_vector")
>        (match_test "aarch64_simd_valid_and_imm (op)")))
>
> +(define_constraint "De"
> +  "@internal
> +   A constraint that matches vector of immediates for xor."
> + (and (match_code "const_vector")
> +      (match_test "aarch64_simd_valid_xor_imm (op)")))
> +
>  (define_constraint "Dn"
>    "@internal
>   A constraint that matches vector of immediates."
> diff --git a/gcc/testsuite/gcc.target/aarch64/pr117292.c b/gcc/testsuite/gcc.target/aarch64/pr117292.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..86816266c681a099c46d2246469edc600a1352e3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/pr117292.c
> @@ -0,0 +1,41 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Os" } */
> +
> +#pragma GCC target "+nosve"
> +
> +typedef char v8u8;
> +typedef __attribute__((__vector_size__ (2))) char v16u8;
> +typedef __attribute__((__vector_size__ (4))) char v32u8;
> +typedef __attribute__((__vector_size__ (8))) char v64u8;
> +typedef short v128u8;
> +typedef __attribute__((__vector_size__ (32))) char v256u8;
> +typedef __attribute__((__vector_size__ (64))) char v512u8;
> +v16u8 foo0_v16s16_0;
> +__attribute__((__vector_size__ (16))) int foo0_v512u32_0;
> +v8u8 foo0_ret;
> +
> +static __attribute__((__noinline__)) __attribute__((__noclone__)) void
> +foo0 (signed char s8_0, v512u8 v512u16_0, v512u8 v512s16_0,
> +            v512u8 v512s32_0, v512u8 v512u64_0, v512u8 v512s64_0,
> +            v512u8 v512u128_0, v512u8 v512s128_0)
> +{
> +  char v8s8_0;
> +  v8s8_0 ^= s8_0;
> +  foo0_v512u32_0 /= foo0_v512u32_0 ^ s8_0;
> +  v512u8 v512u8_r = v512u16_0 + v512s16_0 + v512s32_0 +
> +    v512u64_0 + v512s64_0 + v512u128_0 + v512s128_0;
> +  v16u8 v16u8_r = ((union { v64u8 a; v16u8 b;})
> +                 ((union { v128u8 a; v64u8 b;})
> +                 ((union { v256u8 a; v128u8 b;})
> +                 ((union { v512u8 a; v256u8 b;})  v512u8_r).b).b).b).b +
> +    foo0_v16s16_0;
> +  v8u8 v8u8_r = ((union { v16u8 a; v8u8 b;}) v16u8_r).b + v8s8_0;
> +  foo0_ret = v8u8_r;
> +}
> +
> +void
> +main ()
> +{
> +  foo0 (3, (v512u8){}, (v512u8){}, (v512u8){}, (v512u8){},
> +        (v512u8){}, (v512u8){}, (v512u8){});
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_5.c b/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
> index 233118bbb383bbdf2d342d057ead024f92804221..ac81194733f07eff5d2e9d2309c29e815a52deea 100644
> --- a/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
> @@ -11,8 +11,8 @@
>  /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.8h, 0x4\n} 1 } } */
>  /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.4s, 0x5\n} 1 } } */
>  /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.4s, 0x6\n} 1 } } */
> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 { xfail *-*-* } } } */
> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 { xfail *-*-* } } } */
> +/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
> +/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
>  /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.8h, 1\.0e\+0\n} 1 } } */
>  /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.4s, 2\.0e\+0\n} 1 } } */
>  /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.2d, 3\.0e\+0\n} 1 } } */
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index eabfd5f324fce3bd5b8f676ab9c13827b00baa30..c61195f55cca3bbe5b3b34d9c4364fdc7830e6ea 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1151,7 +1151,7 @@  (define_insn "xor<mode>3<vczle><vczbe>"
   "TARGET_SIMD"
   {@ [ cons: =0 , 1 , 2  ]
      [ w        , w , w  ] eor\t%0.<Vbtype>, %1.<Vbtype>, %2.<Vbtype>
-     [ w        , 0 , Do ] << aarch64_output_simd_xor_imm (operands[2], <bitsize>);
+     [ w        , 0 , De ] << aarch64_output_simd_xor_imm (operands[2], <bitsize>);
   }
   [(set_attr "type" "neon_logic<q>")]
 )
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 3f9fd92a1911e0b18a163dc6c4c2c97c871458e0..647941c3c5a37d8411f931cf00440c0240c91c0a 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -472,6 +472,12 @@  (define_constraint "Db"
  (and (match_code "const_vector")
       (match_test "aarch64_simd_valid_and_imm (op)")))
 
+(define_constraint "De"
+  "@internal
+   A constraint that matches vector of immediates for xor."
+ (and (match_code "const_vector")
+      (match_test "aarch64_simd_valid_xor_imm (op)")))
+
 (define_constraint "Dn"
   "@internal
  A constraint that matches vector of immediates."
diff --git a/gcc/testsuite/gcc.target/aarch64/pr117292.c b/gcc/testsuite/gcc.target/aarch64/pr117292.c
new file mode 100644
index 0000000000000000000000000000000000000000..86816266c681a099c46d2246469edc600a1352e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr117292.c
@@ -0,0 +1,41 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+#pragma GCC target "+nosve"
+
+typedef char v8u8;
+typedef __attribute__((__vector_size__ (2))) char v16u8;
+typedef __attribute__((__vector_size__ (4))) char v32u8;
+typedef __attribute__((__vector_size__ (8))) char v64u8;
+typedef short v128u8;
+typedef __attribute__((__vector_size__ (32))) char v256u8;
+typedef __attribute__((__vector_size__ (64))) char v512u8;
+v16u8 foo0_v16s16_0;
+__attribute__((__vector_size__ (16))) int foo0_v512u32_0;
+v8u8 foo0_ret;
+
+static __attribute__((__noinline__)) __attribute__((__noclone__)) void
+foo0 (signed char s8_0, v512u8 v512u16_0, v512u8 v512s16_0,
+	     v512u8 v512s32_0, v512u8 v512u64_0, v512u8 v512s64_0,
+	     v512u8 v512u128_0, v512u8 v512s128_0)
+{
+  char v8s8_0;
+  v8s8_0 ^= s8_0;
+  foo0_v512u32_0 /= foo0_v512u32_0 ^ s8_0;
+  v512u8 v512u8_r = v512u16_0 + v512s16_0 + v512s32_0 +
+    v512u64_0 + v512s64_0 + v512u128_0 + v512s128_0;
+  v16u8 v16u8_r = ((union { v64u8 a; v16u8 b;})
+		  ((union { v128u8 a; v64u8 b;})
+		  ((union { v256u8 a; v128u8 b;})
+		  ((union { v512u8 a; v256u8 b;})  v512u8_r).b).b).b).b +
+    foo0_v16s16_0;
+  v8u8 v8u8_r = ((union { v16u8 a; v8u8 b;}) v16u8_r).b + v8s8_0;
+  foo0_ret = v8u8_r;
+}
+
+void
+main ()
+{
+  foo0 (3, (v512u8){}, (v512u8){}, (v512u8){}, (v512u8){},
+        (v512u8){}, (v512u8){}, (v512u8){});
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_5.c b/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
index 233118bbb383bbdf2d342d057ead024f92804221..ac81194733f07eff5d2e9d2309c29e815a52deea 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/single_5.c
@@ -11,8 +11,8 @@ 
 /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.8h, 0x4\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.4s, 0x5\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmovi\tv[0-9]+\.4s, 0x6\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 { xfail *-*-* } } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.8h, 1\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.4s, 2\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tv[0-9]+\.2d, 3\.0e\+0\n} 1 } } */