aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-05-03 09:49:43 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2017-05-03 09:49:43 +0200
commit18bfe94032eef1649444d9d204c516dc12901ace (patch)
tree677559067befe1b2fabb60fceaf581474fa32f64 /gcc/testsuite
parent53e62089fbe61bbf59dd1b14d006a619de7b5f87 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cswtch-3.c330
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cswtch-4.c57
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cswtch-5.c66
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp113.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp40.c2
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) {