Hi! bswap_view_convert is used twice in spots where gsi_insert_before is the right thing, but in the last one it wants to insert preparation stmts for the VIEW_CONVERT_EXPR emitted with gsi_insert_after, where at the gsi we still need to insert bswap_stmt and maybe mask_stmt whose lhs the preparation stmts will use. So, this patch adds a BEFORE argument to the function and emits the preparation statements before or after depending on that.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-09-01 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/102141 * gimple-ssa-store-merging.c (bswap_view_convert): Add BEFORE argument. If false, emit stmts after gsi instead of before, and with GSI_NEW_STMT. (bswap_replace): Adjust callers. When converting output of bswap, emit VIEW_CONVERT prepratation stmts after a copy of gsi instead of before it. * gcc.dg/pr102141.c: New test. --- gcc/gimple-ssa-store-merging.c.jj 2021-08-23 11:54:03.319505682 +0200 +++ gcc/gimple-ssa-store-merging.c 2021-08-31 12:26:08.347127224 +0200 @@ -1020,7 +1020,8 @@ public: first. */ static tree -bswap_view_convert (gimple_stmt_iterator *gsi, tree type, tree val) +bswap_view_convert (gimple_stmt_iterator *gsi, tree type, tree val, + bool before) { gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (val)) || POINTER_TYPE_P (TREE_TYPE (val))); @@ -1032,12 +1033,18 @@ bswap_view_convert (gimple_stmt_iterator gimple *g = gimple_build_assign (make_ssa_name (pointer_sized_int_node), NOP_EXPR, val); - gsi_insert_before (gsi, g, GSI_SAME_STMT); + if (before) + gsi_insert_before (gsi, g, GSI_SAME_STMT); + else + gsi_insert_after (gsi, g, GSI_NEW_STMT); val = gimple_assign_lhs (g); } tree itype = build_nonstandard_integer_type (prec, 1); gimple *g = gimple_build_assign (make_ssa_name (itype), NOP_EXPR, val); - gsi_insert_before (gsi, g, GSI_SAME_STMT); + if (before) + gsi_insert_before (gsi, g, GSI_SAME_STMT); + else + gsi_insert_after (gsi, g, GSI_NEW_STMT); val = gimple_assign_lhs (g); } return build1 (VIEW_CONVERT_EXPR, type, val); @@ -1165,7 +1172,8 @@ bswap_replace (gimple_stmt_iterator gsi, gimple_set_vuse (load_stmt, n->vuse); gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT); if (conv_code == VIEW_CONVERT_EXPR) - val_tmp = bswap_view_convert (&gsi, TREE_TYPE (tgt), val_tmp); + val_tmp = bswap_view_convert (&gsi, TREE_TYPE (tgt), val_tmp, + true); gimple_assign_set_rhs_with_ops (&gsi, conv_code, val_tmp); update_stmt (cur_stmt); } @@ -1209,7 +1217,7 @@ bswap_replace (gimple_stmt_iterator gsi, if (!is_gimple_val (src)) return NULL_TREE; if (conv_code == VIEW_CONVERT_EXPR) - src = bswap_view_convert (&gsi, TREE_TYPE (tgt), src); + src = bswap_view_convert (&gsi, TREE_TYPE (tgt), src, true); g = gimple_build_assign (tgt, conv_code, src); } else if (cur_stmt) @@ -1296,14 +1304,13 @@ bswap_replace (gimple_stmt_iterator gsi, /* Convert the result if necessary. */ if (!useless_type_conversion_p (TREE_TYPE (tgt), bswap_type)) { - gimple *convert_stmt; - tmp = make_temp_ssa_name (bswap_type, NULL, "bswapdst"); tree atmp = tmp; + gimple_stmt_iterator gsi2 = gsi; if (conv_code == VIEW_CONVERT_EXPR) - atmp = bswap_view_convert (&gsi, TREE_TYPE (tgt), tmp); - convert_stmt = gimple_build_assign (tgt, conv_code, atmp); - gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT); + atmp = bswap_view_convert (&gsi2, TREE_TYPE (tgt), tmp, false); + gimple *convert_stmt = gimple_build_assign (tgt, conv_code, atmp); + gsi_insert_after (&gsi2, convert_stmt, GSI_SAME_STMT); } gimple_set_lhs (mask_stmt ? mask_stmt : bswap_stmt, tmp); --- gcc/testsuite/gcc.dg/pr102141.c.jj 2021-08-31 12:38:22.271783023 +0200 +++ gcc/testsuite/gcc.dg/pr102141.c 2021-08-31 12:38:01.805071490 +0200 @@ -0,0 +1,11 @@ +/* PR tree-optimization/102141 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +unsigned int __attribute__((__vector_size__ (4))) v; + +void +foo (unsigned long long x) +{ + v &= (unsigned) (x >> 56 | x >> 40 & 0xff00); +} Jakub