Another missing case of CALL_INSN_FUNCTION_USAGE, where clobbered
registers are also marked, this time in postreload/
reload_cse_move2add.

Fixed compiler now generates following code

       call    sysv_abi_func
       movl    $global, %esi
       movl    $.LC2, %edi
       call    sysv_abi_func
       movl    $global, %esi
       movl    $.LC3, %edi
       call    sysv_abi_func

which correctly reloads %esi for every sysv_abi function call.

2015-07-12  Uros Bizjak  <ubiz...@gmail.com>

    PR rtl-optimization/66838
    * postreload.c (reload_cse_move2add): Also process
    CALL_INSN_FUNCTION_USAGE when resetting information of
    call-clobbered registers.

testsuite/ChangeLog:

2015-07-12  Uros Bizjak  <ubiz...@gmail.com>

    PR rtl-optimization/66838
    * gcc.target/i386/pr66838.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

OK for mainline and gcc-5 branch?

Uros.
Index: postreload.c
===================================================================
--- postreload.c        (revision 225722)
+++ postreload.c        (working copy)
@@ -2127,6 +2127,8 @@ reload_cse_move2add (rtx_insn *first)
         unknown values.  */
       if (CALL_P (insn))
        {
+         rtx link;
+
          for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
            {
              if (call_used_regs[i])
@@ -2133,6 +2135,21 @@ reload_cse_move2add (rtx_insn *first)
                /* Reset the information about this register.  */
                reg_mode[i] = VOIDmode;
            }
+
+         for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
+              link = XEXP (link, 1))
+           {
+             rtx setuse = XEXP (link, 0);
+             rtx usage_rtx = XEXP (setuse, 0);
+             if (GET_CODE (setuse) == CLOBBER
+                 && REG_P (usage_rtx))
+               {
+                 unsigned int end_regno = END_REGNO (usage_rtx);
+                 for (unsigned int r = REGNO (usage_rtx); r < end_regno; ++r)
+                   /* Reset the information about this register.  */
+                   reg_mode[r] = VOIDmode;
+               }
+           }
        }
     }
   return changed;
Index: testsuite/gcc.target/i386/pr66838.c
===================================================================
--- testsuite/gcc.target/i386/pr66838.c (revision 0)
+++ testsuite/gcc.target/i386/pr66838.c (working copy)
@@ -0,0 +1,36 @@
+/* { dg-do run { target lp64 } } */
+/* { dg-options "-O2" } */
+
+void abort (void);
+
+char global;
+
+__attribute__((sysv_abi, noinline, noclone))
+void sysv_abi_func(char const *desc, void *local)
+{
+  register int esi asm ("esi");
+  register int edi asm ("edi");
+  
+  if (local != &global)
+    abort ();
+
+  /* Clobber some of the extra SYSV ABI registers.  */
+  asm volatile ("movl\t%2, %0\n\tmovl\t%2, %1"
+               : "=r" (esi), "=r" (edi)
+               : "i" (0xdeadbeef));
+}
+
+__attribute__((ms_abi, noinline, noclone))
+void ms_abi_func ()
+{
+  sysv_abi_func ("1st call", &global);
+  sysv_abi_func ("2nd call", &global);
+  sysv_abi_func ("3rd call", &global);
+}
+
+int
+main(void)
+{
+  ms_abi_func();
+  return 0;
+}

Reply via email to