diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-01-30 02:33:27 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-01-30 02:33:27 +0000 |
commit | 60fb460111c1e195f5580d311dc57c428f8cd7fb (patch) | |
tree | a17b3c109913e98389dfb0d728464f79bd38a700 /gcc/expr.c | |
parent | ab397fa77ab5ffc9cc6c3aa6c599591c29ecd28a (diff) | |
download | gcc-60fb460111c1e195f5580d311dc57c428f8cd7fb.tar.gz |
PR middle-end/19689
* expr.c (store_field): Don't strip sub-mode cast when the input
data is even smaller.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94429 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 29acbba5c5b..ab7cf930d8b 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5226,12 +5226,18 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, the field we're storing into, that mask is redundant. This is particularly common with bit field assignments generated by the C front end. */ - if (TREE_CODE (exp) == NOP_EXPR - && INTEGRAL_TYPE_P (TREE_TYPE (exp)) - && (TYPE_PRECISION (TREE_TYPE (exp)) - < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))) - && bitsize == TYPE_PRECISION (TREE_TYPE (exp))) - exp = TREE_OPERAND (exp, 0); + if (TREE_CODE (exp) == NOP_EXPR) + { + tree type = TREE_TYPE (exp); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < GET_MODE_BITSIZE (TYPE_MODE (type)) + && bitsize == TYPE_PRECISION (type)) + { + type = TREE_TYPE (TREE_OPERAND (exp, 0)); + if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) >= bitsize) + exp = TREE_OPERAND (exp, 0); + } + } temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); |