]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ira: Implicit uses via hard register constraints
authorStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Thu, 15 Jan 2026 14:14:59 +0000 (15:14 +0100)
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Thu, 15 Jan 2026 14:14:59 +0000 (15:14 +0100)
In ira_implicitly_set_insn_hard_regs() all potentially used registers
stemming from single register constraints are recorded.  Since hard
register constraints are pretty similar, do the same for those, too.
This requires to setup the preferred alternatives which is done via
ira_setup_alts() and also implemented for hard register constraints by
this patch.

This fixes an ICE were previously sched1 swapped the order of the
instructions

(insn 10 9 6 2 (parallel [
            (set (reg:DF 118)
                (asm_operands:DF ("") ("={fr2}") 0 [
                        (reg:TF 121 [ a ])
                    ]
                     [
                        (asm_input:TF ("{fr1}") t.i:5)
                    ]
                     [] t.i:5))
            (clobber (reg:SI 98 ca))
        ]) "t.i":5:3 -1
     (expr_list:REG_DEAD (reg:TF 121 [ a ])
        (expr_list:REG_UNUSED (reg:SI 98 ca)
            (nil))))
...
(insn 13 6 14 2 (set (reg:DF 34 2)
        (const_double:DF 0.0 [0x0.0p+0])) "t.i":6:3 606 {*movdf_hardfloat64}
     (nil))

for the attached example.  This led to an ICE because register 34/fr2
was then live while allocating for pseudo 121.

gcc/ChangeLog:

* ira-lives.cc (ira_implicitly_set_insn_hard_regs): Honor hard
register constraints.
* ira.cc (ira_setup_alts): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/asm-hard-reg-1.c: New test.

gcc/ira-lives.cc
gcc/ira.cc
gcc/testsuite/gcc.target/powerpc/asm-hard-reg-1.c [new file with mode: 0644]

index 8b8387cdd177a21c48dbc93b9e3dccf1fca35038..04e586343c82220685d8b5b80a29f926ac9d659f 100644 (file)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "backend.h"
 #include "target.h"
 #include "rtl.h"
+#include "stmt.h"
 #include "predict.h"
 #include "df.h"
 #include "memmodel.h"
@@ -971,6 +972,12 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set,
                    if (regno >= 0)
                      add_to_hard_reg_set (set, mode, regno);
                  }
+               else if (c == '{')
+                 {
+                   int regno = decode_hard_reg_constraint (p);
+                   gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
+                   add_to_hard_reg_set (set, mode, regno);
+                 }
              }
        }
     }
index 3d2c7592675e8e9dae2277a0c5a858df397a9a46..d65e1b97ed8448ef8e9856baab7e32c5cfb4285e 100644 (file)
@@ -1843,6 +1843,12 @@ ira_setup_alts (rtx_insn *insn)
                    goto op_success;
                    break;
 
+                 case '{':
+                   if (REG_P (op) || SUBREG_P (op))
+                     goto op_success;
+                   win_p = true;
+                   break;
+
                  default:
                    {
                      enum constraint_num cn = lookup_constraint (p);
diff --git a/gcc/testsuite/gcc.target/powerpc/asm-hard-reg-1.c b/gcc/testsuite/gcc.target/powerpc/asm-hard-reg-1.c
new file mode 100644 (file)
index 0000000..b0d8eb9
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+long double a;
+double b;
+void c (double, double);
+void d (void)
+{
+  __asm__ ("" : "={fr2}" (b) : "{fr1}" (a));
+  c (0, 0);
+}