aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@linaro.org>2012-03-15 16:43:08 +0000
committerUlrich Weigand <uweigand@gcc.gnu.org>2012-03-15 16:43:08 +0000
commitdf7965e4144004831703ce7ed1d7ea67509c1028 (patch)
tree347e3e164edc0c8e666e713b78409184ce31fecc /gcc
parentbc4fb35543b0e2b6bf1f0b0d4d234a16e8005813 (diff)
downloadgcc-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/ChangeLog4
-rw-r--r--gcc/combine.c46
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;