public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-8519] aarch64: Avoid allocating FPRs to address registers [PR113623]
@ 2024-01-30  9:30 Richard Sandiford
  0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2024-01-30  9:30 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:fa2739ac1b74769d97fba34db9b9a8aa8786539e

commit r14-8519-gfa2739ac1b74769d97fba34db9b9a8aa8786539e
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Tue Jan 30 09:30:35 2024 +0000

    aarch64: Avoid allocating FPRs to address registers [PR113623]
    
    For something like:
    
    void
    foo (void)
    {
      int *ptr;
      asm volatile ("%0" : "=w" (ptr));
      asm volatile ("%0" :: "m" (*ptr));
    }
    
    early-ra would allocate ptr to an FPR for the first asm, thus
    leaving an FPR address in the second asm.  The address was then
    reloaded by LRA to make it valid.
    
    But early-ra shouldn't be allocating at all in that kind of
    situation.  Doing so caused the ICE in the PR (with LDP fusion).
    
    Fixed by making sure that we record address references as
    GPR references.
    
    gcc/
            PR target/113623
            * config/aarch64/aarch64-early-ra.cc (early_ra::preprocess_insns):
            Mark all registers that occur in addresses as needing a GPR.
    
    gcc/testsuite/
            PR target/113623
            * gcc.c-torture/compile/pr113623.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64-early-ra.cc         |   9 ++
 gcc/testsuite/gcc.c-torture/compile/pr113623.c | 137 +++++++++++++++++++++++++
 2 files changed, 146 insertions(+)

diff --git a/gcc/config/aarch64/aarch64-early-ra.cc b/gcc/config/aarch64/aarch64-early-ra.cc
index 028296639b83..1a03d86e94b9 100644
--- a/gcc/config/aarch64/aarch64-early-ra.cc
+++ b/gcc/config/aarch64/aarch64-early-ra.cc
@@ -1173,6 +1173,15 @@ early_ra::preprocess_insns ()
       if (!NONDEBUG_INSN_P (insn))
 	continue;
 
+      // Mark all registers that occur in addresses as needing a GPR.
+      vec_rtx_properties properties;
+      properties.add_insn (insn, true);
+      for (rtx_obj_reference ref : properties.refs ())
+	if (ref.is_reg ()
+	    && ref.in_address ()
+	    && !HARD_REGISTER_NUM_P (ref.regno))
+	  m_pseudo_regs[ref.regno].flags |= ALLOWS_NONFPR | NEEDS_NONFPR;
+
       if (GET_CODE (PATTERN (insn)) == USE
 	  || GET_CODE (PATTERN (insn)) == CLOBBER)
 	continue;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr113623.c b/gcc/testsuite/gcc.c-torture/compile/pr113623.c
new file mode 100644
index 000000000000..ed33890054ef
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr113623.c
@@ -0,0 +1,137 @@
+typedef struct A A;
+typedef struct B B;
+struct A { char *a; long b; };
+enum { C, D };
+typedef struct { A *c; A *d; } E;
+typedef enum { F } G;
+typedef enum { H } I;
+struct B { A *e, *f, *g, *h; char i; } j;
+int k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af;
+int ag, ah, ai, aj, ak, al, am, an, ao, ap;
+E aq;
+G ar;
+I as;
+char at;
+
+static int
+foo (char *c, long d)
+{
+  switch (d) {
+  case 7:
+    switch (c[6])
+    case 'd':
+      if (ao)
+      case 'h':
+        if (an)
+        case 'r':
+          if (am)
+          case 's':
+            if (al)
+              if (ak)
+                return C;
+    /* FALLTHRU */
+  case 8:
+    switch (c[7])
+    case 'e':
+      if (aj)
+      case 'h':
+        if (ai)
+        case 'n':
+          if (ah)
+          case 'y':
+            if (ag)
+            case 9:
+              switch (c[8])
+              case 'l':
+              case 0:
+                switch (c[9])
+                case 'e':
+                  if (af)
+                    if (ae)
+                    case 'n':
+                      if (ad)
+                      case 't':
+                        if (ac)
+                        case 'y':
+                          if (ab)
+                          case 1:
+                            switch (c[0])
+                            case 'r':
+                            case 2:
+                              switch (c[1])
+                              case 'e':
+                              case 3:
+                                switch (c[2])
+                                case 'd':
+                                  if (aa)
+                                  case 'e':
+                                    if (z)
+                                    case 'h':
+                                      if (y)
+                                      case 'l':
+                                        if (x)
+                                        case 'n':
+                                          if (w)
+                                          case 's':
+                                            if (v)
+                                            case 4:
+                                              switch (c[3])
+                                              case 'h':
+                                                if (u)
+                                                case 't':
+                                                  if (t)
+                                                  case 5:
+                                                    switch (c[4])
+                                                    case 'e':
+                                                      if (s)
+                                                      case 'g':
+                                                        if (r)
+                                                        case 6:
+                                                          switch (c[5])
+                                                          case 'e':
+                                                            if (q)
+                                                              if (p)
+                                                              case 'g':
+                                                                if (o)
+                                                                case 'n':
+                                                                  if (n)
+                                                                    if (m)
+                                                                    case 7:
+                                                                      switch (c[6])
+                                                                      case 'e':
+                                                                        if (l)
+                                                                        case 'g':
+                                                                          if (k)
+                                                                            return D;
+  }
+  return 0;
+}
+
+void bar (void);
+
+static int
+baz (B *x)
+{
+  aq.c = x->e;
+  aq.d = x->f;
+  ap = foo (x->e->a, x->e->b);
+  if (x->i)
+    bar ();
+  x->g = aq.c;
+  x->h = aq.d;
+  return 0;
+}
+
+void
+qux (void)
+{
+  for (; at;)
+    switch (as)
+      {
+      case H:
+	baz (&j);
+	j.f->b = 0;
+	if (ar)
+	  baz (&j);
+      }
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-01-30  9:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-30  9:30 [gcc r14-8519] aarch64: Avoid allocating FPRs to address registers [PR113623] Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).