diff options
author | Ulrich Weigand <ulrich.weigand@linaro.org> | 2012-03-15 16:43:08 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2012-03-15 16:43:08 +0000 |
commit | df7965e4144004831703ce7ed1d7ea67509c1028 (patch) | |
tree | 347e3e164edc0c8e666e713b78409184ce31fecc /gcc | |
parent | bc4fb35543b0e2b6bf1f0b0d4d234a16e8005813 (diff) | |
download | gcc-df7965e4144004831703ce7ed1d7ea67509c1028.zip gcc-df7965e4144004831703ce7ed1d7ea67509c1028.tar.gz gcc-df7965e4144004831703ce7ed1d7ea67509c1028.tar.bz2 |
* combine.c (apply_distributive_law): Do not distribute SUBREG.
From-SVN: r185438
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/combine.c | 46 |
2 files changed, 20 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 594192c..32ba912 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2012-03-15 Ulrich Weigand <ulrich.weigand@linaro.org> + + * combine.c (apply_distributive_law): Do not distribute SUBREG. + 2012-03-15 Ira Rosen <irar@il.ibm.com> Ulrich Weigand <ulrich.weigand@linaro.org> diff --git a/gcc/combine.c b/gcc/combine.c index ab825e4..e3c8209 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -9290,36 +9290,22 @@ apply_distributive_law (rtx x) /* This is also a multiply, so it distributes over everything. */ break; - case SUBREG: - /* Non-paradoxical SUBREGs distributes over all operations, - provided the inner modes and byte offsets are the same, this - is an extraction of a low-order part, we don't convert an fp - operation to int or vice versa, this is not a vector mode, - and we would not be converting a single-word operation into a - multi-word operation. The latter test is not required, but - it prevents generating unneeded multi-word operations. Some - of the previous tests are redundant given the latter test, - but are retained because they are required for correctness. - - We produce the result slightly differently in this case. */ - - if (GET_MODE (SUBREG_REG (lhs)) != GET_MODE (SUBREG_REG (rhs)) - || SUBREG_BYTE (lhs) != SUBREG_BYTE (rhs) - || ! subreg_lowpart_p (lhs) - || (GET_MODE_CLASS (GET_MODE (lhs)) - != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs)))) - || paradoxical_subreg_p (lhs) - || VECTOR_MODE_P (GET_MODE (lhs)) - || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD - /* Result might need to be truncated. Don't change mode if - explicit truncation is needed. */ - || !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (x), - GET_MODE (SUBREG_REG (lhs)))) - return x; - - tem = simplify_gen_binary (code, GET_MODE (SUBREG_REG (lhs)), - SUBREG_REG (lhs), SUBREG_REG (rhs)); - return gen_lowpart (GET_MODE (x), tem); + /* This used to handle SUBREG, but this turned out to be counter- + productive, since (subreg (op ...)) usually is not handled by + insn patterns, and this "optimization" therefore transformed + recognizable patterns into unrecognizable ones. Therefore the + SUBREG case was removed from here. + + It is possible that distributing SUBREG over arithmetic operations + leads to an intermediate result than can then be optimized further, + e.g. by moving the outer SUBREG to the other side of a SET as done + in simplify_set. This seems to have been the original intent of + handling SUBREGs here. + + However, with current GCC this does not appear to actually happen, + at least on major platforms. If some case is found where removing + the SUBREG case here prevents follow-on optimizations, distributing + SUBREGs ought to be re-added at that place, e.g. in simplify_set. */ default: return x; |