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