--- /dev/null
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int a, b, c;
+__attribute__((noipa))
+static void d(int e, int f)
+{
+ if (e != 5 && e != 2147483647)
+ __builtin_abort();
+ f = 2147483647;
+ do {
+ f = f - e;
+ if (c - 9 * f) {
+ __builtin_abort();
+ }
+ } while (c);
+}
+__attribute__((noipa))
+int main(void)
+{
+ d(2147483647, 2147483647);
+ return 0;
+}
#include "tree-vectorizer.h"
#include "dbgcnt.h"
#include "cfganal.h"
+#include "gimple-fold.h"
/* For lang_hooks.types.type_for_mode. */
#include "langhooks.h"
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);
}