* Claudiu Zissulescu <claudiu.zissule...@synopsys.com> [2017-02-28 16:59:58 +0100]:
> Hi, > > 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. > > Ok to apply? > Claudiu There's a couple of spelling mistakes I've marked inline, but otherwise, this seems sensible. Thanks, Andrew > > gcc/ > 2017-02-28 Claudiu Zissulescu <claz...@synopsys.com> > > * config/arc/arc.c (arc_legitimize_pic_address): Handle PIC > expressions with MINUS and UNARY ops. > > gcc/testsuite > 2017-02-28 Claudiu Zissulescu <claz...@synopsys.com> > > * gcc.target/arc/pr9001090948.c: New file. > --- > gcc/config/arc/arc.c | 49 > ++++++++++++++++++++++++++++- > gcc/testsuite/gcc.target/arc/pr9001090948.c | 25 +++++++++++++++ > 2 files changed, 73 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.target/arc/pr9001090948.c > > diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c > index 508a9a6..3b94d7c 100644 > --- a/gcc/config/arc/arc.c > +++ b/gcc/config/arc/arc.c > @@ -5024,8 +5024,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 rezulting in complex patterns that are not s/rezulting/resulting/ > + supported by the current implementation. The following > + two if-cases are simplifying the complex patters in s/patters in/patterns 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/gcc.target/arc/pr9001090948.c > b/gcc/testsuite/gcc.target/arc/pr9001090948.c > new file mode 100644 > index 0000000..103f4ae > --- /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; > +} > -- > 1.9.1 >