Hi! As discussed in the PR and suggested by Uros, scheduler has code to keep a use of hard register next to the assignment that sets that hard register from a pseudo, which is desirable so that RA can deal with it properly. Unfortunately, with -fstack-protector* we stick the stack protect epilogue in between, which splits the load and use to different basic blocks. The code emitted by expand_function_end between these two spots is only the loading of the return value into registers, so generally it shouldn't contain any stores which stack protection wants to guard against, so I believe from security POV this shouldn't weaken anything, but fixes the testcase.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2019-02-01 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/87485 * function.c (expand_function_end): Move stack_protect_epilogue before loading of return value into hard register(s). * gcc.dg/pr87485.c: New test. --- gcc/function.c.jj 2019-01-29 16:47:02.000000000 +0100 +++ gcc/function.c 2019-02-01 16:23:07.471877843 +0100 @@ -5330,6 +5330,10 @@ expand_function_end (void) communicate between __builtin_eh_return and the epilogue. */ expand_eh_return (); + /* If stack protection is enabled for this function, check the guard. */ + if (crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) + stack_protect_epilogue (); + /* If scalar return value was computed in a pseudo-reg, or was a named return value that got dumped to the stack, copy that to the hard return register. */ @@ -5475,10 +5479,6 @@ expand_function_end (void) && targetm_common.except_unwind_info (&global_options) != UI_SJLJ) emit_insn (gen_blockage ()); - /* If stack protection is enabled for this function, check the guard. */ - if (crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) - stack_protect_epilogue (); - /* If we had calls to alloca, and this machine needs an accurate stack pointer to exit the function, insert some code to save and restore the stack pointer. */ --- gcc/testsuite/gcc.dg/pr87485.c.jj 2019-02-01 16:30:51.101211900 +0100 +++ gcc/testsuite/gcc.dg/pr87485.c 2019-02-01 16:31:48.660260183 +0100 @@ -0,0 +1,29 @@ +/* PR rtl-optimization/87485 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fschedule-insns -fno-guess-branch-probability -fno-isolate-erroneous-paths-dereference -fno-omit-frame-pointer -fno-split-wide-types -fno-tree-ccp -fno-tree-sra" } */ +/* { dg-additional-options "-fstack-protector-strong" { target fstack_protector } } */ + +int *a; + +int +foo (__int128 x, int y, int z) +{ + __int128 b; + *a = ((!!y ? y : x) * y | x) * 2; + if (z == 0) + { + unsigned int c = 1; + __int128 *d = &b; + for (*a = 0; *a < 1; *a += y) + ; + *a += b < (c / 0); /* { dg-warning "division by zero" } */ + goto l; + m: + while (b < 1) + ; + ++*a; + } + goto m; + l: + return 0; +} Jakub