From: Richard Biener Date: Wed, 14 Dec 2016 10:31:37 +0000 (+0000) Subject: re PR tree-optimization/78731 (Possible bug with switch when optimization is turned... X-Git-Tag: releases/gcc-5.5.0~639 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4f6d10b7071861a388809d35386e673c28feb45e;p=thirdparty%2Fgcc.git re PR tree-optimization/78731 (Possible bug with switch when optimization is turned on.) 2016-12-14 Richard Biener PR tree-optimization/78731 * tree-ssa-threadedge.c (simplify_control_stmt_condition): If we've seen a backedge to not walk the SSA value chain. (thread_around_empty_blocks): Pass down whether we've seen a backedge to simplify_control_stmt_condition. (thread_through_normal_block): Likewise. * gcc.dg/torture/pr78731.c: New testcase. From-SVN: r243641 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 157e40a6efc0..6df670715947 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-12-14 Richard Biener + + PR tree-optimization/78731 + * tree-ssa-threadedge.c (simplify_control_stmt_condition): + If we've seen a backedge to not walk the SSA value chain. + (thread_around_empty_blocks): Pass down whether we've seen + a backedge to simplify_control_stmt_condition. + (thread_through_normal_block): Likewise. + 2016-12-14 Thomas Preud'homme Backport from mainline diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd5f9ecfc979..78ed52518fa8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-14 Richard Biener + + PR tree-optimization/78731 + * gcc.dg/torture/pr78731.c: New testcase. + 2016-12-14 Thomas Preud'homme Backport from mainline diff --git a/gcc/testsuite/gcc.dg/torture/pr78731.c b/gcc/testsuite/gcc.dg/torture/pr78731.c new file mode 100644 index 000000000000..5a4d43be1f9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78731.c @@ -0,0 +1,41 @@ +/* { dg-do run } */ + +#include +#include + +#define GENERAL 1 +#define BRACKETS 2 +#define QUOTES 3 + +void __attribute__((noinline,noclone)) +foo(char *qb, char* into) +{ + int state = QUOTES; + int save_state = BRACKETS; + + while (qb) + { + switch (state) + { + case BRACKETS: + exit(0); + case GENERAL: + abort (); + case QUOTES: + state = save_state; + save_state = GENERAL; + break; + default: ; + } + printf("State %d btw GENERAL %d\n", state, GENERAL); + } + abort (); +} + +int main() +{ + char *b = "123"; + char out[4]; + foo(b, out); + return 0; +} diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index 90c1e2af94ac..97e087569aa6 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -574,7 +574,8 @@ simplify_control_stmt_condition (edge e, gimple stmt, gcond *dummy_cond, tree (*simplify) (gimple, gimple), - bool handle_dominating_asserts) + bool handle_dominating_asserts, + bool backedge_seen) { tree cond, cached_lhs; enum gimple_code code = gimple_code (stmt); @@ -593,7 +594,7 @@ simplify_control_stmt_condition (edge e, /* Get the current value of both operands. */ if (TREE_CODE (op0) == SSA_NAME) { - for (int i = 0; i < 2; i++) + for (int i = 0; i < (backedge_seen ? 1 : 2); i++) { if (TREE_CODE (op0) == SSA_NAME && SSA_NAME_VALUE (op0)) @@ -605,7 +606,7 @@ simplify_control_stmt_condition (edge e, if (TREE_CODE (op1) == SSA_NAME) { - for (int i = 0; i < 2; i++) + for (int i = 0; i < (backedge_seen ? 1 : 2); i++) { if (TREE_CODE (op1) == SSA_NAME && SSA_NAME_VALUE (op1)) @@ -689,7 +690,7 @@ simplify_control_stmt_condition (edge e, a loop invariant SSA_NAME used in the condition. */ if (cached_lhs) { - for (int i = 0; i < 2; i++) + for (int i = 0; i < (backedge_seen ? 1 : 2); i++) { if (TREE_CODE (cached_lhs) == SSA_NAME && SSA_NAME_VALUE (cached_lhs)) @@ -940,7 +941,8 @@ thread_around_empty_blocks (edge taken_edge, /* Extract and simplify the condition. */ cond = simplify_control_stmt_condition (taken_edge, stmt, dummy_cond, - simplify, handle_dominating_asserts); + simplify, handle_dominating_asserts, + *backedge_seen_p); /* If the condition can be statically computed and we have not already visited the destination edge, then add the taken edge to our thread @@ -1326,7 +1328,8 @@ thread_through_normal_block (edge e, /* Extract and simplify the condition. */ cond = simplify_control_stmt_condition (e, stmt, dummy_cond, simplify, - handle_dominating_asserts); + handle_dominating_asserts, + *backedge_seen_p); if (!cond) return 0;