aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1993-09-23 16:56:28 +0000
committerRichard Stallman <rms@gnu.org>1993-09-23 16:56:28 +0000
commita97f5a864f1e3493e140b142a9ceb820663d5c0a (patch)
tree9b2ecd4ac2fa497df584477021bbf38faf4c3d4e /gcc
parent672fd7e23872348476fea0af028ae867d7160f37 (diff)
downloadgcc-a97f5a864f1e3493e140b142a9ceb820663d5c0a.zip
gcc-a97f5a864f1e3493e140b142a9ceb820663d5c0a.tar.gz
gcc-a97f5a864f1e3493e140b142a9ceb820663d5c0a.tar.bz2
(expand_increment): Don't store directly ito a subreg
that is narrower than a word. From-SVN: r5433
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index e3c00c6..87dc0ad 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7648,6 +7648,10 @@ expand_increment (exp, post)
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
int op0_is_copy = 0;
int single_insn = 0;
+ /* 1 means we can't store into OP0 directly,
+ because it is a subreg narrower than a word,
+ and we don't dare clobber the rest of the word. */
+ int bad_subreg = 0;
if (output_bytecode)
{
@@ -7688,6 +7692,9 @@ expand_increment (exp, post)
if (GET_CODE (op0) == SUBREG && SUBREG_PROMOTED_VAR_P (op0))
SUBREG_REG (op0) = copy_to_reg (SUBREG_REG (op0));
+ else if (GET_CODE (op0) == SUBREG
+ && GET_MODE_BITSIZE (GET_MODE (op0)) < BITS_PER_WORD)
+ bad_subreg = 1;
op0_is_copy = ((GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
&& temp != get_last_insn ());
@@ -7723,8 +7730,11 @@ expand_increment (exp, post)
then we cannot just increment OP0. We must therefore contrive to
increment the original value. Then, for postincrement, we can return
OP0 since it is a copy of the old value. For preincrement, expand here
- unless we can do it with a single insn. */
- if (op0_is_copy || (!post && !single_insn))
+ unless we can do it with a single insn.
+
+ Likewise if storing directly into OP0 would clobber high bits
+ we need to preserve (bad_subreg). */
+ if (op0_is_copy || (!post && !single_insn) || bad_subreg)
{
/* This is the easiest way to increment the value wherever it is.
Problems with multiple evaluation of INCREMENTED are prevented