diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2008-11-20 22:11:22 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2008-11-20 22:11:22 +0100 |
commit | b52b558a25df4860b17f5e23a9597f20898b802e (patch) | |
tree | 77cac3ff38e705a37accc7751ca2e0508f38a754 /gcc | |
parent | 586125658af94e158c850dda1da26e6c889d5e57 (diff) | |
download | gcc-b52b558a25df4860b17f5e23a9597f20898b802e.zip gcc-b52b558a25df4860b17f5e23a9597f20898b802e.tar.gz gcc-b52b558a25df4860b17f5e23a9597f20898b802e.tar.bz2 |
re PR middle-end/38151 (structures with _Complex arguments are not passed correctly)
PR target/38151
* config/i386/i386.c (classify_argument) [integer mode size <= 64bit]:
Handle cases when integer argument crosses argument register boundary.
testsuite/ChangeLog:
PR target/38151
* gcc.target/i386/pr38151-1.c: New test.
From-SVN: r142059
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr38151-1.c | 29 |
4 files changed, 76 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af07c93..f63d37b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-11-20 Uros Bizjak <ubizjak@gmail.com> + + PR target/38151 + * config/i386/i386.c (classify_argument) [integer mode size <= 64bit]: + Handle cases when integer argument crosses argument register boundary. + 2008-11-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE> PR bootstrap/33100 @@ -18,10 +24,10 @@ PR rtl-optimization/32283 * tree-ssa-loop-niter.c (scev_probably_wraps_p): Use type of the base of the induction variable to decide whether it may wrap. - * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the initialization - of the bound before the loop. - * simplify-rtx.c (simplify_binary_operation_1): Add two simplifications - regarding AND. + * tree-ssa-loop-ivopts.c (rewrite_use_compare): Emit the + initialization of the bound before the loop. + * simplify-rtx.c (simplify_binary_operation_1): Add two + simplifications regarding AND. (simplify_plus_minus): Only fail if no simplification is possible. * loop-iv.c (simple_rhs_p): Consider reg + reg and reg << cst simple. @@ -73,8 +79,7 @@ * ira-conflicts.c (ira_allocno_live_ranges_intersect_p, ira_pseudo_live_ranges_intersect_p): Rename to allocnos_have_intersected_live_ranges_p and - pseudos_have_intersected_live_ranges_p. Move them from here to - ... + pseudos_have_intersected_live_ranges_p. Move them from here to ... * ira-color.c: ... here (coalesced_allocno_conflict_p): Use @@ -112,8 +117,7 @@ 2008-11-19 Richard Guenther <rguenther@suse.de> * tree.c (build2_stat): Allow non-POINTER_PLUS_EXPRs with - non-sizetype offsets if their precision matches that of - the pointer. + non-sizetype offsets if their precision matches that of the pointer. * expr.c (expand_expr_real_1): Always sign-extend the offset operand of a POINTER_PLUS_EXPR. @@ -134,8 +138,8 @@ 2008-11-19 Razya Ladelsky <razya@il.ibm.com> - PR target/38156 - * tree-parloops.c (loop_parallel_p): NULL vect_dump. + PR target/38156 + * tree-parloops.c (loop_parallel_p): NULL vect_dump. (separate_decls_in_region): Create shared struct even when there are only reductions. @@ -272,7 +276,7 @@ 2008-11-16 Eric Botcazou <ebotcazou@adacore.com> * config/sparc/sparc.c (function_arg_vector_value): Remove 'base_mode' - parameter. Use DImode for computing the number of registers. + parameter. Use DImode for computing the number of registers. (function_arg): Adjust for above change. (function_value): Likewise. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f84f326..fca4d85 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5029,11 +5029,33 @@ classify_argument (enum machine_mode mode, const_tree type, case CSImode: case CHImode: case CQImode: - if (bit_offset + GET_MODE_BITSIZE (mode) <= 32) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - return 1; + { + int size = (bit_offset % 64)+ (int) GET_MODE_BITSIZE (mode); + + if (size <= 32) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 64) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 64+32) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 64+64) + { + classes[0] = classes[1] = X86_64_INTEGER_CLASS; + return 2; + } + else + gcc_unreachable (); + } case CDImode: case TImode: classes[0] = classes[1] = X86_64_INTEGER_CLASS; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3437a0d..6eaad34 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-11-19 Uros Bizjak <ubizjak@gmail.com> + + PR target/38151 + * gcc.target/i386/pr38151-1.c: New test. + 2008-11-20 Jason Merrill <jason@redhat.com> PR c++/28513 diff --git a/gcc/testsuite/gcc.target/i386/pr38151-1.c b/gcc/testsuite/gcc.target/i386/pr38151-1.c new file mode 100644 index 0000000..6500a50 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr38151-1.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +void abort (void); + +struct S2848 +{ + unsigned int a; + _Complex int b; +}; + +struct S2848 s2848; + +void __attribute__((noinline)) +check2848 (struct S2848 arg0) +{ + if (arg0.b != s2848.b) + abort (); +} + +int main() +{ + s2848.a = 4027477739U; + s2848.b = (723419448 + -218144346 * __extension__ 1i); + + check2848 (s2848); + + return 0; +} |