Also provide the vec_extract patterns for floats on pre-z13 machines to prevent ICEing in those cases.
Bootstrapped and regtested on s390. 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