On Fri, Jun 20, 2025 at 08:23:01PM +0200, Juergen Christ wrote:
> Also provide the vec_extract patterns for floats on pre-z13 machines
> to prevent ICEing in those cases.
> 
> Bootstrapped and regtested on s390.

Ok.

Thanks,
Stefan

> 
> gcc/ChangeLog:
> 
>       * config/s390/vector.md (VF): Don't restrict modes.
>       * config/s390/vector.md (VEC_SET_SINGLEFLOAT): Ditto.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.target/s390/vector/vec-extract-1.c: Fix test on arch11.
>       * gcc.target/s390/vector/vec-set-1.c: Run test on arch11.
>       * gcc.target/s390/vector/vec-extract-2.c: New test.
> 
> Signed-off-by: Juergen Christ <jchr...@linux.ibm.com>
> ---
>  gcc/config/s390/vector.md                     |   4 +-
>  .../gcc.target/s390/vector/vec-extract-1.c    |  16 +-
>  .../gcc.target/s390/vector/vec-extract-2.c    | 168 ++++++++++++++++++
>  .../gcc.target/s390/vector/vec-set-1.c        |  23 ++-
>  4 files changed, 187 insertions(+), 24 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c
> 
> diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
> index 6f4e1929eb80..7251a76c3aea 100644
> --- a/gcc/config/s390/vector.md
> +++ b/gcc/config/s390/vector.md
> @@ -75,7 +75,7 @@
>                          V1DF V2DF
>                          (V1TF "TARGET_VXE") (TF "TARGET_VXE")])
>  
> -(define_mode_iterator VF [(V2SF "TARGET_VXE") (V4SF "TARGET_VXE") V2DF])
> +(define_mode_iterator VF [V2SF V4SF V2DF])
>  
>  ; All modes present in V_HW1 and VFT.
>  (define_mode_iterator V_HW1_FT [V16QI V8HI V4SI V2DI V1TI V1DF
> @@ -512,7 +512,7 @@
>  (define_mode_iterator VEC_SET_NONFLOAT
>    [V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI 
> V2SF V4SF])
>  ; Iterator for single element float vectors
> -(define_mode_iterator VEC_SET_SINGLEFLOAT [(V1SF "TARGET_VXE") V1DF (V1TF 
> "TARGET_VXE")])
> +(define_mode_iterator VEC_SET_SINGLEFLOAT [V1SF V1DF (V1TF "TARGET_VXE")])
>  
>  ; FIXME: Support also vector mode operands for 1
>  ; FIXME: A target memory operand seems to be useful otherwise we end
> diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c 
> b/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c
> index 9df7909a3ea8..83af839963be 100644
> --- a/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c
> +++ b/gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -march=z14 -mzarch" } */
> +/* { dg-options "-O2 -march=arch11 -mzarch" } */
>  /* { dg-final { check-function-bodies "**" "" } } */
>  
>  typedef double V2DF __attribute__((vector_size(16)));
> @@ -110,17 +110,6 @@ extractnthfloat (V4SF x, int n)
>    return x[n];
>  }
>  
> -/*
> -** sumfirstfloat:
> -**   vfasb   %v0,%v24,%v26
> -**   br      %r14
> -*/
> -float
> -sumfirstfloat (V4SF x, V4SF y)
> -{
> -  return (x + y)[0];
> -}
> -
>  /*
>  ** extractfirst2:
>  **   vlr     %v0,%v24
> @@ -179,8 +168,7 @@ extractsingled (V1DF x)
>  
>  /*
>  ** extractsingleld:
> -**   vlr     (%v.),%v24
> -**   vst     \1,0\(%r2\),3
> +**   vst     %v24,0\(%r2\),3
>  **   br      %r14
>  */
>  long double
> diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c 
> b/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c
> new file mode 100644
> index 000000000000..640ac0c8c766
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c
> @@ -0,0 +1,168 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -march=arch11 -mzarch" } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +typedef double V2DF __attribute__((vector_size(16)));
> +typedef float V4SF __attribute__((vector_size(16)));
> +typedef float V2SF __attribute__((vector_size(8)));
> +typedef double V1DF __attribute__((vector_size(8)));
> +typedef float V1SF __attribute__((vector_size(4)));
> +typedef long double V1TF __attribute__((vector_size(16)));
> +
> +/*
> +** extractfirstdouble:
> +**   vsteg   %v24,0\(%r2\),0
> +**   br      %r14
> +*/
> +void
> +extractfirstdouble (double *res, V2DF x)
> +{
> +  *res = x[0];
> +}
> +
> +/*
> +** extractseconddouble:
> +**   vsteg   %v24,0\(%r2\),1
> +**   br      %r14
> +*/
> +void
> +extractseconddouble (double *res, V2DF x)
> +{
> +  *res = x[1];
> +}
> +
> +/*
> +** extractnthdouble:
> +**   vlgvg   (%r.),%v24,0\(%r3\)
> +**   stg     \1,0\(%r2\)
> +**   br      %r14
> +*/
> +void
> +extractnthdouble (double *res, V2DF x, int n)
> +{
> +  *res = x[n];
> +}
> +
> +/*
> +** extractfirstfloat:
> +**   vstef   %v24,0\(%r2\),0
> +**   br      %r14
> +*/
> +void
> +extractfirstfloat (float *res, V4SF x)
> +{
> +  *res = x[0];
> +}
> +
> +/*
> +** extractsecondfloat:
> +**   vstef   %v24,0\(%r2\),1
> +**   br      %r14
> +*/
> +void
> +extractsecondfloat (float *res, V4SF x)
> +{
> +  *res = x[1];
> +}
> +
> +/*
> +** extractthirdfloat:
> +**   vstef   %v24,0\(%r2\),2
> +**   br      %r14
> +*/
> +void
> +extractthirdfloat (float *res, V4SF x)
> +{
> +  *res = x[2];
> +}
> +
> +/*
> +** extractfourthfloat:
> +**   vstef   %v24,0\(%r2\),3
> +**   br      %r14
> +*/
> +void
> +extractfourthfloat (float *res, V4SF x)
> +{
> +  *res = x[3];
> +}
> +
> +/*
> +** extractnthfloat:
> +**   vlgvf   (%r.),%v24,0\(%r3\)
> +**   st      \1,0\(%r2\)
> +**   br      %r14
> +*/
> +void
> +extractnthfloat (float *res, V4SF x, int n)
> +{
> +  *res = x[n];
> +}
> +
> +/*
> +** extractfirst2:
> +**   vstef   %v24,0\(%r2\),0
> +**   br      %r14
> +*/
> +void
> +extractfirst2 (float *res, V2SF x)
> +{
> +  *res = x[0];
> +}
> +
> +/*
> +** extractsecond2:
> +**   vstef   %v24,0\(%r2\),1
> +**   br      %r14
> +*/
> +void
> +extractsecond2 (float *res, V2SF x)
> +{
> +  *res = x[1];
> +}
> +
> +/*
> +** extractnth2:
> +**   vlgvf   (%r.),%v24,0\(%r3\)
> +**   st      \1,0\(%r2\)
> +**   br      %r14
> +*/
> +void
> +extractnth2 (float *res, V2SF x, int n)
> +{
> +  *res = x[n];
> +}
> +
> +/*
> +** extractsinglef:
> +**   vlr     %v(.),%v24
> +**   ste     %f\1,0\(%r2\)
> +**   br      %r14
> +*/
> +void
> +extractsinglef (float *res, V1SF x)
> +{
> +  *res = x[0];
> +}
> +
> +/*
> +** extractsingled:
> +**   vsteg   %v24,0\(%r2\),0
> +**   br      %r14
> +*/
> +void
> +extractsingled (double *res, V1DF x)
> +{
> +  *res = x[0];
> +}
> +
> +/*
> +** extractsingleld:
> +**   vst     %v24,0\(%r2\),3
> +**   br      %r14
> +*/
> +void
> +extractsingleld (long double *res, V1TF x)
> +{
> +  *res = x[0];
> +}
> diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c 
> b/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c
> index 021a5b9a0b7b..fd706160142d 100644
> --- a/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c
> +++ b/gcc/testsuite/gcc.target/s390/vector/vec-set-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -march=z14 -mzarch" } */
> +/* { dg-options "-O2 -march=arch11 -mzarch" } */
>  /* { dg-final { check-function-bodies "**" "" } } */
>  
>  typedef double V2DF __attribute__((vector_size(16)));
> @@ -69,7 +69,7 @@ set1dfn (V1DF x, double y, int n)
>  
>  /*
>  ** setsf0:
> -**   lgdr    (%r.),%f0
> +**   vlgvf   (%r.),%v0,0
>  **   vlvgf   %v24,\1,0
>  **   br      %r14
>  */
> @@ -82,7 +82,7 @@ setsf0 (V4SF x, float y)
>  
>  /*
>  ** setsf1:
> -**   lgdr    (%r.),%f0
> +**   vlgvf   (%r.),%v0,0
>  **   vlvgf   %v24,\1,1
>  **   br      %r14
>  */
> @@ -94,8 +94,8 @@ setsf1 (V4SF x, float y)
>  }
>  
>  /*
> -** setsf0:
> -**   lgdr    (%r.),%f0
> +** setsf2:
> +**   vlgvf   (%r.),%v0,0
>  **   vlvgf   %v24,\1,2
>  **   br      %r14
>  */
> @@ -107,8 +107,8 @@ setsf2 (V4SF x, float y)
>  }
>  
>  /*
> -** setsf1:
> -**   lgdr    (%r.),%f0
> +** setsf3:
> +**   vlgvf   (%r.),%v0,0
>  **   vlvgf   %v24,\1,3
>  **   br      %r14
>  */
> @@ -121,7 +121,7 @@ setsf3 (V4SF x, float y)
>  
>  /*
>  ** setsfn:
> -**   lgdr    (%r.),%f0
> +**   vlgvf   (%r.),%v0,0
>  **   vlvgf   %v24,\1,0\(%r2\)
>  **   br      %r14
>  */
> @@ -129,5 +129,12 @@ V4SF
>  setsfn (V4SF x, float y, int n)
>  {
>    x[n] = y;
> +  /* Make sure to read all FPRs such that the "save GPRs in FPRs" 
> optimization
> +     cannot be used.  That optimization has a memory clobber on SP restore
> +     causing DSE to fail to eliminate dead stores in leaf functions using 
> this
> +     optimization.  */
> +  asm volatile ("" : : "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y),
> +                    "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y),
> +                    "f" (y), "f" (y), "f" (y), "f" (y));
>    return x;
>  }
> -- 
> 2.43.5
> 

Reply via email to