diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2014-02-02 16:35:53 +0100 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2014-02-02 16:35:53 +0100 |
commit | 6c90f137151fc996489e9a5652bd59078a65f162 (patch) | |
tree | 1348122d64fff2168ee0d9b72e5b9b0966e026aa | |
parent | 5e64bbbbf39d44f96bdd94711aa77e0f92c9b828 (diff) | |
download | gcc-6c90f137151fc996489e9a5652bd59078a65f162.zip gcc-6c90f137151fc996489e9a5652bd59078a65f162.tar.gz gcc-6c90f137151fc996489e9a5652bd59078a65f162.tar.bz2 |
re PR target/60017 (Struct not returned correctly)
PR target/60017
* config/i386/i386.c (classify_argument): Fix handling of bit_offset
when calculating size of integer atomic types.
testsuite/ChangeLog:
PR target/60017
* gcc.c-torture/execute/pr60017.c: New test.
From-SVN: r207399
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr60017.c | 33 |
4 files changed, 52 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0825c36..9635722 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-02-02 Uros Bizjak <ubizjak@gmail.com> + + PR target/60017 + * config/i386/i386.c (classify_argument): Fix handling of bit_offset + when calculating size of integer atomic types. + 2014-02-02 H.J. Lu <hongjiu.lu@intel.com> * ipa-inline-analysis.c (true_predicate_p): Fix a typo in comments. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index dcf96e6..a5d6559 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -6627,25 +6627,28 @@ classify_argument (enum machine_mode mode, const_tree type, case CHImode: case CQImode: { - int size = (bit_offset % 64)+ (int) GET_MODE_BITSIZE (mode); + int size = bit_offset + (int) GET_MODE_BITSIZE (mode); - if (size <= 32) + /* Analyze last 128 bits only. */ + size = (size - 1) & 0x7f; + + if (size < 32) { classes[0] = X86_64_INTEGERSI_CLASS; return 1; } - else if (size <= 64) + else if (size < 64) { classes[0] = X86_64_INTEGER_CLASS; return 1; } - else if (size <= 64+32) + else if (size < 64+32) { classes[0] = X86_64_INTEGER_CLASS; classes[1] = X86_64_INTEGERSI_CLASS; return 2; } - else if (size <= 64+64) + else if (size < 64+64) { classes[0] = classes[1] = X86_64_INTEGER_CLASS; return 2; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd547e7..3cce684 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-02-02 Uros Bizjak <ubizjak@gmail.com> + + PR target/60017 + * gcc.c-torture/execute/pr60017.c: New test. + 2014-02-02 Mikael Morin <mikael@gcc.gnu.org> PR fortran/57033 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60017.c b/gcc/testsuite/gcc.c-torture/execute/pr60017.c new file mode 100644 index 0000000..d72c12c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr60017.c @@ -0,0 +1,33 @@ +/* PR target/60017 */ + +extern void abort (void); + +struct S0 +{ + short m0; + short m1; +}; + +struct S1 +{ + unsigned m0:1; + char m1[2][2]; + struct S0 m2[2]; +}; + +struct S1 x = { 1, {{2, 3}, {4, 5}}, {{6, 7}, {8, 9}} }; + +struct S1 func (void) +{ + return x; +} + +int main (void) +{ + struct S1 ret = func (); + + if (ret.m2[1].m1 != 9) + abort (); + + return 0; +} |