On Wed, Jul 15, 2015 at 3:37 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Wed, Jul 15, 2015 at 5:05 AM, Uros Bizjak <ubiz...@gmail.com> wrote: >> On Wed, Jul 15, 2015 at 1:36 PM, Uros Bizjak <ubiz...@gmail.com> wrote: >> >>>> I couldn't figure a way to add conditional constraints for "?r/rmF" and >>>> "r/rmF". I simply disabled *movsf_internal if TARGET_HARD_FP_REGS >>>> is false and added a new "*movsf_internal_soft_fp" pattern. >>>> >>>> OK for trunk if there is no regressions? >>> >>> No. We don't want duplicated patterns. >>> Please add two patterns at the end of the constraint string and use >> >> ... add two *constraints* at the end ... > > When I simply added "r/rmF" to the end, RA saw "?r/rmF" first and > ignored "r/rmF" at the end.
Please try attached patch. 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; +}