[gcc r16-1651] s390: Fix float vector extract for pre-z13
Juergen Christ
jchrist@gcc.gnu.org
Tue Jun 24 11:35:51 GMT 2025
https://gcc.gnu.org/g:bd9cac12373aecaa0ebee808f805c617f2c15375
commit r16-1651-gbd9cac12373aecaa0ebee808f805c617f2c15375
Author: Juergen Christ <jchrist@linux.ibm.com>
Date: Wed Jun 18 15:16:28 2025 +0200
s390: Fix float vector extract for pre-z13
Also provide the vec_extract patterns for floats on pre-z13 machines
to prevent ICEing in those cases.
gcc/ChangeLog:
* config/s390/vector.md (VF): Don't restrict modes.
(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 <jchrist@linux.ibm.com>
Diff:
---
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/testsuite/gcc.target/s390/vector/vec-set-1.c | 23 ++-
4 files changed, 187 insertions(+), 24 deletions(-)
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..c03963e63af1 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;
}
More information about the Gcc-cvs
mailing list