mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 12:00:11 -05:00
tree-optimization/121382 - avoid UB in IVOPTs inserted step computation
IVOPTs, when replacing an IV, inserts the computation of the new IVs step in the loop preheader without considering the case of the loop not iterating. This means we have to ensure the step computation does not invoke UB. There is also SCEV which does not care about signed arithmetic UB when re-associating expressions to form CHRECs, so even when we know the loop iterates this is required. PR tree-optimization/121382 * tree-ssa-loop-ivopts.cc (create_new_iv): Rewrite the IV step to defined form. * gcc.dg/torture/pr121382.c: New testcase.
This commit is contained in:
committed by
Richard Biener
parent
afafae0972
commit
5d55cd95e2
23
gcc/testsuite/gcc.dg/torture/pr121382.c
Normal file
23
gcc/testsuite/gcc.dg/torture/pr121382.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* { 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user