diff mbox series

i386: Fix up ix86_expand_int_compare with TImode comparisons of SUBREGs from V8{H,B}Fmode against zero [PR116921]

Message ID Zv+/jvkppSl9eCX6@tucnak
State New
Headers show
Series i386: Fix up ix86_expand_int_compare with TImode comparisons of SUBREGs from V8{H,B}Fmode against zero [PR116921] | expand

Commit Message

Jakub Jelinek Oct. 4, 2024, 10:12 a.m. UTC
Hi!

The following testcase ICEs, because the ix86_expand_int_compare
optimization to use {,v}ptest assumes there are instructions for all
16-byte vector modes.  That isn't the case, we only have one for
V16QI, V8HI, V4SI, V2DI, V1TI, V4SF and V2DF, not for
V8HF nor V8BF.

The following patch fixes that by using the V8HI instruction instead
for those 2 modes.  tmp can't be a SUBREG, because it is SUBREG_REG
of another SUBREG, so we don't need to worry about gen_lowpart
failing.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-10-04  Jakub Jelinek  <jakub@redhat.com>

	PR target/116921
	* config/i386/i386-expand.cc (ix86_expand_int_compare): Add a SUBREG
	to V8HImode from V8HFmode or V8BFmode before generating a ptest.

	* gcc.target/i386/pr116921.c: New test.


	Jakub

Comments

Uros Bizjak Oct. 4, 2024, 10:49 a.m. UTC | #1
On Fri, Oct 4, 2024 at 12:12 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> The following testcase ICEs, because the ix86_expand_int_compare
> optimization to use {,v}ptest assumes there are instructions for all
> 16-byte vector modes.  That isn't the case, we only have one for
> V16QI, V8HI, V4SI, V2DI, V1TI, V4SF and V2DF, not for
> V8HF nor V8BF.
>
> The following patch fixes that by using the V8HI instruction instead
> for those 2 modes.  tmp can't be a SUBREG, because it is SUBREG_REG
> of another SUBREG, so we don't need to worry about gen_lowpart
> failing.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2024-10-04  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/116921
>         * config/i386/i386-expand.cc (ix86_expand_int_compare): Add a SUBREG
>         to V8HImode from V8HFmode or V8BFmode before generating a ptest.
>
>         * gcc.target/i386/pr116921.c: New test.

OK.

Thanks,
Uros.
>
> --- gcc/config/i386/i386-expand.cc.jj   2024-10-03 17:27:28.328227793 +0200
> +++ gcc/config/i386/i386-expand.cc      2024-10-03 18:11:18.514076904 +0200
> @@ -3095,6 +3095,9 @@ ix86_expand_int_compare (enum rtx_code c
>        && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))) == 16)
>      {
>        tmp = SUBREG_REG (op0);
> +      if (GET_MODE_INNER (GET_MODE (tmp)) == HFmode
> +         || GET_MODE_INNER (GET_MODE (tmp)) == BFmode)
> +       tmp = gen_lowpart (V8HImode, tmp);
>        tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec (2, tmp, tmp), UNSPEC_PTEST);
>      }
>    else
> --- gcc/testsuite/gcc.target/i386/pr116921.c.jj 2024-10-03 18:16:36.368711747 +0200
> +++ gcc/testsuite/gcc.target/i386/pr116921.c    2024-10-03 18:17:25.702034243 +0200
> @@ -0,0 +1,12 @@
> +/* PR target/116921 */
> +/* { dg-do compile { target int128 } } */
> +/* { dg-options "-O2 -msse4" } */
> +
> +long x;
> +_Float16 __attribute__((__vector_size__ (16))) f;
> +
> +void
> +foo (void)
> +{
> +  x -= !(__int128) (f / 2);
> +}
>
>         Jakub
>
diff mbox series

Patch

--- gcc/config/i386/i386-expand.cc.jj	2024-10-03 17:27:28.328227793 +0200
+++ gcc/config/i386/i386-expand.cc	2024-10-03 18:11:18.514076904 +0200
@@ -3095,6 +3095,9 @@  ix86_expand_int_compare (enum rtx_code c
       && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))) == 16)
     {
       tmp = SUBREG_REG (op0);
+      if (GET_MODE_INNER (GET_MODE (tmp)) == HFmode
+	  || GET_MODE_INNER (GET_MODE (tmp)) == BFmode)
+	tmp = gen_lowpart (V8HImode, tmp);
       tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec (2, tmp, tmp), UNSPEC_PTEST);
     }
   else
--- gcc/testsuite/gcc.target/i386/pr116921.c.jj	2024-10-03 18:16:36.368711747 +0200
+++ gcc/testsuite/gcc.target/i386/pr116921.c	2024-10-03 18:17:25.702034243 +0200
@@ -0,0 +1,12 @@ 
+/* PR target/116921 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -msse4" } */
+
+long x;
+_Float16 __attribute__((__vector_size__ (16))) f;
+
+void
+foo (void)
+{
+  x -= !(__int128) (f / 2);
+}