diff options
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.cc')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.cc | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index 879668c..2fe2655 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -132,6 +132,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-vectorizer.h" #include "dbgcnt.h" #include "cfganal.h" +#include "gimple-fold.h" /* For lang_hooks.types.type_for_mode. */ #include "langhooks.h" @@ -7252,7 +7253,24 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand) base = unshare_expr (cand->iv->base); - create_iv (base, PLUS_EXPR, unshare_expr (cand->iv->step), + /* The step computation could invoke UB when the loop does not iterate. + Avoid inserting it on the preheader in its native form but rewrite + it to a well-defined form. This also helps masking SCEV issues + which freely re-associates the IV computations when building up + CHRECs without much regard for signed overflow invoking UB. */ + gimple_seq stmts = NULL; + tree step = force_gimple_operand (unshare_expr (cand->iv->step), &stmts, + true, NULL_TREE); + if (stmts) + { + for (auto gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi)) + if (gimple_needing_rewrite_undefined (gsi_stmt (gsi))) + rewrite_to_defined_unconditional (&gsi); + gsi_insert_seq_on_edge_immediate + (loop_preheader_edge (data->current_loop), stmts); + } + + create_iv (base, PLUS_EXPR, step, cand->var_before, data->current_loop, &incr_pos, after, &cand->var_before, &cand->var_after); } |