diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-11 07:33:23 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-11 07:33:23 +0000 |
commit | 171557e8ce0106d9cc0321be218b42bbaaefeec0 (patch) | |
tree | 654aa05676a650f4bfb708a7c200e82d0a1e39c8 /gcc/expmed.c | |
parent | 96efe7138202a220c3f6168a4e7f3fc9f4e93a83 (diff) | |
download | gcc-171557e8ce0106d9cc0321be218b42bbaaefeec0.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140265 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 0daf7fa31f0..6099c4b6839 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; |