On Fri, Nov 18, 2016 at 09:09:40AM +0100, Richard Biener wrote:
> > This patch rewrites the algorithm to deal with this.  It also makes it
> > simpler: it does not need the "candidates" array anymore, it does not
> > need RTL layout mode, it does not need cleanup_cfg, and it does not
> > need to keep track of what blocks it already visited.
> > 
> > Tested on powerpc64-linux {-m32,-m64}, and on the testcase, and on a version
> > of the testcase that has 2000 cases instead of 4.  Is this okay for trunk?
> 
> Looks good to me - a single question below:

And here is a testcase, okay as well?


Segher


2016-11-18  Segher Boessenkool  <seg...@kernel.crashing.org>

gcc/testsuite/
        PR rtl-optimization/71785
        * gcc.target/powerpc/pr71785.c: New file.

---
 gcc/testsuite/gcc.target/powerpc/pr71785.c | 52 ++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr71785.c

diff --git a/gcc/testsuite/gcc.target/powerpc/pr71785.c 
b/gcc/testsuite/gcc.target/powerpc/pr71785.c
new file mode 100644
index 0000000..613dcd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr71785.c
@@ -0,0 +1,52 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not {\mb\M} } } */
+
+/* Check that all computed gotos in this testcase end up unfactored completely.
+   If some is not there will be a unconditional jump left; if all works fine,
+   all are gone.  */
+
+typedef enum opcode
+{
+       OP_A,
+       OP_B,
+       OP_END
+} opcode;
+
+typedef struct op
+{
+       opcode opcode;
+       int arg;
+} op;
+
+extern void do_stuff_b(int arg);
+extern void do_stuff_c(int arg);
+
+extern int someglobal;
+
+void
+eval(op *op)
+{
+       static const void *dispatch_table[] = {
+               &&CASE_OP_A,
+               &&CASE_OP_B,
+               &&CASE_OP_C,
+               &&CASE_OP_END
+       };
+
+       goto *dispatch_table[op->opcode];
+CASE_OP_A:
+       someglobal++;
+       op++;
+       goto *dispatch_table[op->opcode];
+CASE_OP_B:
+       do_stuff_b(op->arg);
+       op++;
+       goto *dispatch_table[op->opcode];
+CASE_OP_C:
+       do_stuff_c(op->arg);
+       op++;
+       goto *dispatch_table[op->opcode];
+CASE_OP_END:
+       return;
+}
-- 
1.9.3

Reply via email to