This backport contains 1 patch from gcc main stream tree. The commit id of these patchs list as following in the order of time. 0001-re-PR-tree-optimization-92512-ICE-in-gimple_op-at-gi.patch b9f71c51cd578c6ab6ad2986edb80ba48aa477bc diff -Nurp a/gcc/testsuite/gcc.dg/torture/pr92512.c b/gcc/testsuite/gcc.dg/torture/pr92512.c --- a/gcc/testsuite/gcc.dg/torture/pr92512.c 1970-01-01 08:00:00.000000000 +0800 +++ b/gcc/testsuite/gcc.dg/torture/pr92512.c 2020-08-10 20:53:50.404000000 +0800 @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize" } */ + +long int +nl (long int fy, int k3, int zr) +{ + while (k3 < 1) + { + if (zr == 0) + fy = 0; + + fy *= fy < zr; + ++k3; + } + + return fy; +} diff -Nurp a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c --- a/gcc/tree-vect-loop.c 2020-08-10 20:53:42.636000000 +0800 +++ b/gcc/tree-vect-loop.c 2020-08-10 20:53:50.404000000 +0800 @@ -2931,9 +2931,11 @@ pop: /* The following make sure we can compute the operand index easily plus it mostly disallows chaining via COND_EXPR condition operands. */ - || (gimple_assign_rhs1 (use_stmt) != op - && gimple_assign_rhs2 (use_stmt) != op - && gimple_assign_rhs3 (use_stmt) != op)) + || (gimple_assign_rhs1_ptr (use_stmt) != path[i].second->use + && (gimple_num_ops (use_stmt) <= 2 + || gimple_assign_rhs2_ptr (use_stmt) != path[i].second->use) + && (gimple_num_ops (use_stmt) <= 3 + || gimple_assign_rhs3_ptr (use_stmt) != path[i].second->use))) { fail = true; break; @@ -2946,7 +2948,18 @@ pop: FOR_EACH_IMM_USE_STMT (op_use_stmt, imm_iter, op) if (!is_gimple_debug (op_use_stmt) && flow_bb_inside_loop_p (loop, gimple_bb (op_use_stmt))) - cnt++; + { + /* We want to allow x + x but not x < 1 ? x : 2. */ + if (is_gimple_assign (op_use_stmt) + && gimple_assign_rhs_code (op_use_stmt) == COND_EXPR) + { + use_operand_p use_p; + FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) + cnt++; + } + else + cnt++; + } if (cnt != 1) { fail = true;