]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR117946][LRA]: When assigning hard reg use biggest mode to check ira_prohibited_cla...
authorVladimir N. Makarov <vmakarov@redhat.com>
Tue, 10 Dec 2024 17:50:27 +0000 (12:50 -0500)
committerVladimir N. Makarov <vmakarov@redhat.com>
Tue, 10 Dec 2024 17:53:00 +0000 (12:53 -0500)
A pseudo in the PR test case gets hard reg 43 which is x86 r15 (after
r15, xmm regs go).  The pseudo is of INT_SSE_CLASS and SImode but is
used in TImode as paradoxical subreg.  r15 in TImode is wrong and does
not satisfy constraint 'r'.  Therefore LRA creates moves involving the
pseudo in TImode until the limit of reload insns is achieved.
Unfortunately x86 hard_regno_mode_ok (as some hooks for other targets)
says that it is ok to use r15 for TImode pseudo.  Therefore LRA uses
ira_prohibited_class_mode_regs for such cases but it was checked
against native pseudo mode.  The patch fixes it by using the biggest
pseudo mode.

gcc/ChangeLog:

PR rtl-optimization/117946
* lra-assigns.cc: (find_hard_regno_for_1): Use the biggest mode to
check ira_prohibited_class_mode_regs.

gcc/testsuite/ChangeLog:

PR rtl-optimization/117946
* gcc.target/i386/pr117946.c: New.

gcc/lra-assigns.cc
gcc/testsuite/gcc.target/i386/pr117946.c [new file with mode: 0644]

index 0a14bde5e743c54673bd7f89db3047ce31ac822e..405afc06f57e120b806c6e5797d3f1da8af87eb5 100644 (file)
@@ -629,13 +629,12 @@ find_hard_regno_for_1 (int regno, int *cost, int try_only_hard_regno,
        hard_regno = ira_class_hard_regs[rclass][i];
       if (! overlaps_hard_reg_set_p (conflict_set,
                                     PSEUDO_REGNO_MODE (regno), hard_regno)
-         && targetm.hard_regno_mode_ok (hard_regno,
-                                        PSEUDO_REGNO_MODE (regno))
+         && targetm.hard_regno_mode_ok (hard_regno, PSEUDO_REGNO_MODE (regno))
          /* We cannot use prohibited_class_mode_regs for all classes
             because it is not defined for all classes.  */
          && (ira_allocno_class_translate[rclass] != rclass
              || ! TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs
-                                     [rclass][PSEUDO_REGNO_MODE (regno)],
+                                     [rclass][biggest_mode],
                                      hard_regno))
          && ! TEST_HARD_REG_BIT (impossible_start_hard_regs, hard_regno)
          && (nregs_diff == 0
diff --git a/gcc/testsuite/gcc.target/i386/pr117946.c b/gcc/testsuite/gcc.target/i386/pr117946.c
new file mode 100644 (file)
index 0000000..7304e01
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile  { target { ! ia32 } } } */
+/* { dg-options "-O -favoid-store-forwarding -mavx10.1 -mprefer-avx128 --param=store-forwarding-max-distance=128 -Wno-psabi" } */
+typedef __attribute__((__vector_size__ (64))) _Decimal32 V;
+
+void
+bar (float, float, float, float, float, _Complex, float, float, float,
+     _BitInt(1023), _BitInt (1023), float, float, float, float, float, float,
+     float, float, float, float, float, float, _Decimal64, float, float, float,
+     V, float, _Decimal64);
+
+void
+foo ()
+{
+  bar (0, 0, 0, 0, 0, 0, 0, __builtin_nand64 ("nan"), 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (V){}, 0, 0);
+}