diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-09-15 17:54:04 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-09-15 17:54:04 +0200 |
commit | a1189286e5dedc4ab4aacda95216b047017cd3cf (patch) | |
tree | a04038ed07d498e752afbd26f1ad98c025f14411 /gcc/combine.c | |
parent | 681f5b7cc8e80ef09f4692fac5bf3824e4854d54 (diff) | |
download | gcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.zip gcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.tar.gz gcc-a1189286e5dedc4ab4aacda95216b047017cd3cf.tar.bz2 |
re PR rtl-optimization/82192 (gcc produces incorrect code with -O2 and bit-field)
PR rtl-optimization/82192
* combine.c (make_extraction): Don't look through non-paradoxical
SUBREGs or TRUNCATE if pos + len is or might be bigger than
inner's mode.
* gcc.c-torture/execute/pr82192.c: New test.
From-SVN: r252824
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index ccfee26..e502fa1 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7442,7 +7442,14 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (pos_rtx && CONST_INT_P (pos_rtx)) pos = INTVAL (pos_rtx), pos_rtx = 0; - if (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner)) + if (GET_CODE (inner) == SUBREG + && subreg_lowpart_p (inner) + && (paradoxical_subreg_p (inner) + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + non-paradoxical SUBREGs. See PR82192. */ + || (pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)))) { /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...), consider just the QI as the memory to extract from. @@ -7468,7 +7475,12 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, if (new_rtx != 0) return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1)); } - else if (GET_CODE (inner) == TRUNCATE) + else if (GET_CODE (inner) == TRUNCATE + /* If trying or potentionally trying to extract + bits outside of is_mode, don't look through + TRUNCATE. See PR82192. */ + && pos_rtx == NULL_RTX + && pos + len <= GET_MODE_PRECISION (is_mode)) inner = XEXP (inner, 0); inner_mode = GET_MODE (inner); |