]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LRA: Check hard reg availability of pseudo and its subreg for pseudo reload
authorVladimir N. Makarov <vmakarov@redhat.com>
Fri, 2 Dec 2022 13:18:04 +0000 (08:18 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Fri, 2 Dec 2022 13:24:03 +0000 (08:24 -0500)
Do not reload subreg pseudo if there are hard regs for subreg mode
but there are no hard regs for pseudo mode.

        PR target/106462

gcc/ChangeLog:

* lra-constraints.cc (curr_insn_transform): Check available hard
regs for pseudo and its subreg to decide what to reload.

gcc/testsuite/ChangeLog:

* gcc.target/mips/pr106462.c: New test.

gcc/lra-constraints.cc
gcc/testsuite/gcc.target/mips/pr106462.c [new file with mode: 0644]

index d92ab76908c8e07219ae9efd55eafbe76430e3f7..02b5ab4a3169e52477e9da78aa4835e858939465 100644 (file)
@@ -4582,7 +4582,18 @@ curr_insn_transform (bool check_only_p)
                      || (partial_subreg_p (mode, GET_MODE (reg))
                          && known_le (GET_MODE_SIZE (GET_MODE (reg)),
                                       UNITS_PER_WORD)
-                         && WORD_REGISTER_OPERATIONS)))
+                         && WORD_REGISTER_OPERATIONS))
+                 /* Avoid the situation when there are no available hard regs
+                    for the pseudo mode but there are ones for the subreg
+                    mode: */
+                 && !(goal_alt[i] != NO_REGS
+                      && REGNO (reg) >= FIRST_PSEUDO_REGISTER
+                      && (prohibited_class_reg_set_mode_p
+                          (goal_alt[i], reg_class_contents[goal_alt[i]],
+                           GET_MODE (reg)))
+                      && !(prohibited_class_reg_set_mode_p
+                           (goal_alt[i], reg_class_contents[goal_alt[i]],
+                            mode))))
                {
                  /* An OP_INOUT is required when reloading a subreg of a
                     mode wider than a word to ensure that data beyond the
diff --git a/gcc/testsuite/gcc.target/mips/pr106462.c b/gcc/testsuite/gcc.target/mips/pr106462.c
new file mode 100644 (file)
index 0000000..c910540
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=64 -msingle-float" } */
+
+extern void bar (float x, short y);
+
+void foo (int argc)
+{
+    short c = argc * 2;
+    float a = (float)(short)c, b = 9.5;
+
+    bar (b/a, c);
+}