aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1993-08-18 17:48:33 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1993-08-18 17:48:33 -0400
commit0840fd91a3ecc27805284548c687bc365581d031 (patch)
tree1d041d50fabfd7401bd555373c950a1d5956209a /gcc
parent9d53c942648faa593c459b137142338e9864dc53 (diff)
downloadgcc-0840fd91a3ecc27805284548c687bc365581d031.zip
gcc-0840fd91a3ecc27805284548c687bc365581d031.tar.gz
gcc-0840fd91a3ecc27805284548c687bc365581d031.tar.bz2
(nonzero_bits): Handle case when BYTE_LOADS_EXTEND is not on and we
are asked for something in a mode wider than it. From-SVN: r5183
Diffstat (limited to 'gcc')
-rw-r--r--gcc/combine.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index a270b6b..af83df5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6347,6 +6347,25 @@ nonzero_bits (x, mode)
just return the mode mask. Those tests will then be false. */
return nonzero;
+#ifndef BYTE_LOADS_EXTEND
+ /* If X is wider than MODE, but both are a single word for both the host
+ and target machines, we can compute this from which bits of the
+ object might be nonzero in its own mode, taking into account the fact
+ that on many CISC machines, accessing an object in a wider mode
+ causes the high-order bits to become undefined. So they are
+ not known to be zero. */
+
+ if (GET_MODE (x) != VOIDmode && GET_MODE (x) != mode
+ && GET_MODE_BITSIZE (GET_MODE (x)) <= BITS_PER_WORD
+ && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
+ && GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (GET_MODE (x)))
+ {
+ nonzero &= nonzero_bits (x, GET_MODE (x));
+ nonzero |= GET_MODE_MASK (mode) & ~ GET_MODE_MASK (GET_MODE (x));
+ return nonzero;
+ }
+#endif
+
code = GET_CODE (x);
switch (code)
{