re PR middle-end/80421 (Case dispatch is scrambled in switch-statement)
authorJakub Jelinek <jakub@redhat.com>
Wed, 11 Oct 2017 20:51:08 +0000 (22:51 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 11 Oct 2017 20:51:08 +0000 (22:51 +0200)
PR middle-end/80421
* gcc.c-torture/execute/pr80421.c: New test.

From-SVN: r253662

gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr80421.c [new file with mode: 0644]

index 2135f48e5f8fa0e9483c967b405ebe6bf6a75891..7ea4bd22ac7889c2372abe941901a12576d908aa 100644 (file)
@@ -1,5 +1,8 @@
 2017-10-11  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/80421
+       * gcc.c-torture/execute/pr80421.c: New test.
+
        PR tree-optimization/78558
        * gcc.dg/vect/pr78558.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr80421.c b/gcc/testsuite/gcc.c-torture/execute/pr80421.c
new file mode 100644 (file)
index 0000000..b13ab5f
--- /dev/null
@@ -0,0 +1,121 @@
+/* PR middle-end/80421 */
+
+__attribute__ ((noinline, noclone)) void
+baz (const char *t, ...)
+{
+  asm volatile (""::"r" (t):"memory");
+  if (*t == 'T')
+    __builtin_abort ();
+}
+
+unsigned int
+foo (char x)
+{
+  baz ("x %c\n", x);
+  switch (x)
+    {
+    default:
+      baz ("case default\n");
+      if (x == 'D' || x == 'I')
+       baz ("This should never be reached.\n");
+      return 0;
+    case 'D':
+      baz ("case 'D'\n");
+      return 0;
+    case 'I':
+      baz ("case 'I'\n");
+      return 0;
+    }
+}
+
+void
+bar (void)
+{
+  int a = 2;
+  int b = 5;
+  char c[] = {
+    2, 4, 1, 2, 5, 5, 2, 4, 4, 0, 0, 0, 0, 0, 0, 3, 4, 4, 2, 4,
+    1, 2, 5, 5, 2, 4, 1, 0, 0, 0, 2, 4, 4, 3, 4, 3, 3, 5, 1, 3,
+    5, 5, 2, 4, 4, 2, 4, 1, 3, 5, 3, 3, 5, 1, 3, 5, 1, 2, 4, 4,
+    2, 4, 2, 3, 5, 1, 3, 5, 1, 3, 5, 5, 2, 4, 1, 2, 4, 2, 3, 5,
+    3, 3, 5, 1, 3, 5, 5, 2, 4, 1, 2, 4, 1, 3, 5, 3, 3, 5, 1, 3,
+    5, 5, 2, 4, 4, 2, 4, 1, 3, 5, 3, 3, 5, 1, 3, 5, 1, 2, 4, 1,
+    2, 4, 2, 3, 5, 1, 3, 5, 1, 3, 5, 1, 2, 4, 1, 2, 4, 1, 3, 5,
+    1, 3, 5, 1, 3, 5, 1, 2, 4, 4, 2, 4, 1, 3, 5, 1, 3, 5, 1, 3,
+    5, 5, 2, 4, 4, 2, 4, 2, 3, 5, 3, 3, 5, 1, 3, 5, 5, 2, 4, 4,
+    2, 4, 1, 3, 5, 3, 3, 5, 1, 3, 5, 1, 2, 5, 5, 2, 4, 2, 3, 5,
+    1, 3, 4, 1, 3, 5, 1, 2, 5, 5, 2, 4, 1, 2, 5, 1, 3, 5, 3, 3,
+    5, 1, 2, 5, 5, 2, 4, 2, 2, 5, 1, 3, 5, 3, 3, 5, 1, 2, 5, 1,
+    2, 4, 1, 2, 5, 2, 3, 5, 1, 3, 5, 1, 2, 5, 1, 2, 4, 2, 2, 5,
+    1, 3, 5, 1, 3, 5, 1, 2, 5, 5, 2, 4, 2, 2, 5, 2, 3, 5, 3, 3,
+    5, 1, 2, 5, 5, 2, 4, 2, 2, 5, 2, 3, 5, 3, 3, 5, 1, 2, 5, 5,
+    2, 4, 2, 2, 5, 1, 3, 5, 3, 3, 5, 1, 2, 5, 5, 2, 4, 2, 2, 5,
+    1, 3, 5, 3, 3, 5, 1, 2, 5, 1, 2, 4, 1, 2, 5, 2, 3, 5, 1, 3,
+    5, 1, 2, 5, 5, 2, 4, 2, 2, 5, 2, 3, 5, 3, 3, 5, 1, 2, 5, 5,
+    2, 4, 1, 2, 5, 1, 3, 5, 3, 3, 5, 1, 2, 5, 5, 2, 4, 2, 2, 5,
+    1, 3, 5, 3, 3, 5, 1, 2, 5, 5, 2, 4, 2, 2, 5, 1, 3, 5, 3, 3,
+    5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  };
+  char *f = c + 390;
+  int i, j, e, g, h;
+  char k, l;
+  i = 26;
+  j = 25;
+  k = l = 'M';
+  h = 2;
+  while (i > 0)
+    {
+      int x = i - a;
+      x = x > 0 ? x : 0;
+      x = j - x;
+      g = x * 3 + h;
+      switch (f[g])
+       {
+       case 1:
+         --i;
+         --j;
+         h = 2;
+         f -= b * 3;
+         k = 'M';
+         break;
+       case 2:
+         --i;
+         h = 0;
+         f -= b * 3;
+         k = 'I';
+         break;
+       case 3:
+         --i;
+         h = 2;
+         f -= b * 3;
+         k = 'I';
+         break;
+       case 4:
+         --j;
+         h = 1;
+         k = 'D';
+         break;
+       case 5:
+         --j;
+         h = 2;
+         k = 'D';
+         break;
+       }
+      if (k == l)
+       ++e;
+      else
+       {
+         foo (l);
+         l = k;
+       }
+    }
+}
+
+int
+main ()
+{
+  char l = 'D';
+  foo (l);
+  bar ();
+  return 0;
+}