diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-24 14:37:02 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-24 14:37:02 +0000 |
commit | 60778e622858f194cee57d3dfa2a4e7b9915b3f4 (patch) | |
tree | 96c049e5b6aaaf1182db5e68e2f764aacc90ede6 | |
parent | 1ddf4bfd4e8523849c0357f0b3fc734459a90c64 (diff) | |
download | gcc-60778e622858f194cee57d3dfa2a4e7b9915b3f4.tar.gz |
PR middle-end/45234
* rtl.h (enum global_rtl_index): Add
GR_VIRTUAL_PREFERRED_STACK_BOUNDARY.
(LAST_VIRTUAL_POINTER_REGISTER): Define.
(virtual_preferred_stack_boundary_rtx,
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM): Define.
(LAST_VIRTUAL_REGISTER): Increase by one.
(REGNO_PTR_FRAME_P): Use LAST_VIRTUAL_POINTER_REGISTER
instead of LAST_VIRTUAL_REGISTER.
* function.c (instantiate_new_reg): Handle
virtual_preferred_stack_boundary_rtx.
* emit-rtl.c (init_virtual_regs): Handle
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM.
(init_emit_regs): Initialize virtual_preferred_stack_boundary_rtx.
* explow.c (round_push): If crtl->preferred_stack_boundary
is smaller than MAX_SUPPORTED_STACK_ALIGNMENT, use
virtual_preferred_stack_boundary_rtx alignment instead of
crtl->preferred_stack_boundary alignment.
(allocate_dynamic_stack_space): Use CONST_INT_P and REG_P
macros. Never decrease crtl->preferred_stack_boundary,
use crtl->preferred_stack_boundary or MAX_SUPPORTED_STACK_ALIGNMENT
instead of PREFERRED_STACK_BOUNDARY. Don't modify
stack_pointer_delta in dynamic allocation, even when size
is constant.
(probe_stack_range, anti_adjust_stack_and_probe): Use CONST_INT_P
macro.
* print-rtl.c (print_rtx): Handle
VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM.
* config/alpha/alpha.h (NONSTRICT_REG_OK_FP_BASE_P): Use
LAST_VIRTUAL_POINTER_REGISTER instead of LAST_VIRTUAL_REGISTER.
* config/frv/frv.c (frv_emit_movsi): Likewise.
* config/arm/arm.c (thumb1_legitimate_address_p): Likewise.
* config/rs6000/rs6000.c (virtual_stack_registers_memory_p):
Likewise.
* gcc.dg/torture/stackalign/alloca-6.c: New test.
* gcc.target/i386/pr45234.c: New test.
Revert:
2010-09-17 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/45234
* calls.c (expand_call): Make sure that all variable sized
adjustments are multiple of preferred stack boundary after
stack alignment.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164593 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 45 | ||||
-rw-r--r-- | gcc/calls.c | 13 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 2 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 3 | ||||
-rw-r--r-- | gcc/config/frv/frv.c | 2 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 2 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 4 | ||||
-rw-r--r-- | gcc/explow.c | 77 | ||||
-rw-r--r-- | gcc/function.c | 5 | ||||
-rw-r--r-- | gcc/print-rtl.c | 3 | ||||
-rw-r--r-- | gcc/rtl.h | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/stackalign/alloca-6.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr45234.c | 18 |
14 files changed, 185 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f024889c46..e957d02a335 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,48 @@ +2010-09-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/45234 + * rtl.h (enum global_rtl_index): Add + GR_VIRTUAL_PREFERRED_STACK_BOUNDARY. + (LAST_VIRTUAL_POINTER_REGISTER): Define. + (virtual_preferred_stack_boundary_rtx, + VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM): Define. + (LAST_VIRTUAL_REGISTER): Increase by one. + (REGNO_PTR_FRAME_P): Use LAST_VIRTUAL_POINTER_REGISTER + instead of LAST_VIRTUAL_REGISTER. + * function.c (instantiate_new_reg): Handle + virtual_preferred_stack_boundary_rtx. + * emit-rtl.c (init_virtual_regs): Handle + VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM. + (init_emit_regs): Initialize virtual_preferred_stack_boundary_rtx. + * explow.c (round_push): If crtl->preferred_stack_boundary + is smaller than MAX_SUPPORTED_STACK_ALIGNMENT, use + virtual_preferred_stack_boundary_rtx alignment instead of + crtl->preferred_stack_boundary alignment. + (allocate_dynamic_stack_space): Use CONST_INT_P and REG_P + macros. Never decrease crtl->preferred_stack_boundary, + use crtl->preferred_stack_boundary or MAX_SUPPORTED_STACK_ALIGNMENT + instead of PREFERRED_STACK_BOUNDARY. Don't modify + stack_pointer_delta in dynamic allocation, even when size + is constant. + (probe_stack_range, anti_adjust_stack_and_probe): Use CONST_INT_P + macro. + * print-rtl.c (print_rtx): Handle + VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM. + * config/alpha/alpha.h (NONSTRICT_REG_OK_FP_BASE_P): Use + LAST_VIRTUAL_POINTER_REGISTER instead of LAST_VIRTUAL_REGISTER. + * config/frv/frv.c (frv_emit_movsi): Likewise. + * config/arm/arm.c (thumb1_legitimate_address_p): Likewise. + * config/rs6000/rs6000.c (virtual_stack_registers_memory_p): + Likewise. + + Revert: + 2010-09-17 H.J. Lu <hongjiu.lu@intel.com> + + PR middle-end/45234 + * calls.c (expand_call): Make sure that all variable sized + adjustments are multiple of preferred stack boundary after + stack alignment. + 2010-09-24 Iain Sandoe <iains@gcc.gnu.org> Dominique Dhumieres <dominiq@lps.ens.fr> diff --git a/gcc/calls.c b/gcc/calls.c index b3109cee8d2..388883137be 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2385,19 +2385,6 @@ expand_call (tree exp, rtx target, int ignore) preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT; - if (SUPPORTS_STACK_ALIGNMENT) - { - /* All variable sized adjustments must be multiple of preferred - stack boundary. Stack alignment may change preferred stack - boundary after variable sized adjustments have been made. We - need to compensate it here. */ - unsigned HOST_WIDE_INT delta - = ((stack_pointer_delta - pending_stack_adjust) - % preferred_unit_stack_boundary); - if (delta) - anti_adjust_stack (GEN_INT (preferred_unit_stack_boundary - delta)); - } - /* We want to make two insn chains; one for a sibling call, the other for a normal call. We will select one of the two chains after initial RTL generation is complete. */ diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index f0d8b9dba4d..be885c1235d 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -916,7 +916,7 @@ extern int alpha_memory_latency; #define NONSTRICT_REG_OK_FP_BASE_P(X) \ (REGNO (X) == 31 || REGNO (X) == 63 \ || (REGNO (X) >= FIRST_PSEUDO_REGISTER \ - && REGNO (X) < LAST_VIRTUAL_REGISTER)) + && REGNO (X) < LAST_VIRTUAL_POINTER_REGISTER)) /* Nonzero if X is a hard reg that can be used as a base reg. */ #define STRICT_REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 782bc985a1e..44cbc8e1353 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -5855,7 +5855,8 @@ thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) && (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM || REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM || (REGNO (XEXP (x, 0)) >= FIRST_VIRTUAL_REGISTER - && REGNO (XEXP (x, 0)) <= LAST_VIRTUAL_REGISTER)) + && REGNO (XEXP (x, 0)) + <= LAST_VIRTUAL_POINTER_REGISTER)) && GET_MODE_SIZE (mode) >= 4 && GET_CODE (XEXP (x, 1)) == CONST_INT && (INTVAL (XEXP (x, 1)) & 3) == 0) diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c index 0730e32d9a4..42d0b1d9d0e 100644 --- a/gcc/config/frv/frv.c +++ b/gcc/config/frv/frv.c @@ -4067,7 +4067,7 @@ frv_emit_movsi (rtx dest, rtx src) || (GET_CODE (src) == REG && IN_RANGE_P (REGNO (src), FIRST_VIRTUAL_REGISTER, - LAST_VIRTUAL_REGISTER)))) + LAST_VIRTUAL_POINTER_REGISTER)))) { emit_insn (gen_rtx_SET (VOIDmode, dest, copy_to_mode_reg (SImode, src))); return TRUE; diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 55cb92fa4ad..5a3e333ffbe 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5489,7 +5489,7 @@ virtual_stack_registers_memory_p (rtx op) return false; return (regnum >= FIRST_VIRTUAL_REGISTER - && regnum <= LAST_VIRTUAL_REGISTER); + && regnum <= LAST_VIRTUAL_POINTER_REGISTER); } static bool diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index e0e1550948f..35a4360c973 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -5376,6 +5376,8 @@ init_virtual_regs (void) regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx; regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx; regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx; + regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM] + = virtual_preferred_stack_boundary_rtx; } @@ -5698,6 +5700,8 @@ init_emit_regs (void) virtual_outgoing_args_rtx = gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM); virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM); + virtual_preferred_stack_boundary_rtx = + gen_raw_REG (Pmode, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM); /* Initialize RTL for commonly used hard registers. These are copied into regno_reg_rtx as we begin to compile each function. */ diff --git a/gcc/explow.c b/gcc/explow.c index 74f52279e54..2024b5324d8 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -915,30 +915,47 @@ anti_adjust_stack (rtx adjust) static rtx round_push (rtx size) { - int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + rtx align_rtx, alignm1_rtx; - if (align == 1) - return size; - - if (CONST_INT_P (size)) + if (!SUPPORTS_STACK_ALIGNMENT + || crtl->preferred_stack_boundary == MAX_SUPPORTED_STACK_ALIGNMENT) { - HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align; + int align = crtl->preferred_stack_boundary / BITS_PER_UNIT; + + if (align == 1) + return size; + + if (CONST_INT_P (size)) + { + HOST_WIDE_INT new_size = (INTVAL (size) + align - 1) / align * align; - if (INTVAL (size) != new_size) - size = GEN_INT (new_size); + if (INTVAL (size) != new_size) + size = GEN_INT (new_size); + return size; + } + + align_rtx = GEN_INT (align); + alignm1_rtx = GEN_INT (align - 1); } else { - /* CEIL_DIV_EXPR needs to worry about the addition overflowing, - but we know it can't. So add ourselves and then do - TRUNC_DIV_EXPR. */ - size = expand_binop (Pmode, add_optab, size, GEN_INT (align - 1), - NULL_RTX, 1, OPTAB_LIB_WIDEN); - size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, GEN_INT (align), - NULL_RTX, 1); - size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1); + /* If crtl->preferred_stack_boundary might still grow, use + virtual_preferred_stack_boundary_rtx instead. This will be + substituted by the right value in vregs pass and optimized + during combine. */ + align_rtx = virtual_preferred_stack_boundary_rtx; + alignm1_rtx = force_operand (plus_constant (align_rtx, -1), NULL_RTX); } + /* CEIL_DIV_EXPR needs to worry about the addition overflowing, + but we know it can't. So add ourselves and then do + TRUNC_DIV_EXPR. */ + size = expand_binop (Pmode, add_optab, size, alignm1_rtx, + NULL_RTX, 1, OPTAB_LIB_WIDEN); + size = expand_divmod (0, TRUNC_DIV_EXPR, Pmode, size, align_rtx, + NULL_RTX, 1); + size = expand_mult (Pmode, size, align_rtx, NULL_RTX, 1); + return size; } @@ -1144,9 +1161,9 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, introduced later by the various alignment operations. */ if (flag_stack_usage) { - if (GET_CODE (size) == CONST_INT) + if (CONST_INT_P (size)) stack_usage_size = INTVAL (size); - else if (GET_CODE (size) == REG) + else if (REG_P (size)) { /* Look into the last emitted insn and see if we can deduce something for the register. */ @@ -1154,10 +1171,10 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, insn = get_last_insn (); if ((set = single_set (insn)) && rtx_equal_p (SET_DEST (set), size)) { - if (GET_CODE (SET_SRC (set)) == CONST_INT) + if (CONST_INT_P (SET_SRC (set))) stack_usage_size = INTVAL (SET_SRC (set)); else if ((note = find_reg_equal_equiv_note (insn)) - && GET_CODE (XEXP (note, 0)) == CONST_INT) + && CONST_INT_P (XEXP (note, 0))) stack_usage_size = INTVAL (XEXP (note, 0)); } } @@ -1177,7 +1194,8 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, /* We can't attempt to minimize alignment necessary, because we don't know the final value of preferred_stack_boundary yet while executing this code. */ - crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; + if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY) + crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY; /* We will need to ensure that the address we return is aligned to BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't @@ -1195,7 +1213,7 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, #if defined (STACK_DYNAMIC_OFFSET) || defined (STACK_POINTER_OFFSET) #define MUST_ALIGN 1 #else -#define MUST_ALIGN (PREFERRED_STACK_BOUNDARY < BIGGEST_ALIGNMENT) +#define MUST_ALIGN (crtl->preferred_stack_boundary < BIGGEST_ALIGNMENT) #endif if (MUST_ALIGN) @@ -1255,13 +1273,13 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, insns. Since this is an extremely rare event, we have no reliable way of knowing which systems have this problem. So we avoid even momentarily mis-aligning the stack. */ - if (!known_align_valid || known_align % PREFERRED_STACK_BOUNDARY != 0) + if (!known_align_valid || known_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0) { size = round_push (size); if (flag_stack_usage) { - int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + int align = crtl->preferred_stack_boundary / BITS_PER_UNIT; stack_usage_size = (stack_usage_size + align - 1) / align * align; } } @@ -1328,6 +1346,8 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, else #endif { + int saved_stack_pointer_delta; + #ifndef STACK_GROWS_DOWNWARD emit_move_insn (target, virtual_stack_dynamic_rtx); #endif @@ -1358,10 +1378,15 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align, emit_label (space_available); } + saved_stack_pointer_delta = stack_pointer_delta; if (flag_stack_check && STACK_CHECK_MOVING_SP) anti_adjust_stack_and_probe (size, false); else anti_adjust_stack (size); + /* Even if size is constant, don't modify stack_pointer_delta. + The constant size alloca should preserve + crtl->preferred_stack_boundary alignment. */ + stack_pointer_delta = saved_stack_pointer_delta; #ifdef STACK_GROWS_DOWNWARD emit_move_insn (target, virtual_stack_dynamic_rtx); @@ -1572,7 +1597,7 @@ probe_stack_range (HOST_WIDE_INT first, rtx size) { rtx addr; - if (GET_CODE (temp) == CONST_INT) + if (CONST_INT_P (temp)) { /* Use [base + disp} addressing mode if supported. */ HOST_WIDE_INT offset = INTVAL (temp); @@ -1613,7 +1638,7 @@ anti_adjust_stack_and_probe (rtx size, bool adjust_back) /* If we have a constant small number of probes to generate, that's the easy case. */ - if (GET_CODE (size) == CONST_INT && INTVAL (size) < 7 * PROBE_INTERVAL) + if (CONST_INT_P (size) && INTVAL (size) < 7 * PROBE_INTERVAL) { HOST_WIDE_INT isize = INTVAL (size), i; bool first_probe = true; diff --git a/gcc/function.c b/gcc/function.c index fac8b75f3d9..a11f248dc35 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1405,6 +1405,11 @@ instantiate_new_reg (rtx x, HOST_WIDE_INT *poffset) #endif offset = cfa_offset; } + else if (x == virtual_preferred_stack_boundary_rtx) + { + new_rtx = GEN_INT (crtl->preferred_stack_boundary / BITS_PER_UNIT); + offset = 0; + } else return NULL_RTX; diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index ec7e35883a8..2a6a19846c9 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -457,6 +457,9 @@ print_rtx (const_rtx in_rtx) fprintf (outfile, " %d virtual-outgoing-args", value); else if (value == VIRTUAL_CFA_REGNUM) fprintf (outfile, " %d virtual-cfa", value); + else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM) + fprintf (outfile, " %d virtual-preferred-stack-boundary", + value); else fprintf (outfile, " %d virtual-reg-%d", value, value-FIRST_VIRTUAL_REGISTER); diff --git a/gcc/rtl.h b/gcc/rtl.h index f490a0c29e3..24a735ffa51 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2010,6 +2010,7 @@ enum global_rtl_index GR_VIRTUAL_STACK_DYNAMIC, GR_VIRTUAL_OUTGOING_ARGS, GR_VIRTUAL_CFA, + GR_VIRTUAL_PREFERRED_STACK_BOUNDARY, GR_MAX }; @@ -2157,7 +2158,18 @@ extern rtx gen_rtx_MEM (enum machine_mode, rtx); #define VIRTUAL_CFA_REGNUM ((FIRST_VIRTUAL_REGISTER) + 4) -#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4) +#define LAST_VIRTUAL_POINTER_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4) + +/* This is replaced by crtl->preferred_stack_boundary / BITS_PER_UNIT + when finalized. */ + +#define virtual_preferred_stack_boundary_rtx \ + (global_rtl[GR_VIRTUAL_PREFERRED_STACK_BOUNDARY]) + +#define VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM \ + ((FIRST_VIRTUAL_REGISTER) + 5) + +#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 5) /* Nonzero if REGNUM is a pointer into the stack frame. */ #define REGNO_PTR_FRAME_P(REGNUM) \ @@ -2166,7 +2178,7 @@ extern rtx gen_rtx_MEM (enum machine_mode, rtx); || (REGNUM) == HARD_FRAME_POINTER_REGNUM \ || (REGNUM) == ARG_POINTER_REGNUM \ || ((REGNUM) >= FIRST_VIRTUAL_REGISTER \ - && (REGNUM) <= LAST_VIRTUAL_REGISTER)) + && (REGNUM) <= LAST_VIRTUAL_POINTER_REGISTER)) /* REGNUM never really appearing in the INSN stream. */ #define INVALID_REGNUM (~(unsigned int) 0) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea031cc2571..1917147d79d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-09-24 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/45234 + * gcc.dg/torture/stackalign/alloca-6.c: New test. + * gcc.target/i386/pr45234.c: New test. + 2010-09-24 Richard Guenther <rguenther@suse.de> * gcc.dg/lto/20091006-2_0.c: Prune warnings. diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/alloca-6.c b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-6.c new file mode 100644 index 00000000000..f0e4513de0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/stackalign/alloca-6.c @@ -0,0 +1,34 @@ +/* PR middle-end/45234 */ +/* { dg-do run { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-mincoming-stack-boundary=2 -mpreferred-stack-boundary=2" } */ + +#include "check.h" + +void +__attribute__ ((noinline)) +bar (__float128 f) +{ + check (&f, __alignof__(f)); +} + +volatile int z = 6; + +int +main (void) +{ + char *p = __builtin_alloca (z); + + bar (0); + + __builtin_strncpy (p, "good", 5); + if (__builtin_strncmp (p, "good", 5) != 0) + { +#ifdef DEBUG + p[z - 1] = '\0'; + printf ("Failed: %s != good\n", p); +#endif + abort (); + } + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr45234.c b/gcc/testsuite/gcc.target/i386/pr45234.c new file mode 100644 index 00000000000..b11096b65e2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr45234.c @@ -0,0 +1,18 @@ +/* PR middle-end/45234 */ +/* { dg-do compile } */ +/* { dg-options "-march=i586" { target ilp32 } } */ + +struct S { union { double b[4]; } a[18]; } s, a[5]; +void foo (struct S); +struct S bar (struct S, struct S *, struct S); + +void +foo (struct S arg) +{ +} + +void +baz (void) +{ + foo (bar (s, &a[1], a[2])); +} |