If we see a promoted subreg and TRULY_NOOP_TRUNCATION says the
truncation is not a noop, then all bits of the inner reg are live.  We
cannot reduce the live mask to that of the mode of the subreg.

gcc/ChangeLog:

        PR rtl-optimization/120050
        * ext-dce.cc (ext_dce_process_uses): Break early if a SUBREG in
        rhs is promoted and the truncation from the inner mode to the
        outer mode is not a noop when handling SETs.
---

Bootstrapped on mips64el-linux-gnuabi64.  Ok for trunk?

 gcc/ext-dce.cc | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc
index a0343950141..3b21e68b90c 100644
--- a/gcc/ext-dce.cc
+++ b/gcc/ext-dce.cc
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "print-rtl.h"
 #include "dbgcnt.h"
 #include "diagnostic-core.h"
+#include "target.h"
 
 /* These should probably move into a C++ class.  */
 static vec<bitmap_head> livein;
@@ -764,13 +765,20 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj,
                         We don't want to mark those bits live unnecessarily
                         as that inhibits extension elimination in important
                         cases such as those in Coremark.  So we need that
-                        outer code.  */
+                        outer code.
+
+                        But if !TRULY_NOOP_TRUNCATION_MODES_P, those bits
+                        may be actually alive with any promoted subreg
+                        regardless of the outer code.  See PR 120050.  */
                      if (!REG_P (SUBREG_REG (y))
                          || (SUBREG_PROMOTED_VAR_P (y)
                              && ((GET_CODE (SET_SRC (x)) == SIGN_EXTEND
                                   && SUBREG_PROMOTED_SIGNED_P (y))
                                  || (GET_CODE (SET_SRC (x)) == ZERO_EXTEND
-                                     && SUBREG_PROMOTED_UNSIGNED_P (y)))))
+                                     && SUBREG_PROMOTED_UNSIGNED_P (y))
+                                 || !TRULY_NOOP_TRUNCATION_MODES_P (
+                                       GET_MODE (y),
+                                       GET_MODE (SUBREG_REG (y))))))
                        break;
 
                      bit = subreg_lsb (y).to_constant ();
-- 
2.49.0

Reply via email to