diff options
author | Adam Nemet <anemet@caviumnetworks.com> | 2008-11-18 02:08:24 +0000 |
---|---|---|
committer | Adam Nemet <anemet@caviumnetworks.com> | 2008-11-18 02:08:24 +0000 |
commit | 072e26c79103928df61536f3b39690bb8b2a21b4 (patch) | |
tree | 5a743df1e9e72a72b5cbac89bebae2c44dd3bd74 | |
parent | 31e8d4582a0fe96218103a043b7596a6cef1b2ad (diff) |
* expmed.c (extract_bit_field_1): Also use a temporary and
convert_extracted_bit_field when the conversion from ext_mode to
the target mode requires explicit truncation.
testsuite/
* gcc.c-torture/execute/20081117-1.c: New test.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@141960 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expmed.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20081117-1.c | 24 |
4 files changed, 41 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0477d27532c..da96cb50c60 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-11-17 Adam Nemet <anemet@caviumnetworks.com> + + * expmed.c (extract_bit_field_1): Also use a temporary and + convert_extracted_bit_field when the conversion from ext_mode to + the target mode requires explicit truncation. + 2008-11-17 Richard Sandiford <rdsandiford@googlemail.com> * config/mips/mips.h (REG_ALLOC_ORDER): Put accumulators first. diff --git a/gcc/expmed.c b/gcc/expmed.c index 0c7e611e188..70a0d18bcb5 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -1533,7 +1533,13 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (GET_MODE (xtarget) != ext_mode) { - if (REG_P (xtarget)) + /* Don't use LHS paradoxical subreg if explicit truncation is needed + between the mode of the extraction (word_mode) and the target + mode. Instead, create a temporary and use convert_move to set + the target. */ + if (REG_P (xtarget) + && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE (xtarget)), + GET_MODE_BITSIZE (ext_mode))) { xtarget = gen_lowpart (ext_mode, xtarget); if (GET_MODE_SIZE (ext_mode) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2bc32017299..0af6cad0a3d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-11-17 Adam Nemet <anemet@caviumnetworks.com> + + * gcc.c-torture/execute/20081117-1.c: New test. + 2008-11-17 Richard Sandiford <rdsandiford@googlemail.com> * gcc.target/mips/dspr2-MULT.c: Just check for $ac1 and $ac2. diff --git a/gcc/testsuite/gcc.c-torture/execute/20081117-1.c b/gcc/testsuite/gcc.c-torture/execute/20081117-1.c new file mode 100644 index 00000000000..bff7464cbae --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20081117-1.c @@ -0,0 +1,24 @@ +extern void abort (void); + +struct s +{ + unsigned long long a:16; + unsigned long long b:32; + unsigned long long c:16; +}; + +__attribute__ ((noinline)) unsigned +f (struct s s, unsigned i) +{ + return s.b == i; +} + +struct s s = { 1, 0x87654321u, 2}; + +int +main () +{ + if (!f (s, 0x87654321u)) + abort (); + return 0; +} |