From 6b520e8d4a24036508ad59eadf725437d2717a84 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 16 Dec 2016 14:19:44 +0000 Subject: [PATCH] re PR tree-optimization/78819 (Wrong code with VRP caused by register assertions along default switch labels) PR tree-optimization/78819 * tree-vrp.c (find_switch_asserts): Return if the insertion limit is 0. Don't register an assertion if the default case shares a label with another case. * gcc.dg/tree-ssa/vrp112.c: New test. From-SVN: r243746 --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/tree-ssa/vrp112.c | 31 ++++++++++++++++++++++++++ gcc/tree-vrp.c | 9 ++++++++ 4 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp112.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bdbadd348b7..2a443d0a499 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-12-16 Marek Polacek + + PR tree-optimization/78819 + * tree-vrp.c (find_switch_asserts): Return if the insertion limit is 0. + Don't register an assertion if the default case shares a label with + another case. + 2016-12-16 Wilco Dijkstra * config/arm/arm.md (subsi3_carryin): Add Thumb-2 RSC #0. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index afd90ee71d1..3307b2efce9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-16 Marek Polacek + + PR tree-optimization/78819 + * gcc.dg/tree-ssa/vrp112.c: New test. + 2016-12-16 Eric Botcazou * gnat.dg/opt61.adb: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp112.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp112.c new file mode 100644 index 00000000000..fdc6711bae4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp112.c @@ -0,0 +1,31 @@ +/* PR tree-optimization/78819 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +__attribute__((noinline, noclone)) void +foo (int argc) +{ + if (argc <= 0 || argc > 3) + return; + + switch (argc) + { + case 1: + case 3: + if (argc != 3) + __builtin_abort (); + break; + case 2: + asm (""); + break; + default: + __builtin_abort (); + } +} + +int +main (void) +{ + foo (3); + return 0; +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 97e9953a139..31b6b7de35d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -6051,10 +6051,17 @@ find_switch_asserts (basic_block bb, gswitch *last) /* Now register along the default label assertions that correspond to the anti-range of each label. */ int insertion_limit = PARAM_VALUE (PARAM_MAX_VRP_SWITCH_ASSERTIONS); + if (insertion_limit == 0) + return; + + /* We can't do this if the default case shares a label with another case. */ + tree default_cl = gimple_switch_default_label (last); for (idx = 1; idx < n; idx++) { tree min, max; tree cl = gimple_switch_label (last, idx); + if (CASE_LABEL (cl) == CASE_LABEL (default_cl)) + continue; min = CASE_LOW (cl); max = CASE_HIGH (cl); @@ -6065,6 +6072,8 @@ find_switch_asserts (basic_block bb, gswitch *last) { tree next_min, next_max; tree next_cl = gimple_switch_label (last, idx); + if (CASE_LABEL (next_cl) == CASE_LABEL (default_cl)) + break; next_min = CASE_LOW (next_cl); next_max = CASE_HIGH (next_cl); -- 2.30.2