Skip to content
Snippets Groups Projects
Commit 2066c29b authored by Richard Biener's avatar Richard Biener
Browse files

tree-optimization/111233 - loop splitting miscompile

The change in r14-2852-gf5fb9ff2396fd4 failed to update patch_loop_exit
to compensate for rewriting of a NE/EQ_EXPR to a new code.  Fixed
with the following.

	PR tree-optimization/111233
	PR tree-optimization/111652
	PR tree-optimization/111727
	PR tree-optimization/111838
	PR tree-optimization/112113
	* tree-ssa-loop-split.cc (patch_loop_exit): Get the new
	guard code instead of the old guard stmt.
	(split_loop): Adjust.

	* gcc.dg/torture/pr111233.c: New testcase.
	* gcc.dg/torture/pr111652.c: Likewise.
	* gcc.dg/torture/pr111727.c: Likewise.
	* gcc.dg/torture/pr111838.c: Likewise.
	* gcc.dg/torture/pr112113.c: Likewise.
parent bc390ae7
No related branches found
No related tags found
No related merge requests found
/* { dg-do run } */
/* { dg-additional-options "-fsplit-loops" } */
int a, c, f;
char b, g;
int *d = &c;
long e;
int main()
{
for (; e != 25; e++) {
f = -17;
for (; f <= 0; f = f + 7) {
g = f ? 0 : b;
a = *d;
}
}
if (a != 0)
__builtin_abort ();
}
/* { dg-do run } */
/* { dg-additional-options "-fsplit-loops" } */
volatile int a;
int b;
int main() {
for (; b < 5; b += 3) {
b && a;
if (b < 4)
a--;
}
if (b != 6)
__builtin_abort();
return 0;
}
/* { dg-do run } */
/* { dg-additional-options "-fsplit-loops" } */
int a, b;
int main()
{
for (; a < 4; a += 2)
if (a > 2)
while (b++);
;
if (a != 4)
__builtin_abort();
return 0;
}
/* { dg-do run } */
/* { dg-additional-options "-fsplit-loops" } */
int a, b, c;
volatile char d;
int main()
{
for (; b < 1; b++)
for (char e = -17; e < 1; e += 5)
{
if (e ? a % e : 0)
d;
for (c = 0; c < 1; c++)
;
}
return 0;
}
/* { dg-do run } */
/* The -Waggressive-loop-optimizations diagnostic is spurious, missed
constant propagation after final value replacement. */
/* { dg-additional-options "-Wno-aggressive-loop-optimizations -fsplit-loops" } */
volatile int a;
int main()
{
for (int b = 0; b < 33; b += 3) {
if (b > 31)
a++;
}
if (a != 0)
__builtin_abort();
return 0;
}
......@@ -194,13 +194,12 @@ split_at_bb_p (class loop *loop, basic_block bb, tree *border, affine_iv *iv,
also be true/false in the next iteration. */
static void
patch_loop_exit (class loop *loop, gcond *guard, tree nextval, tree newbound,
bool initial_true)
patch_loop_exit (class loop *loop, tree_code guard_code, tree nextval,
tree newbound, bool initial_true)
{
edge exit = single_exit (loop);
gcond *stmt = as_a <gcond *> (*gsi_last_bb (exit->src));
gimple_cond_set_condition (stmt, gimple_cond_code (guard),
nextval, newbound);
gimple_cond_set_condition (stmt, guard_code, nextval, newbound);
update_stmt (stmt);
edge stay = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit);
......@@ -745,7 +744,7 @@ split_loop (class loop *loop1)
gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop1),
stmts);
tree guard_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop1));
patch_loop_exit (loop1, guard_stmt, guard_next, newend, initial_true);
patch_loop_exit (loop1, guard_code, guard_next, newend, initial_true);
/* Finally patch out the two copies of the condition to be always
true/false (or opposite). */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment