Bug 38245 - [4.4 Regression] stack corruption when a call is removed but not the outgoing argument pushes
Summary: [4.4 Regression] stack corruption when a call is removed but not the outgoing...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.4.0
: P1 normal
Target Milestone: 4.4.0
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
: 38364 (view as bug list)
Depends on:
Blocks:
 
Reported: 2008-11-24 04:08 UTC by John Regehr
Modified: 2009-01-15 08:15 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.2
Known to fail: 4.4.0
Last reconfirmed: 2008-12-18 16:55:52


Attachments
make all functions with nonzero crtl->outgoing_args_size non-leaf (465 bytes, patch)
2008-12-18 22:35 UTC, Steven Bosscher
Details | Diff
Make targets allocate outgoing args space if necessary (1.03 KB, patch)
2008-12-18 22:58 UTC, Steven Bosscher
Details | Diff
gcc44-pr38245.patch (1.16 KB, patch)
2008-12-19 14:37 UTC, Jakub Jelinek
Details | Diff
gcc44-pr38245.patch (1.77 KB, patch)
2009-01-12 16:18 UTC, Jakub Jelinek
Details | Diff
gcc44-pr38245.patch (4.98 KB, patch)
2009-01-13 15:37 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description John Regehr 2008-11-24 04:08:13 UTC
This is seen using r142142 on Ubuntu Hardy on x86.

I don't think anything in the source code justifies the segfault.

regehr@john-home:~/volatile/tmp66$ current-gcc -O2 small.c -o small
regehr@john-home:~/volatile/tmp66$ ./small
Segmentation fault
regehr@john-home:~/volatile/tmp66$ current-gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr : (reconfigured) ../configure --program-prefix=current- --enable-languages=c,c++ --prefix=/home/regehr
Thread model: posix
gcc version 4.4.0 20081123 (experimental) (GCC) 

regehr@john-home:~/volatile/tmp66$ cat small.c

#include <stdint.h>
#include <limits.h>

static inline int8_t

safe_sub_int8_t_s_s (int8_t si1, int8_t si2)
{
	if (((si1^si2)
		 & (((si1 ^ ((si1^si2)
					 & (1 << (sizeof(int8_t)*CHAR_BIT-1))))-si2)^si2)) < 0) {
		return si1;
	}
	return si1 - si2;
}

static inline int32_t
safe_div_int32_t_s_s (int32_t si1, int32_t si2)
{
	if ((si2 == 0) || ((si1 == INT_MIN) && (si2 == -1))) {
		return si1;
	}		
	return si1 / si2;
}			

static inline uint64_t	
safe_mod_uint64_t_u_u (uint64_t ui1, uint64_t ui2)
{					
	if (ui2 == 0) return ui1;	
	return ui1 % ui2;		
}					
				
uint8_t g_2;
volatile uint32_t g_9;

int32_t func_3 (void);
int32_t func_3 (void)
{
  return g_2;
}

void func_1 (void);
void func_1 (void)
{
  uint32_t l_10 = 0x084BL;
  if (safe_sub_int8_t_s_s
      ((safe_div_int32_t_s_s
	(0, (safe_mod_uint64_t_u_u (func_3 (), l_10)))), 1))
    {
    }
  else if (g_9)
    {
    }
}

int main (void)
{
  func_1 ();
  return 0;
}
Comment 1 Jakub Jelinek 2008-11-24 09:01:44 UTC
Smaller testcase:
static inline int
f1 (int si1, int si2)
{
  return si2 == 0 ? si1 : si1 / si2;
}

static inline unsigned long long
f2 (unsigned long long ui1, unsigned long long ui2)
{
  return ui1 % ui2;
}

unsigned char g;
volatile unsigned int h;

void
f3 (void)
{
  if (!((signed char) f1 (0, f2 (g, 2123)) - 1))
    h;
}

int
main (void)
{
  f3 ();
  return 0;
}

The problem seems to be that RTL DCE pass removes umoddi3 call:
(insn 8 6 34 2 u2.c:19 (set (mem:DI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S8 A32])
        (const_int 2123 [0x84b])) 88 {*movdi_2} (nil))

(insn 34 8 35 2 u2.c:19 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32])
        (reg:SI 61 [ g ])) 47 {*movsi_1} (expr_list:REG_DEAD (reg:SI 61 [ g ])
        (nil)))

(insn 35 34 10 2 u2.c:19 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 4 [0x4])) [0 S4 A32])
        (const_int 0 [0x0])) 47 {*movsi_1} (nil))

(call_insn/u 10 35 0 2 u2.c:19 (set (reg:DI 0 ax)
        (call (mem:QI (symbol_ref:SI ("__umoddi3") [flags 0x41]) [0 S1 A8])
            (const_int 16 [0x10]))) 902 {*call_value_0} (expr_list:REG_UNUSED (reg:SI 1 dx)
        (expr_list:REG_EH_REGION (const_int -1 [0xffffffffffffffff])
            (nil)))
    (expr_list:REG_DEP_TRUE (use (mem:DI (reg/f:SI 7 sp) [0 S8 A8]))
        (expr_list:REG_DEP_TRUE (use (mem:DI (plus:SI (reg/f:SI 7 sp)
                        (const_int 8 [0x8])) [0 S8 A8]))
            (nil))))

but doesn't remove the pushes of its arguments, and then ix86_compute_frame_layout doesn't allocate space for the outgoing arguments
as the function is leaf.

  /* Add outgoing arguments area.  Can be skipped if we eliminated
     all the function calls as dead code.
     Skipping is however impossible when function calls alloca.  Alloca
     expander assumes that last crtl->outgoing_args_size
     of stack frame are unused.  */
  if (ACCUMULATE_OUTGOING_ARGS
      && (!current_function_is_leaf || cfun->calls_alloca
          || ix86_current_function_calls_tls_descriptor))
    {
      offset += crtl->outgoing_args_size;
      frame->outgoing_arguments_size = crtl->outgoing_args_size;
    }
  else
    frame->outgoing_arguments_size = 0;

I guess this was caused by the removal of REG_LIBCALL notes.
Comment 2 Steven Bosscher 2008-11-28 11:23:58 UTC
There really is obvious way to remove the argument pushes without libcall notes.  There is nothing in the RTL to make clear that the pushes are dead when the call is removed, so they pushes stay.

There are several ways to "fix" this.

1. Make the call not pure (even if the function is technically pure).
IIRC the call pops the incoming arguments on return, which is clearly a non-pure side-effect. I am assuming it is acceptable that the call is not a candidate for DCE.  I think this is acceptable -- it's the consequence of removing libcall notes -- but OTOH I would like to understand *why* we end up with a DCE-able pure call in the first place, why it's not optimized away in the tree optimizations.
Of course, a call would only have to be non-pure if it takes arguments via the stack.  For targets with "proper" argument passing via registers ;) the call should still be pure.


2. Make it explicit in the IL that the pushes are inputs for the call.
For example, add EXPR_LISTs from the CALL_INSNs to the pushes of the outgoing args, and teach DCE to remove the insn in the EXPR_LIST when a CALL_INSN is removed.  Or resurrect REG_LIBCALL_ID (renamed REG_PURECALL_ID), teach DCE to keep a list of the REG_PURECALL_IDs for removed pure calls, and do a second pass to remove all (non-CALL_INSN) insns that have the REG_PURECALL_ID of a removed libcall.
This assumes that we can always remove the outgoing argument pushes if a pure call is removed.  I'm not sure if this is true (is it conceivable that we CSE things in such a way that other insns would depend on the argument pushes?).


Personally, I'm strongly in favor of option 1.
Comment 3 Eric Botcazou 2008-11-28 11:58:09 UTC
> Personally, I'm strongly in favor of option 1.

Personally, I'd strongly oppose option 2. :-)
Comment 4 Jakub Jelinek 2008-11-28 14:12:43 UTC
*.optimized dump is:
  D.1611 = (int) (long long unsigned int) g % 2123;
  if (D.1611 != 0)
    goto <bb 3>;
  else
    goto <bb 5>;

<bb 3>:
  if ((signed char) (0 / D.1611) == 1)
    goto <bb 4>;
  else
    goto <bb 5>;

<bb 4>:
  vol.2 ={v} h;

<bb 5>:
  return;

The problem is that fold_comparison doesn't fold EQ_EXPR (signed char) (0 / D.1611) with 1 (signed char type) into 0 / D.1611, false, nor anything else optimizes this at the tree level.  I guess e.g. VRP should be able to find this out.  Even when that is fixed (can look at it), I guess there still be possibilities that tree optimizers miss something that the RTL optimizers might DCE away (otherwise, why would we run RTL DCE at all?).

The call BTW doesn't pop any arguments on return.

I guess option 3 is remove this i386.c optimization, assume only very few calls will be DCEd at RTL level and count with the fact that their argument stores might not have been eliminated.  For x86_64 this wouldn't make a difference for
calls that pass args only in registers - the outgoing args size will be 0 in that case anyway.
Comment 5 Eric Botcazou 2008-11-28 15:59:44 UTC
> Even when that is fixed (can look at it), I guess there still be
> possibilities that tree optimizers miss something that the RTL optimizers
> might DCE away (otherwise, why would we run RTL DCE at all?).

My gut feeling is also that most dead calls are DCEd at the tree level nowadays
so we could decide to restrict RTL DCE to non-call insns.

> I guess option 3 is remove this i386.c optimization, assume only very few
> calls will be DCEd at RTL level and count with the fact that their argument
> stores might not have been eliminated.

Other back-ends may do something equivalent though.

I guess that option 4 is to investigate why DSE doesn't remove the dead stores.
Since there are no calls in the function anymore, this should be doable.
Comment 6 Jakub Jelinek 2008-12-01 14:36:31 UTC
Subject: Bug 38245

Author: jakub
Date: Mon Dec  1 14:34:51 2008
New Revision: 142317

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142317
Log:
	PR rtl-optimization/38245
	* tree-vrp.c (abs_extent_range): New function.
	(extract_range_from_binary_expr): Compute range
	for *_DIV_EXPR even if vr1 is VR_VARYING, VR_ANTI_RANGE
	or includes zero or if vr1 is VR_RANGE and op0 has some
	other range.

	* gcc.dg/pr38245-1.c: New test.
	* gcc.dg/pr38245-2.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr38245-1.c
    trunk/gcc/testsuite/gcc.dg/pr38245-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-vrp.c

Comment 7 Jakub Jelinek 2008-12-02 17:46:35 UTC
*** Bug 38364 has been marked as a duplicate of this bug. ***
Comment 8 Jakub Jelinek 2008-12-02 17:50:27 UTC
"I guess that option 4 is to investigate why DSE doesn't remove the dead stores."
1) DCE which removes this is done after DSE2
2) DSE doesn't remove sp based stores, except for spill slots (there is a PR
about it, but isn't going to be fixed any time soon).
Comment 9 Eric Botcazou 2008-12-05 10:28:01 UTC
> "I guess that option 4 is to investigate why DSE doesn't remove the dead
> stores."
> 1) DCE which removes this is done after DSE2

Bummer.

> 2) DSE doesn't remove sp based stores, except for spill slots (there is a PR
> about it, but isn't going to be fixed any time soon).

Right, I remember now. :-)

I'll try to come up with something.
Comment 10 Jakub Jelinek 2008-12-05 11:07:35 UTC
I guess for !ACCUMULATE_OUTGOING_ARGS DCE of calls having stack arguments generally shouldn't be an issue (unless they pop the stack themselves, don't remember if it is easily determinable in generic way), worst case where will be some pushes and some pops or stack additions left around.
For ACCUMULATE_OUTGOING_ARGS you could use:
    (expr_list:REG_DEP_TRUE (use (mem:SI (reg/f:SI 7 sp) [0 S4 A8]))
        (expr_list:REG_DEP_TRUE (use (mem:SI (plus:SI (reg/f:SI 7 sp)
                        (const_int 4 [0x4])) [0 S4 A8]))
            (nil))))
from the CALL_INSN, just see if you can find safely and remove also the stores
to those stack locations, if yes, remove them together with the call, if not,
don't DCE the call either.
Comment 11 Eric Botcazou 2008-12-11 23:03:46 UTC
> I guess for !ACCUMULATE_OUTGOING_ARGS DCE of calls having stack arguments
> generally shouldn't be an issue (unless they pop the stack themselves, don't
> remember if it is easily determinable in generic way), worst case where will
> be some pushes and some pops or stack additions left around.
> For ACCUMULATE_OUTGOING_ARGS you could use:
>     (expr_list:REG_DEP_TRUE (use (mem:SI (reg/f:SI 7 sp) [0 S4 A8]))
>         (expr_list:REG_DEP_TRUE (use (mem:SI (plus:SI (reg/f:SI 7 sp)
>                         (const_int 4 [0x4])) [0 S4 A8]))
>             (nil))))
> from the CALL_INSN, just see if you can find safely and remove also the
> stores to those stack locations, if yes, remove them together with the
> call, if not, don't DCE the call either.

This seems reasonable to me.

Because of more urgent issues suddenly popping up in a row, I haven't had time
to seriously work on this and probably won't have before next year.  Sorry.
Comment 12 Steven Bosscher 2008-12-18 16:55:52 UTC
Let me try, I'm kinda sorta responsible for this bug in a way, you know...
Comment 13 Steven Bosscher 2008-12-18 21:19:08 UTC
Jakub's idea of comment #10 is nice conceptually, but it's a bit complicated in practice for most cases where a libcall is emitted.  Before subreg lowering we have this:

(insn 8 7 9 2 t.c:19 (set (mem:DI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S8 A32])
        (const_int 2123 [0x84b])) 63 {*movdi_2} (nil))

(insn 9 8 10 2 t.c:19 (set (mem:DI (reg/f:SI 7 sp) [0 S8 A32])
        (reg:DI 60)) 63 {*movdi_2} (nil))

(call_insn/u 10 9 11 2 t.c:19 (set (reg:DI 0 ax)
        (call (mem:QI (symbol_ref:SI ("__umoddi3") [flags 0x43]) [0 S1 A8])
            (const_int 16 [0x10]))) 676 {*call_value_0} (expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
        (nil))
    (expr_list:REG_DEP_TRUE (use (mem:DI (reg/f:SI 7 sp) [0 S8 A8]))
        (expr_list:REG_DEP_TRUE (use (mem:DI (plus:SI (reg/f:SI 7 sp)
                        (const_int 8 [0x8])) [0 S8 A8]))
            (nil))))


But after subreg lowering (and some more, fwprop dump shown) we have split the DImode store of g into two separate stores, without updating the REG_DEP notes in the CALL_INSN:

(insn 8 33 34 2 t.c:19 (set (mem:DI (plus:SI (reg/f:SI 7 sp)
                (const_int 8 [0x8])) [0 S8 A32])
        (const_int 2123 [0x84b])) 63 {*movdi_2} (nil))

(insn 34 8 35 2 t.c:19 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32])
        (reg:SI 61 [ g ])) 41 {*movsi_1} (nil))

(insn 35 34 10 2 t.c:19 (set (mem:SI (plus:SI (reg/f:SI 7 sp)
                (const_int 4 [0x4])) [0 S4 A32])
        (const_int 0 [0x0])) 41 {*movsi_1} (nil))

(call_insn/u 10 35 36 2 t.c:19 (set (reg:DI 0 ax)
        (call (mem:QI (symbol_ref:SI ("__umoddi3") [flags 0x43]) [0 S1 A8])
            (const_int 16 [0x10]))) 676 {*call_value_0} (expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
        (nil))
    (expr_list:REG_DEP_TRUE (use (mem:DI (reg/f:SI 7 sp) [0 S8 A8]))
        (expr_list:REG_DEP_TRUE (use (mem:DI (plus:SI (reg/f:SI 7 sp)
                        (const_int 8 [0x8])) [0 S8 A8]))
            (nil))))

