]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s390: Fix float vector extract for pre-z13
authorJuergen Christ <jchrist@linux.ibm.com>
Wed, 18 Jun 2025 13:16:28 +0000 (15:16 +0200)
committerJuergen Christ <jchrist@linux.ibm.com>
Tue, 24 Jun 2025 11:34:22 +0000 (13:34 +0200)
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>
gcc/config/s390/vector.md
gcc/testsuite/gcc.target/s390/vector/vec-extract-1.c
gcc/testsuite/gcc.target/s390/vector/vec-extract-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/vector/vec-set-1.c

index 6f4e1929eb80cdb0deefb57b65efdf44e4f819eb..7251a76c3aeaf581d8ae86ee799d55ce7b2b67ad 100644 (file)
@@ -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
 (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
index 9df7909a3ea83a44b914df6d1c08b9c6e7e42dcb..83af839963be4dee72712a24b8b667724519e405 100644 (file)
@@ -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 (file)
index 0000000..640ac0c
--- /dev/null
@@ -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];
+}
index 021a5b9a0b7be428abe5153c6a4a7ac1eacbc166..c03963e63af1a9429ffe94317596bfdae6117eb4 100644 (file)
@@ -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;
 }