Bug 11202 - [3.4 regression] incorrectly ordered rtl after emit_libcall_block
Summary: [3.4 regression] incorrectly ordered rtl after emit_libcall_block
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.0
: P2 critical
Target Milestone: 3.4.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2003-06-16 01:50 UTC by Bob Abeles
Modified: 2004-01-17 04:22 UTC (History)
1 user (show)

See Also:
Host: powerpc-apple-darwin6.6
Target: powerpc-apple-darwin6.6
Build: powerpc-apple-darwin6.6
Known to work:
Known to fail:
Last reconfirmed: 2003-06-16 02:03:39


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bob Abeles 2003-06-16 01:50:12 UTC
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)))))
Comment 1 Andrew Pinski 2003-06-16 02:03:39 UTC
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.
Comment 2 Andrew Pinski 2003-07-20 03:15:21 UTC
This testcase never fails, do you know if affects other testcases?
Comment 3 Andrew Pinski 2003-08-12 21:23:08 UTC
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.
Comment 4 Andrew Pinski 2003-09-14 00:48:13 UTC
Bugs back somehow. :(.
Comment 5 Andrew Pinski 2003-10-14 16:13:35 UTC
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.