Most "interesting" libcalls for x86 -m32 probably are the DImode ones, and if subreg lowering does this for all arguments, we would have to update the REG_REP notes in the CALL_INSN, or do a lot of DSE-like work...
Comment 14 Steven Bosscher 2008-12-18 22:35:56 UTC
Created attachment 16939 [details]
make all functions with nonzero crtl->outgoing_args_size non-leaf

The result of this patch is that DCE of dead const/pure calls still happens, but the argument pushes will stay around.  Removing the pushes too is just hard and not really worth it.

A nice-to-have would be some mechanism to detect this situation where we remove a call but not the pushes, because it probably will be the result of a missed optimization on GIMPLE...
Comment 15 Steven Bosscher 2008-12-18 22:58:04 UTC
Created attachment 16940 [details]
Make targets allocate outgoing args space if necessary

Alternative approach is to let all targets check if crtl->outgoing_args_size is nonzero, instead of assuming so when the function is leaf.
Comment 16 Jakub Jelinek 2008-12-19 09:50:53 UTC
Given the sorry state of tree DSE (what we have is a joke), it is actually trivial to come up with testcases for arbitrary pure/const call elimination
during RTL DCE.  E.g.
/* PR rtl-optimization/38245 */
/* { dg-do run } */
/* { dg-options "-O2" } */

extern int bar (long, long, long, long, long, long, long, long,
long, long, long, long, long, long, long, long)
     __attribute__((pure));

struct A { int i, j; union { short s[4]; long long l; }; char pad[512]; } a;

void __attribute__((noinline))
foo (void)
{
  a.s[2] = bar (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21);
  a.l = 6;
}

int
main (void)
{
  foo ();
  return 0;
}

This segfaults on i386-linux, x86_64-linux, powerpc64-linux (-m64 only, -m32 is fine), haven't tried other targets.  For ia64-linux and other targets where return ip is passed in a register I think we'd want to call foo from some function that has some stuff on the stack and checks that it hasn't been modified by the foo call.
Comment 17 Jakub Jelinek 2008-12-19 10:41:55 UTC
Better testcase:
/* PR rtl-optimization/38245 */
/* { dg-do run } */
/* { dg-options "-O2" } */

extern int bar (long, long, long, long, long, long, long, long,
                long, long, long, long, long, long, long, long,
                long, long, long, long, long, long, long, long,
                long, long, long, long, long, long, long, long)
     __attribute__((pure));

struct A { int i, j; union { short s[4]; long long l; }; char pad[512]; } a;

void __attribute__((noinline))
foo (void)
{
  a.s[2] = bar (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21);
  a.l = 6;
}

int
main (void)
{
  char buf[256];
  int i;
  for (i = 0; i < (int) sizeof buf; i++)
    buf[i] = i;
  asm volatile ("" : : "r" (buf) : "memory");
  foo ();
  asm volatile ("" : : "r" (buf) : "memory");
  for (i = 0; i < (int) sizeof buf; i++)
    if (buf[i] != (char) i)
      __builtin_abort ();
  return 0;
}

BTW, e.g. on powerpc64-linux or ia64-linux the stack arguments aren't in CALL_INSN_FUNCTION_USAGE at all, only the register arguments.
Comment 18 Jakub Jelinek 2008-12-19 14:37:40 UTC
Created attachment 16944 [details]
gcc44-pr38245.patch

On x86_64 some more work is needed, because in leaf functions parts of the
outgoing_args_size space might be in red-zone, and as all the left-over stack pushes are from %rsp upwards, that still clobbers the return pointer.
Perhaps we might in that case just make the red-zone smaller to make sure all of the outgoing_args_size are is above the red zone.

This patch also fixes powerpc64, though in that case (or for msabi on x86_64 too) if we eliminate a call that has arguments solely in registers, still outgoing_args_size area is allocated.

I guess we might want to track the size of outgoing args we really pushed for some call, not considering OUTGOING_REG_PARM_STACK_SPACE, and remember it in a new crtl-> field.
Comment 19 Steven Bosscher 2008-12-20 09:56:05 UTC
Fixing all targets is beyond my hacking skills.
Comment 20 Eric Botcazou 2009-01-07 06:34:07 UTC
> Most "interesting" libcalls for x86 -m32 probably are the DImode ones, and if
> subreg lowering does this for all arguments, we would have to update the
> REG_REP notes in the CALL_INSN, or do a lot of DSE-like work...

