aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-09-11 09:33:23 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2008-09-11 09:33:23 +0200
commitd898d29bf9d642a49bb2502416ecdfe0a21d6ac1 (patch)
tree654aa05676a650f4bfb708a7c200e82d0a1e39c8 /gcc/expmed.c
parentace428e3133f0aa7f4cb90180e716114bf73d705 (diff)
downloadgcc-d898d29bf9d642a49bb2502416ecdfe0a21d6ac1.zip
gcc-d898d29bf9d642a49bb2502416ecdfe0a21d6ac1.tar.gz
gcc-d898d29bf9d642a49bb2502416ecdfe0a21d6ac1.tar.bz2
re PR target/37382 (ICE in extract_insn: <var_decl 0x7fda26ff4b40 swig_module>) 0))
PR target/37382 * expmed.c (extract_low_bits): Avoid creating invalid subregs. * dse.c (find_shift_sequence): Use extract_low_bits instead of simplify_gen_subreg. * gcc.c-torture/compile/pr37382.c: New test. From-SVN: r140265
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 0daf7fa..6099c4b 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -1991,8 +1991,22 @@ extract_low_bits (enum machine_mode mode, enum machine_mode src_mode, rtx src)
return src;
if (CONSTANT_P (src))
- return simplify_gen_subreg (mode, src, src_mode,
- subreg_lowpart_offset (mode, src_mode));
+ {
+ /* simplify_gen_subreg can't be used here, as if simplify_subreg
+ fails, it will happily create (subreg (symbol_ref)) or similar
+ invalid SUBREGs. */
+ unsigned int byte = subreg_lowpart_offset (mode, src_mode);
+ rtx ret = simplify_subreg (mode, src, src_mode, byte);
+ if (ret)
+ return ret;
+
+ if (GET_MODE (src) == VOIDmode
+ || !validate_subreg (mode, src_mode, src, byte))
+ return NULL_RTX;
+
+ src = force_reg (GET_MODE (src), src);
+ return gen_rtx_SUBREG (mode, src, byte);
+ }
if (GET_MODE_CLASS (mode) == MODE_CC || GET_MODE_CLASS (src_mode) == MODE_CC)
return NULL_RTX;