aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-08-11 13:00:17 +0200
committerRichard Biener <rguenther@suse.de>2023-08-11 15:03:31 +0200
commit798a880a0b1fed8a9e3b3e026dd8bd09314b7c38 (patch)
tree8c8d7d66c52c6d3ff3dfd39f05ab1dac9eb22cc1
parent3a13884b23ae32b43d56d68a9c6bd4ce53d60017 (diff)
downloadgcc-798a880a0b1fed8a9e3b3e026dd8bd09314b7c38.zip
gcc-798a880a0b1fed8a9e3b3e026dd8bd09314b7c38.tar.gz
gcc-798a880a0b1fed8a9e3b3e026dd8bd09314b7c38.tar.bz2
tree-optimization/110979 - fold-left reduction and partial vectors
When we vectorize fold-left reductions with partial vectors but no target operation available we use a vector conditional to force excess elements to zero. But that doesn't correctly preserve the sign of zero. The following patch disables partial vector support when we have to do that and also need to honor rounding modes other than round-to-nearest. When round-to-nearest is in effect and we have to preserve the sign of zero instead use negative zero for the excess elements. PR tree-optimization/110979 * tree-vect-loop.cc (vectorizable_reduction): For FOLD_LEFT_REDUCTION without target support make sure we don't need to honor signed zeros and sign dependent rounding. * gcc.dg/torture/pr110979.c: New testcase.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110979.c25
-rw-r--r--gcc/tree-vect-loop.cc24
2 files changed, 48 insertions, 1 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr110979.c b/gcc/testsuite/gcc.dg/torture/pr110979.c
new file mode 100644
index 0000000..c25ad7a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr110979.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+/* { dg-additional-options "--param vect-partial-vector-usage=2" } */
+
+#define FLT double
+#define N 20
+
+__attribute__((noipa))
+FLT
+foo3 (FLT *a)
+{
+ FLT sum = -0.0;
+ for (int i = 0; i != N; i++)
+ sum += a[i];
+ return sum;
+}
+
+int main()
+{
+ FLT a[N];
+ for (int i = 0; i != N; i++)
+ a[i] = -0.0;
+ if (!__builtin_signbit(foo3(a)))
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/tree-vect-loop.cc b/gcc/tree-vect-loop.cc
index bf8d677..bc3063c 100644
--- a/gcc/tree-vect-loop.cc
+++ b/gcc/tree-vect-loop.cc
@@ -6905,7 +6905,17 @@ vectorize_fold_left_reduction (loop_vec_info loop_vinfo,
tree vector_identity = NULL_TREE;
if (LOOP_VINFO_FULLY_MASKED_P (loop_vinfo))
- vector_identity = build_zero_cst (vectype_out);
+ {
+ vector_identity = build_zero_cst (vectype_out);
+ if (!HONOR_SIGNED_ZEROS (vectype_out))
+ ;
+ else
+ {
+ gcc_assert (!HONOR_SIGN_DEPENDENT_ROUNDING (vectype_out));
+ vector_identity = const_unop (NEGATE_EXPR, vectype_out,
+ vector_identity);
+ }
+ }
tree scalar_dest_var = vect_create_destination_var (scalar_dest, NULL);
int i;
@@ -8037,6 +8047,18 @@ vectorizable_reduction (loop_vec_info loop_vinfo,
" no conditional operation is available.\n");
LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false;
}
+ else if (reduction_type == FOLD_LEFT_REDUCTION
+ && reduc_fn == IFN_LAST
+ && FLOAT_TYPE_P (vectype_in)
+ && HONOR_SIGNED_ZEROS (vectype_in)
+ && HONOR_SIGN_DEPENDENT_ROUNDING (vectype_in))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "can't operate on partial vectors because"
+ " signed zeros cannot be preserved.\n");
+ LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo) = false;
+ }
else
{
internal_fn mask_reduc_fn