What about canonicalizing the modes in CALL_INSN_FUNCTION_USAGE to word mode
or smaller, like for hard registers?  Would this make the DSE-like work more
or less trivial?
Comment 21 Jakub Jelinek 2009-01-12 16:18:52 UTC
Created attachment 17078 [details]
gcc44-pr38245.patch

Patch I'm playing with.  I don't see why changing CALL_INSN_FUNCTION_USAGE
to have only at most word sized stores would simplify it much.  The patch
is still overly conservative, on the other side some stack arguments (e.g. large struct by value) still aren't added to CALL_INSN_FUNCTION_USAGE.
If such an argument is first or last, this patch still won't catch it.
Comment 22 Jakub Jelinek 2009-01-13 15:37:25 UTC
Created attachment 17086 [details]
gcc44-pr38245.patch

Updated patch (tested with the new testcase on i386/x86_64 and eyeballed
for ppc{,64}, sparc{32,64}, ia64.
Comment 23 Jakub Jelinek 2009-01-15 08:07:52 UTC
Subject: Bug 38245

Author: jakub
Date: Thu Jan 15 08:07:38 2009
New Revision: 143387

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143387
Log:
	PR rtl-optimization/38245
	* calls.c (expand_call): Add stack arguments to
	CALL_INSN_FUNCTION_USAGE even for pure calls (when
	ACCUMULATE_OUTGOING_ARGS) and even for args partially passed
	in regs and partially in memory or BLKmode arguments.
	(emit_library_call_value_1): Add stack arguments to
	CALL_INSN_FUNCTION_USAGE even for pure calls (when
	ACCUMULATE_OUTGOING_ARGS).
	* dce.c: Include tm_p.h.
	(find_call_stack_args): New function.
	(deletable_insn_p): Call it for CALL_P insns.  Add ARG_STORES
	argument.
	(mark_insn): Call find_call_stack_args for CALL_Ps.
	(prescan_insns_for_dce): Walk insns backwards in bb rather than
	forwards.  Allocate and free arg_stores bitmap if needed, pass it
	down to deletable_insn_p, don't mark stores set in arg_stores
	bitmap, clear the bitmap at the beginning of each bb.
	* Makefile.in (dce.o): Depend on $(TM_P_H).

	* gcc.dg/pr38245-3.c: New test.
	* gcc.dg/pr38245-3.h: New file.
	* gcc.dg/pr38245-4.c: New file.
	* gcc.dg/pr38364.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr38245-3.c
    trunk/gcc/testsuite/gcc.dg/pr38245-3.h
    trunk/gcc/testsuite/gcc.dg/pr38245-4.c
    trunk/gcc/testsuite/gcc.dg/pr38364.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/Makefile.in
    trunk/gcc/calls.c
    trunk/gcc/dce.c
    trunk/gcc/testsuite/ChangeLog

Comment 24 Jakub Jelinek 2009-01-15 08:15:58 UTC
Fixed.
Comment 25 hjl@gcc.gnu.org 2009-01-30 22:36:38 UTC
Subject: Bug 38245

Author: hjl
Date: Fri Jan 30 22:36:22 2009
New Revision: 143810

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=143810
Log:
2009-01-30  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline:
	2009-01-14  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/38245
	* gcc.dg/pr38245-3.c: New test.
	* gcc.dg/pr38245-3.h: New file.
	* gcc.dg/pr38245-4.c: New file.
	* gcc.dg/pr38364.c: New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr38245-3.c
      - copied unchanged from r143809, trunk/gcc/testsuite/gcc.dg/pr38245-3.c
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr38245-3.h
      - copied unchanged from r143809, trunk/gcc/testsuite/gcc.dg/pr38245-3.h
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr38245-4.c
      - copied unchanged from r143809, trunk/gcc/testsuite/gcc.dg/pr38245-4.c
    branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/pr38364.c
      - copied unchanged from r143809, trunk/gcc/testsuite/gcc.dg/pr38364.c
Modified:
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog