diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-05-03 09:49:43 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-05-03 09:49:43 +0200 |
commit | 18bfe94032eef1649444d9d204c516dc12901ace (patch) | |
tree | 677559067befe1b2fabb60fceaf581474fa32f64 /gcc/testsuite | |
parent | 53e62089fbe61bbf59dd1b14d006a619de7b5f87 (diff) | |
download | gcc-18bfe94032eef1649444d9d204c516dc12901ace.zip gcc-18bfe94032eef1649444d9d204c516dc12901ace.tar.gz gcc-18bfe94032eef1649444d9d204c516dc12901ace.tar.bz2 |
re PR tree-optimization/79472 (x86-64: Switch table generation fails if default case has different code)
PR tree-optimization/79472
* tree-switch-conversion.c (struct switch_conv_info): Add
contiguous_range and default_case_nonstandard fields.
(collect_switch_conv_info): Compute contiguous_range and
default_case_nonstandard fields, don't clear final_bb if
contiguous_range and only the default case doesn't have the required
structure.
(check_all_empty_except_final): Set default_case_nonstandard instead
of failing if contiguous_range and the default case doesn't have empty
block.
(check_final_bb): Add SWTCH argument, don't fail if contiguous_range
and only the default case doesn't have the required constants. Skip
virtual phis.
(gather_default_values): Skip virtual phis. Allow non-NULL CASE_LOW
if default_case_nonstandard.
(build_constructors): Build constant 1 just once. Assert that default
values aren't inserted in between cases if contiguous_range. Skip
virtual phis.
(build_arrays): Skip virtual phis.
(prune_bbs): Add DEFAULT_BB argument, don't remove that bb.
(fix_phi_nodes): Don't add e2f phi arg if default_case_nonstandard.
Handle virtual phis.
(gen_inbound_check): Handle default_case_nonstandard case.
(process_switch): Adjust check_final_bb caller. Call
gather_default_values with the first non-default case instead of
default case if default_case_nonstandard.
* gcc.dg/tree-ssa/vrp40.c: Add -fno-tree-switch-conversion to dg-options.
* gcc.dg/tree-ssa/vrp113.c: New test.
* gcc.dg/tree-ssa/cswtch-3.c: New test.
* gcc.dg/tree-ssa/cswtch-4.c: New test.
* gcc.dg/tree-ssa/cswtch-5.c: New test.
From-SVN: r247538
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cswtch-3.c | 330 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cswtch-4.c | 57 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cswtch-5.c | 66 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp113.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp40.c | 2 |
6 files changed, 480 insertions, 1 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e84e045..3f6190bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2017-05-03 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/79472 + * gcc.dg/tree-ssa/vrp40.c: Add -fno-tree-switch-conversion to dg-options. + * gcc.dg/tree-ssa/vrp113.c: New test. + * gcc.dg/tree-ssa/cswtch-3.c: New test. + * gcc.dg/tree-ssa/cswtch-4.c: New test. + * gcc.dg/tree-ssa/cswtch-5.c: New test. + 2017-05-03 Tom de Vries <tom@codesourcery.com> PR testsuite/80557 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cswtch-3.c b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-3.c new file mode 100644 index 0000000..b983c8f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-3.c @@ -0,0 +1,330 @@ +/* PR tree-optimization/79472 */ +/* { dg-options "-O2 -fdump-tree-switchconv" } */ +/* { dg-do run } */ + +int *expected; + +void +foo (int x, int y) +{ + if (x != expected[0] || y != expected[1]) + __builtin_abort (); + expected += 2; +} + +__attribute__((noinline, noclone)) void +f1 (int v, int w) +{ + int i, j; + if (w) + { + i = 129; + j = i - 1; + goto lab; + } + switch (v) + { + case 170: + j = 7; + i = 27; + break; + case 171: + i = 8; + j = 122; + break; + case 172: + i = 21; + j = -19; + break; + case 173: + i = 18; + j = 17; + break; + case 174: + i = 139; + j = -5; + break; + case 175: + i = 14; + j = -26; + break; + case 176: + j = 5; + i = -14; + break; + case 177: + j = 8; + i = 12; + break; + default: + __builtin_abort (); + } + + lab: + foo (i, j); +} + +__attribute__((noinline, noclone)) void +f2 (int v) +{ + int i, j; + switch (v) + { + case 170: + j = 7; + i = 27; + break; + case 171: + i = 8; + j = 122; + break; + case 172: + i = 21; + j = -19; + break; + case 173: + i = 18; + j = 17; + break; + case 174: + i = 139; + j = -5; + break; + case 175: + i = 14; + j = -26; + break; + case 176: + j = 5; + i = -14; + break; + case 177: + j = 8; + i = 12; + break; + default: + foo (5, 12); + foo (17, 19); + i = 8; + j = 19; + break; + } + + foo (i, j); +} + +__attribute__((noinline, noclone)) void +f3 (int v) +{ + int i; + switch (v) + { + default: + i = v; + goto lab; + case 170: + i = 27; + break; + case 171: + i = 8; + break; + case 172: + i = 21; + break; + case 173: + i = 18; + break; + case 174: + i = 139; + break; + case 175: + i = 14; + break; + case 176: + i = -14; + break; + case 177: + i = 12; + break; + } + + lab: + foo (i, -5); +} + +__attribute__((noinline, noclone)) void +f4 (int v, int w) +{ + int i, j, k = 5; + if (w) + { + foo (0, 0); + k = 26; + goto do_default; + } + switch (v) + { + case 170: + j = 7; + i = 27; + break; + case 171: + i = 8; + j = 122; + break; + case 172: + i = 21; + j = -19; + break; + case 173: + i = 18; + j = 17; + break; + case 174: + i = 139; + j = -5; + break; + case 175: + i = 14; + j = -26; + break; + case 176: + j = 5; + i = -14; + break; + case 177: + j = 8; + i = 12; + break; + default: + do_default: + foo (5, 12); + foo (17, 19); + i = 8; + j = 19; + break; + } + + foo (i, j + k); +} + +void +f5 (int v, int w) +{ + int i; + if (w) + { + foo (23, 0); + i = 129; + } + else + switch (v) + { + case 170: + i = 27; + break; + case 171: + i = 8; + break; + case 172: + i = 21; + break; + case 173: + i = 18; + break; + case 174: + i = 139; + break; + case 175: + i = 14; + break; + case 176: + i = -14; + break; + case 177: + i = 12; + break; + default: + i = 80; + break; + } + + lab: + foo (i, 0); +} + +int +main () +{ + int *e; +#define T(call, cnt, ...) \ + expected = e = (int []) __VA_ARGS__; \ + call; \ + if (expected != e + cnt) \ + __builtin_abort () + T (f1 (171, 1), 2, { 129, 128 }); + T (f1 (140, 1), 2, { 129, 128 }); + T (f1 (170, 0), 2, { 27, 7 }); + T (f1 (171, 0), 2, { 8, 122 }); + T (f1 (172, 0), 2, { 21, -19 }); + T (f1 (173, 0), 2, { 18, 17 }); + T (f1 (174, 0), 2, { 139, -5 }); + T (f1 (175, 0), 2, { 14, -26 }); + T (f1 (176, 0), 2, { -14, 5 }); + T (f1 (177, 0), 2, { 12, 8 }); + T (f2 (-31), 6, { 5, 12, 17, 19, 8, 19 }); + T (f2 (169), 6, { 5, 12, 17, 19, 8, 19 }); + T (f2 (170), 2, { 27, 7 }); + T (f2 (171), 2, { 8, 122 }); + T (f2 (172), 2, { 21, -19 }); + T (f2 (173), 2, { 18, 17 }); + T (f2 (174), 2, { 139, -5 }); + T (f2 (175), 2, { 14, -26 }); + T (f2 (176), 2, { -14, 5 }); + T (f2 (177), 2, { 12, 8 }); + T (f2 (178), 6, { 5, 12, 17, 19, 8, 19 }); + T (f2 (231), 6, { 5, 12, 17, 19, 8, 19 }); + T (f3 (-31), 2, { -31, -5 }); + T (f3 (169), 2, { 169, -5 }); + T (f3 (170), 2, { 27, -5 }); + T (f3 (171), 2, { 8, -5 }); + T (f3 (172), 2, { 21, -5 }); + T (f3 (173), 2, { 18, -5 }); + T (f3 (174), 2, { 139, -5 }); + T (f3 (175), 2, { 14, -5 }); + T (f3 (176), 2, { -14, -5 }); + T (f3 (177), 2, { 12, -5 }); + T (f3 (178), 2, { 178, -5 }); + T (f3 (231), 2, { 231, -5 }); + T (f4 (171, 1), 8, { 0, 0, 5, 12, 17, 19, 8, 45 }); + T (f4 (140, 1), 8, { 0, 0, 5, 12, 17, 19, 8, 45 }); + T (f4 (-31, 0), 6, { 5, 12, 17, 19, 8, 24 }); + T (f4 (169, 0), 6, { 5, 12, 17, 19, 8, 24 }); + T (f4 (170, 0), 2, { 27, 12 }); + T (f4 (171, 0), 2, { 8, 127 }); + T (f4 (172, 0), 2, { 21, -14 }); + T (f4 (173, 0), 2, { 18, 22 }); + T (f4 (174, 0), 2, { 139, 0 }); + T (f4 (175, 0), 2, { 14, -21 }); + T (f4 (176, 0), 2, { -14, 10 }); + T (f4 (177, 0), 2, { 12, 13 }); + T (f4 (178, 0), 6, { 5, 12, 17, 19, 8, 24 }); + T (f4 (231, 0), 6, { 5, 12, 17, 19, 8, 24 }); + T (f5 (171, 1), 4, { 23, 0, 129, 0 }); + T (f5 (140, 1), 4, { 23, 0, 129, 0 }); + T (f5 (-31, 0), 2, { 80, 0 }); + T (f5 (169, 0), 2, { 80, 0 }); + T (f5 (170, 0), 2, { 27, 0 }); + T (f5 (171, 0), 2, { 8, 0 }); + T (f5 (172, 0), 2, { 21, 0 }); + T (f5 (173, 0), 2, { 18, 0 }); + T (f5 (174, 0), 2, { 139, 0 }); + T (f5 (175, 0), 2, { 14, 0 }); + T (f5 (176, 0), 2, { -14, 0 }); + T (f5 (177, 0), 2, { 12, 0 }); + T (f5 (178, 0), 2, { 80, 0 }); + T (f5 (231, 0), 2, { 80, 0 }); +} + +/* { dg-final { scan-tree-dump-times "Switch converted" 5 "switchconv" } } */ +/* { dg-final { scan-tree-dump-times "= CSWTCH" 8 "switchconv" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cswtch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-4.c new file mode 100644 index 0000000..962690d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-4.c @@ -0,0 +1,57 @@ +/* PR tree-optimization/79472 */ +/* { dg-options "-O2 -fdump-tree-switchconv" } */ +/* { dg-do compile } */ + +void +frobulate (unsigned int v) +{ + const char *s; + + switch (v) + { + case 0: + s = "foo"; + break; + case 1: + s = "bar"; + break; + case 2: + s = "spam"; + break; + default: + __builtin_abort (); + break; + } + + __builtin_printf ("%s\n", s); +} + +void +frobulate_for_gcc (unsigned int v) +{ + const char *s; + + switch (v) + { + case 0: + s = "foo"; + break; + case 1: + s = "bar"; + break; + case 2: + s = "spam"; + break; + default: + s = (const char *) 0; + break; + } + + if (!s) + __builtin_abort (); + + __builtin_printf ("%s\n", s); +} + +/* { dg-final { scan-tree-dump-times "Switch converted" 2 "switchconv" } } */ +/* { dg-final { scan-tree-dump-times "= CSWTCH" 2 "switchconv" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cswtch-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-5.c new file mode 100644 index 0000000..96a86bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cswtch-5.c @@ -0,0 +1,66 @@ +/* PR tree-optimization/79472 */ +/* { dg-options "-O2 -fdump-tree-switchconv" } */ +/* { dg-do compile } */ + +void +foo (unsigned int v) +{ + const char *s; + + switch (v) + { + case 0: + s = "foo"; + break; + case 1: + s = "bar"; + break; + case 2: + s = "spam"; + break; + default: + for (int i = 0; i < v; i++) + __builtin_printf ("baz\n"); + return; + } + + __builtin_printf ("%s\n", s); +} + +int +bar (unsigned int v, int w) +{ + const char *s; + + switch (v) + { + case 0: + s = "foo"; + break; + case 1: + s = "bar"; + break; + case 2: + s = "spam"; + break; + default: + __builtin_printf ("baz\n"); + if (v > 25) + __builtin_printf ("bl1\n"); + else + __builtin_printf ("bl2\n"); + goto lab; + } + + __builtin_printf ("%s\n", s); + if (w > 25) + __builtin_printf ("cl1\n"); + else + __builtin_printf ("cl2\n"); + lab: + __builtin_printf ("dl\n"); + return v + w; +} + +/* { dg-final { scan-tree-dump-times "Switch converted" 2 "switchconv" } } */ +/* { dg-final { scan-tree-dump-times "= CSWTCH" 2 "switchconv" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp113.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp113.c new file mode 100644 index 0000000..5069fdf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp113.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +int f(int a) { + switch (a & 1) { + case 0: + case 1: return 3; + case 2: return 5; + case 3: return 7; + case 4: return 11; + case 5: return 13; + case 6: return 17; + case 7: return 19; + } +} + +/* { dg-final { scan-tree-dump "return 3;" "vrp1" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp40.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp40.c index de56179..394b5fc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp40.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp40.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1" } */ +/* { dg-options "-O2 -fdump-tree-vrp1 -fno-tree-switch-conversion" } */ int f(int a) { switch (a & 1) { |