Attached patch backports fixes for PR 58066 to release branches. 2015-07-XX Uros Bizjak <ubiz...@gmail.com>
Backport from mainline: 2015-07-17 Uros Bizjak <ubiz...@gmail.com> PR rtl-optimization/66891 * calls.c (expand_call): Wrap precompute_register_parameters with NO_DEFER_POP/OK_DEFER_POP to prevent deferred pops. 2015-07-15 Uros Bizjak <ubiz...@gmail.com> PR target/58066 * config/i386/i386.md (*tls_global_dynamic_64_<mode>): Depend on SP_REG. (*tls_local_dynamic_base_64_<mode>): Ditto. (*tls_local_dynamic_base_64_largepic): Ditto. (tls_global_dynamic_64_<mode>): Update expander pattern. (tls_local_dynamic_base_64_<mode>): Ditto. 2015-07-15 Uros Bizjak <ubiz...@gmail.com> PR rtl-optimization/58066 * calls.c (expand_call): Precompute register parameters before stack testsuite/ChangeLog: 2015-07-XX Uros Bizjak <ubiz...@gmail.com> Backport from mainline: 2015-07-17 Uros Bizjak <ubiz...@gmail.com> PR target/66891 * gcc.target/i386/pr66891.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32} for all default languages, obj-c++ and go. OK for branches? Uros.
Index: calls.c =================================================================== --- calls.c (revision 226001) +++ calls.c (working copy) @@ -3115,6 +3115,19 @@ expand_call (tree exp, rtx target, int ignore) compute_argument_addresses (args, argblock, num_actuals); + /* Stack is properly aligned, pops can't safely be deferred during + the evaluation of the arguments. */ + NO_DEFER_POP; + + /* Precompute all register parameters. It isn't safe to compute + anything once we have started filling any specific hard regs. + TLS symbols sometimes need a call to resolve. Precompute + register parameters before any stack pointer manipulation + to avoid unaligned stack in the called function. */ + precompute_register_parameters (num_actuals, args, ®_parm_seen); + + OK_DEFER_POP; + /* Perform stack alignment before the first push (the last arg). */ if (argblock == 0 && adjusted_args_size.constant > reg_parm_stack_space @@ -3155,10 +3168,6 @@ expand_call (tree exp, rtx target, int ignore) funexp = rtx_for_function_call (fndecl, addr); - /* Precompute all register parameters. It isn't safe to compute anything - once we have started filling any specific hard regs. */ - precompute_register_parameters (num_actuals, args, ®_parm_seen); - if (CALL_EXPR_STATIC_CHAIN (exp)) static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp)); else Index: testsuite/gcc.target/i386/pr66891.c =================================================================== --- testsuite/gcc.target/i386/pr66891.c (revision 0) +++ testsuite/gcc.target/i386/pr66891.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-O2" } */ + +__attribute__((__stdcall__)) void fn1(); + +int a; + +static void fn2() { + for (;;) + ; +} + +void fn3() { + fn1(0); + fn2(a == 0); +}