]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR105032] LRA: modify loop condition to find reload insns for hard reg splitting
authorVladimir N. Makarov <vmakarov@redhat.com>
Fri, 1 Apr 2022 13:48:57 +0000 (09:48 -0400)
committerVladimir N. Makarov <vmakarov@redhat.com>
Fri, 1 Apr 2022 14:21:19 +0000 (10:21 -0400)
When trying to split hard reg live range to assign hard reg to a reload
pseudo, LRA searches for reload insns of the reload pseudo
assuming a specific order of the reload insns.  This order is violated if
reload involved in inheritance transformation. In such case, the loop used
for reload insn searching can become infinite.  The patch fixes this.

gcc/ChangeLog:

PR middle-end/105032
* lra-assigns.c (find_reload_regno_insns): Modify loop condition.

gcc/testsuite/ChangeLog:

PR middle-end/105032
* gcc.target/i386/pr105032.c: New.

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

index c6a941fe66381ba733a0eda3f527a6c11383ed37..b406096a39cbf95d6d2db719bf33d63cbfcdc164 100644 (file)
@@ -1724,7 +1724,8 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish)
     {
       for (prev_insn = PREV_INSN (start_insn),
             next_insn = NEXT_INSN (start_insn);
-          n != 1 && (prev_insn != NULL || next_insn != NULL); )
+          n != 1 && ((prev_insn != NULL && first_insn == NULL)
+                     || (next_insn != NULL && second_insn == NULL)); )
        {
          if (prev_insn != NULL && first_insn == NULL)
            {
diff --git a/gcc/testsuite/gcc.target/i386/pr105032.c b/gcc/testsuite/gcc.target/i386/pr105032.c
new file mode 100644 (file)
index 0000000..a45e755
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-w" } */
+
+typedef unsigned int size_t;   
+__extension__ typedef long int __off_t;
+typedef __off_t off_t;
+static void *__sys_mmap(void *addr, size_t length, int prot, int flags, int fd,
+                       off_t offset)
+{
+  offset >>= 12;
+  return (void *)({ long _ret;
+      register long _num asm("eax") = (192);
+      register long _arg1 asm("ebx") = (long)(addr);
+      register long _arg2 asm("ecx") = (long)(length);
+      register long _arg3 asm("edx") = (long)(prot);
+      register long _arg4 asm("esi") = (long)(flags);
+      register long _arg5 asm("edi") = (long)(fd);
+      long _arg6 = (long)(offset);
+      asm volatile ("pushl     %[_arg6]\n\t"
+                   "pushl      %%ebp\n\t"
+                   "movl       4(%%esp), %%ebp\n\t"
+                   "int        $0x80\n\t"
+                   "popl       %%ebp\n\t"
+                   "addl       $4,%%esp\n\t"
+                   : "=a"(_ret)
+                   : "r"(_num), "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),"r"(_arg5), [_arg6]"m"(_arg6)
+                   : "memory", "cc" );
+      _ret; });
+}
+
+int main(void)
+{
+  __sys_mmap(((void *)0), 0x1000, 0x1 | 0x2, 0x20 | 0x02, -1, 0);
+  return 0;
+}