aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclaziss <claziss@138bc75d-0d04-0410-961f-82ee72b054a4>2017-03-13 12:55:38 +0000
committerclaziss <claziss@138bc75d-0d04-0410-961f-82ee72b054a4>2017-03-13 12:55:38 +0000
commitafd80b00e766c511245e7a485d910bb5c4eb97f8 (patch)
treeccf1113962d544a11955c333d4a591a72daa3b44
parent11c999a24f3807fe5121bede6c60a0367865403b (diff)
[ARC] Handle complex PIC move patterns.
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@246087 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/arc/arc.c49
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arc/pr9001090948.c25
4 files changed, 82 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c001ae5a5e0..f6435046c13 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 4c99f1ddcaf..23b7ea4fbd2 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c25c69fe093..5b7b5c19894 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..103f4aee7ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/pr9001090948.c
@@ -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;
+}