From b9ec5ebb605936684e95b8dcc12e43ba7d8f2cb4 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 11 Jun 2021 13:36:26 +0200 Subject: [PATCH] tree-optimization/101028 - fix endless SLP reassoc discovery This fixes a missing clearing of mismatched lanes from the fatal fail path in SLP reassoc discovery in the most conservative way. 2021-06-11 Richard Biener PR tree-optimization/101028 * tree-vect-slp.c (vect_build_slp_tree_2): When SLP reassoc discovery fails fatally, mark appropriate lanes in matches[] so. * gcc.dg/pr101028.c: New testcase. --- gcc/testsuite/gcc.dg/pr101028.c | 34 ++++++++++++++++++++++++++++++++++ gcc/tree-vect-slp.c | 26 +++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr101028.c diff --git a/gcc/testsuite/gcc.dg/pr101028.c b/gcc/testsuite/gcc.dg/pr101028.c new file mode 100644 index 0000000..501e6af --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr101028.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +typedef struct { + double x, y; +} PointInfo; + +typedef struct { + PointInfo point; +} PrimitiveInfo; + +int TraceBezier_alpha, TraceBezier_i; +double TraceBezier_weight; +PointInfo *TraceBezier_points; +PrimitiveInfo *TraceBezier_primitive_info; + +void TracePath() { + double *coefficients; + PointInfo point; + long j; + for (; TraceBezier_i; TraceBezier_i++) { + point.x = point.y = TraceBezier_alpha = 1.0; + j = 0; + for (; j < 4; j++) { + point.x += TraceBezier_alpha * coefficients[j] * + TraceBezier_primitive_info->point.x; + point.y += TraceBezier_alpha * TraceBezier_primitive_info->point.y; + TraceBezier_alpha *= TraceBezier_weight; + TraceBezier_primitive_info++; + } + TraceBezier_points[TraceBezier_i] = point; + TraceBezier_weight += 1.0; + } +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 897bd6f..9ded585 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1849,14 +1849,28 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, mismatch still hard-FAIL. */ if (chain_len == 0) hard_fail = false; + else + { + matches[lane] = false; + /* ??? We might want to process the other lanes, but + make sure to not give false matching hints to the + caller for lanes we did not process. */ + if (lane != group_size - 1) + matches[0] = false; + } break; } else if (chain_len == 0) chain_len = chain.length (); else if (chain.length () != chain_len) - /* ??? Here we could slip in magic to compensate with - neutral operands. */ - break; + { + /* ??? Here we could slip in magic to compensate with + neutral operands. */ + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; + break; + } chains.quick_push (chain.copy ()); chain.truncate (0); } @@ -1905,6 +1919,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, dump_printf_loc (MSG_NOTE, vect_location, "giving up on chain due to mismatched " "def types\n"); + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; goto out; } if (dt == vect_constant_def @@ -1983,6 +2000,9 @@ vect_build_slp_tree_2 (vec_info *vinfo, slp_tree node, dump_printf_loc (MSG_NOTE, vect_location, "failed to match up op %d\n", n); op_stmts.release (); + matches[lane] = false; + if (lane != group_size - 1) + matches[0] = false; goto out; } if (dump_enabled_p ()) -- 2.7.4