[ARC] Handle complex PIC move patterns.
authorClaudiu Zissulescu <claziss@synopsys.com>
Mon, 13 Mar 2017 12:55:38 +0000 (13:55 +0100)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Mon, 13 Mar 2017 12:55:38 +0000 (13:55 +0100)
fwprop step is placing in the REG_EQUIV notes constant pic unspecs
expressions.  Then, loop may use these notes for optimizations
rezulting in complex patterns that are not supported by the current
implementation.

The patch adds handling of complex PIC addresses having MINUS or UNARY
operations.

gcc/
2017-03-13  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.c (arc_legitimize_pic_address): Handle PIC
expressions with MINUS and UNARY ops.

gcc/testsuite
2017-03-13  Claudiu Zissulescu  <claziss@synopsys.com>

* gcc.target/arc/pr9001090948.c: New file.

From-SVN: r246087

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/pr9001090948.c [new file with mode: 0644]

index c001ae5..f643504 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-13  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.c (arc_legitimize_pic_address): Handle PIC
+       expressions with MINUS and UNARY ops.
+
 2017-03-13  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/79911
index 4c99f1d..23b7ea4 100644 (file)
@@ -4900,8 +4900,55 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
              /* Check that the unspec is one of the ones we generate?  */
              return orig;
            }
+         /* fwprop is placing in the REG_EQUIV notes constant pic
+            unspecs expressions.  Then, loop may use these notes for
+            optimizations resulting in complex patterns that are not
+            supported by the current implementation. The following
+            two if-cases are simplifying the complex patters to
+            simpler ones.  */
+         else if (GET_CODE (addr) == MINUS)
+           {
+             rtx op0 = XEXP (addr, 0);
+             rtx op1 = XEXP (addr, 1);
+             gcc_assert (oldx);
+             gcc_assert (GET_CODE (op1) == UNSPEC);
+
+             emit_move_insn (oldx,
+                             gen_rtx_CONST (SImode,
+                                            arc_legitimize_pic_address (op1,
+                                                                        NULL_RTX)));
+             emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
+             return oldx;
+
+           }
+         else if (GET_CODE (addr) != PLUS)
+           {
+             rtx tmp = XEXP (addr, 0);
+             enum rtx_code code = GET_CODE (addr);
+
+             /* It only works for UNARY operations.  */
+             gcc_assert (UNARY_P (addr));
+             gcc_assert (GET_CODE (tmp) == UNSPEC);
+             gcc_assert (oldx);
+
+             emit_move_insn
+               (oldx,
+                gen_rtx_CONST (SImode,
+                               arc_legitimize_pic_address (tmp,
+                                                           NULL_RTX)));
+
+             emit_insn (gen_rtx_SET (oldx,
+                                     gen_rtx_fmt_ee (code, SImode,
+                                                     oldx, const0_rtx)));
+
+             return oldx;
+           }
          else
-           gcc_assert (GET_CODE (addr) == PLUS);
+           {
+             gcc_assert (GET_CODE (addr) == PLUS);
+             if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
+               return orig;
+           }
        }
 
       if (GET_CODE (addr) == PLUS)
index c25c69f..5b7b5c1 100644 (file)
@@ -1,3 +1,7 @@
+2017-03-13  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * testsuite/gcc.target/arc/pr9001090948.c: New file.
+
 2017-03-11  Segher Boessenkool  <segher@kernel.crashing.org>
 
        * lib/target-supports.exp (check_effective_target_broken_cplxf_arg):
diff --git a/gcc/testsuite/gcc.target/arc/pr9001090948.c b/gcc/testsuite/gcc.target/arc/pr9001090948.c
new file mode 100644 (file)
index 0000000..103f4ae
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-skip-if "ARC600 doesn't support pic" { arc6xx } } */
+/* { dg-options "-Os -fPIC" } */
+#include <stdio.h>
+#include <string.h>
+
+char *
+strip_trail (const char str[], size_t n)
+{
+  static char buf[1025];
+  int j;
+
+  strncpy (buf, str, n);
+  buf[n] = '\0';
+
+  for (j = strlen (buf) - 1; j >= 0; j--)
+    {
+      if (buf[j] != ' ')
+        break;
+
+      buf[j] = '\0';
+    }
+
+  return buf;
+}