From: Richard Earnshaw <[email protected]>

This is code in the subst[1] pass in combine that rejects substituting a
subreg of two modes that are not tieable.  However, optimizations on
VEC_SELECT in both cse and combine will blithly simplify to a subreg
without regard to this restriction.  This lack of duality can make it
difficult to correctly combine certain idioms that have previously
been 'simplified' to subreg patterns.  This patch creates a bit more
duality between the two parts of the compiler.

[1]
                  /* In general, don't install a subreg involving two
                     modes not tieable.  It can worsen register ...

gcc/ChangeLog:

        * combine.cc (combine_simplify_rtx): Only simplify VEC_SELECT
        to a subreg if the modes are tieable.
        * cse.cc (fold_rtx): Likewise.
---
 gcc/combine.cc | 6 ++++--
 gcc/cse.cc     | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 939c5495e3994..d7233b4e4eecf 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -6472,8 +6472,10 @@ combine_simplify_rtx (rtx x, machine_mode op0_mode, bool 
in_dest, bool in_cond)
        rtx trueop0 = XEXP (x, 0);
        mode = GET_MODE (trueop0);
        rtx trueop1 = XEXP (x, 1);
-       /* If we select a low-part subreg, return that.  */
-       if (vec_series_lowpart_p (GET_MODE (x), mode, trueop1))
+       /* If we select a low-part subreg, return that, but only if the
+          modes are tieable.  */
+       if (targetm.modes_tieable_p (GET_MODE (x), mode)
+           && vec_series_lowpart_p (GET_MODE (x), mode, trueop1))
          {
            rtx new_rtx = lowpart_subreg (GET_MODE (x), trueop0, mode);
            if (new_rtx != NULL_RTX)
diff --git a/gcc/cse.cc b/gcc/cse.cc
index 53483b967edba..9cc4f11c23f2b 100644
--- a/gcc/cse.cc
+++ b/gcc/cse.cc
@@ -3235,8 +3235,10 @@ fold_rtx (rtx x, rtx_insn *insn)
        rtx trueop0 = XEXP (x, 0);
        mode = GET_MODE (trueop0);
        rtx trueop1 = XEXP (x, 1);
-       /* If we select a low-part subreg, return that.  */
-       if (vec_series_lowpart_p (GET_MODE (x), mode, trueop1))
+       /* If we select a low-part subreg, return that, but only if the
+          modes are tieable.  */
+       if (targetm.modes_tieable_p (GET_MODE (x), mode)
+           && vec_series_lowpart_p (GET_MODE (x), mode, trueop1))
          {
            rtx new_rtx = lowpart_subreg (GET_MODE (x), trueop0, mode);
            if (new_rtx != NULL_RTX)
-- 
2.56.0

Reply via email to