aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2019-09-20 09:45:26 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2019-09-20 09:45:26 +0000
commitf3471d9d409b99af3d75abd2ad09fc1a22a18529 (patch)
treee00e5739d699615ba9e9f7df8988a2c7ec3a77a3
parent176b3b7aba1ebf45587aa6876e828cb24a619d3a (diff)
PR target/91269
* config/sparc/sparc.h (HARD_REGNO_CALLER_SAVE_MODE): Define. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@275995 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sparc/sparc.h7
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/pr91269.c70
4 files changed, 86 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aa90ce5df7b..1d694a7f7c9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2019-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/91269
+ * config/sparc/sparc.h (HARD_REGNO_CALLER_SAVE_MODE): Define.
+
2019-09-19 Kito Cheng <kito.cheng@sifive.com>
Backport from mainline
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 015065ffb81..4b09fc86b78 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -736,6 +736,13 @@ along with GCC; see the file COPYING3. If not see
register window instruction in the prologue. */
#define HARD_REGNO_RENAME_OK(FROM, TO) ((FROM) != 1)
+/* Select a register mode required for caller save of hard regno REGNO.
+ Contrary to what is documented, the default is not the smallest suitable
+ mode but the largest suitable mode for the given (REGNO, NREGS) pair and
+ it quickly creates paradoxical subregs that can be problematic. */
+#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
+ ((MODE) == VOIDmode ? choose_hard_reg_mode (REGNO, NREGS, false) : (MODE))
+
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 51bb429e6bf..221de2e428c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/pr91269.c: New test.
+
2019-09-19 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/91727
diff --git a/gcc/testsuite/gcc.dg/pr91269.c b/gcc/testsuite/gcc.dg/pr91269.c
new file mode 100644
index 00000000000..8c03ba8dab2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91269.c
@@ -0,0 +1,70 @@
+/* PR target/91269 */
+/* Testcase by Sergei Trofimovich <slyfox@inbox.ru> */
+
+/* { dg-do assemble } */
+/* { dg-options "-O2 -Wno-int-conversion" } */
+/* { dg-additional-options "-fcall-used-g6 -fPIE -mcpu=niagara4" { target sparc*-*-* } } */
+
+struct m;
+
+enum { a = 2 };
+int b[1];
+int d[2715];
+int e, f, h;
+enum { i = 2 } j;
+inline int c(int k) {
+ char *cp;
+ if (k >= 62 && k <= 247)
+ cp = b[k];
+ if (cp)
+ return 65533;
+ return 2;
+}
+inline int g(int k) {
+ if (k < sizeof(d))
+ return e;
+ return 0;
+}
+
+int u(struct m*, char*, char*);
+
+int l(struct m *k, char n, long o, int *p) {
+ int q, flags = j, r, s, lasttwo = *p;
+ char inptr, outptr;
+ while (inptr) {
+ if (__builtin_expect(h, 0))
+ break;
+ unsigned ch = inptr;
+ if (lasttwo) {
+ long need = lasttwo >> 3;
+ if (__builtin_expect(need > n, 0))
+ break;
+ } else if (s == i) {
+ long t = c(ch);
+ if (t != 65533) {
+ int jch = g(ch);
+ if (jch & 8)
+ continue;
+ }
+ }
+ if (ch <= 5)
+ ;
+ else {
+ long t = c(ch);
+ if (t != 65533)
+ ;
+ else {
+ switch (f >> 8)
+ case 79:
+ q = f == 20308 || f == 20350;
+ if (q)
+ if (j)
+ r = u(k, &inptr, &outptr);
+ s = *p;
+ if (r)
+ if (o && flags & a)
+ break;
+ }
+ }
+ }
+}