For a function call having structs as arguments, rtl may be generated containing call_insns to memcpy to copy the struct to the argument area of the caller's stack frame, as well as insns for saving and restoring the argument area across subsequent calls to memcpy. When -O3 is in effect, emit_libcall_block may be invoked on this string of insns when the called function's ECF_LIBCALL_BLOCK is set. emit_libcall_block may then inappropriately re-order some of the argument-area-save insns before the memcpy call_insn that moves the argument into the argument area. Problem may be recreated using gcc/gcc/testsuite/gcc.c-torture/execute/20000412-3.c: typedef struct { char y; char x[32]; } X; int z (void) { X xxx; xxx.x[0] = xxx.x[31] = '0'; xxx.y = 0xf; return f (xxx, xxx); } int main (void) { int val; val = z (); if (val != 0x60) abort (); exit (0); } int f(X x, X y) { if (x.y != y.y) return 'F'; return x.x[0] + y.x[0]; return 0; } Here is an extract from the generated rtl showing the incorrectly ordered insns (31, 33, 35, and 37) generated for the call to f() in z(): (011a0570:insn 19 18 20 (011a40c0:set (011a40b0:reg:SI 123) (011461b0:reg/f:SI 116 virtual-outgoing-args)) -1 (nil) (nil)) (011a05a0:insn 20 19 21 (011a41d0:set (011a41c0:reg:SI 124) (011a40b0:reg:SI 123)) -1 (nil) (nil)) (011a05d0:insn 21 20 22 (011a4200:set (011a41e0:reg:SI 125) (011a41f0:plus:SI (01146190:reg/f:SI 114 virtual-stack-vars) (01148250:const_int 8 [0x8]))) -1 (nil) (nil)) (011a0600:insn 22 21 28 (011a4220:set (011a4210:reg:SI 126) (01148318:const_int 33 [0x21])) -1 (nil) (nil)) (011a0780:insn 28 22 29 (011a4400:set (011a43e0:reg:SI 128) (011a43f0:plus:SI (011a40b0:reg:SI 123) (01148330:const_int 36 [0x24]))) -1 (nil) (nil)) (011a07b0:insn 29 28 30 (011a4430:set (011a4410:reg:SI 129) (011a4420:plus:SI (01146190:reg/f:SI 114 virtual-stack-vars) (01148250:const_int 8 [0x8]))) -1 (nil) (nil)) (011a07e0:insn 30 29 31 (011a4450:set (011a4440:reg:SI 130) (01148318:const_int 33 [0x21])) -1 (nil) (nil)) (011a0840:insn 31 30 33 (011a4580:set (011a4560:reg:SI 131) (011a4530:mem:SI (011461b0:reg/f:SI 116 virtual-outgoing-args) [0 S4 A32])) -1 (nil) (nil)) (011a08a0:insn 33 31 35 (011a4600:set (011a45f0:reg:SI 132) (011a45b0:mem:SI (011a45a0:plus:SI (011461b0:reg/f:SI 116 virtual-outgoing-args) (01148230:const_int 4 [0x4])) [0 S4 A32])) -1 (nil) (nil)) (011a0900:insn 35 33 37 (011a4680:set (011a4670:reg:SI 133) (011a4630:mem:SI (011a4620:plus:SI (011461b0:reg/f:SI 116 virtual-outgoing-args) (01148250:const_int 8 [0x8])) [0 S4 A32])) -1 (nil) (nil)) (011a0960:insn 37 35 23 (011a4700:set (011a46f0:reg:SI 134) (011a46b0:mem:SI (011a46a0:plus:SI (011461b0:reg/f:SI 116 virtual-outgoing-args) (01148270:const_int 12 [0xc])) [0 S4 A32])) -1 (nil) (nil)) (011a0630:insn 23 37 24 (011a42b0:set (011a4260:reg:SI 3 r3) (011a41c0:reg:SI 124)) -1 (nil) (011a71c0:insn_list:REG_LIBCALL 77 (nil))) (011a0660:insn 24 23 25 (011a42d0:set (011a4270:reg:SI 4 r4) (011a41e0:reg:SI 125)) -1 (nil) (nil)) (011a0690:insn 25 24 26 (011a42f0:set (011a4280:reg:SI 5 r5) (011a4210:reg:SI 126)) -1 (nil) (nil)) (011a0720:call_insn 26 25 27 (0116bfb8:parallel [ (011a4350:set (011a4290:reg:SI 3 r3) (011a4340:call (011a4330:mem:SI (011a4320:symbol_ref:SI ("&L_memcpy$stub")) [0 S4 A8]) (01148310:const_int 32 [0x20]))) (0116bfa0:use (01148210:const_int 0 [0x0])) (0116bfb0:clobber (0116bfa8:scratch:SI)) ]) -1 (nil) (011a4370:expr_list:REG_EH_REGION (01148208:const_int -1 [0xffffffff]) (nil)) (011a4300:expr_list (0116bf98:use (011a4280:reg:SI 5 r5)) (011a42e0:expr_list (0116bf90:use (011a4270:reg:SI 4 r4)) (011a42c0:expr_list (0116bf88:use (011a4260:reg:SI 3 r3)) (nil)))))
This has been failing since March 7 <http://gcc.gnu.org/ml/gcc-regression/2003-03/ msg00050.html>, there is a list of changes in this message that could be the cause of this regression.
This testcase never fails, do you know if affects other testcases?
I should have marked this one as fixed but I had asked for another testcase but the testcase in the testsuite is good enough to know when this fails.
Bugs back somehow. :(.
Fixed really by: 2003-10-13 Geoffrey Keating <geoffk@apple.com> * expr.c (block_move_libcall_safe_for_call_parm): Clean up, and add case for machines where outgoing register parameters get stack space.