[gcc r16-1110] ext-dce: Don't refine live width with SUBREG mode if !TRULY_NOOP_TRUNCATION_MODES_P [PR 120050]
Xi Ruoyao
xry111@gcc.gnu.org
Wed Jun 4 15:28:23 GMT 2025
https://gcc.gnu.org/g:65f3a439c4f76fe780a30ac66969f51035c4bf98
commit r16-1110-g65f3a439c4f76fe780a30ac66969f51035c4bf98
Author: Xi Ruoyao <xry111@xry111.site>
Date: Sun May 11 16:44:31 2025 +0800
ext-dce: Don't refine live width with SUBREG mode if !TRULY_NOOP_TRUNCATION_MODES_P [PR 120050]
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.
Diff:
---
gcc/ext-dce.cc | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc
index a03439501419..aa80c0483d61 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,25 @@ 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, the mode
+ change performed by Y would normally need to be a
+ TRUNCATE rather than a SUBREG. It is probably the
+ guarantee provided by SUBREG_PROMOTED_VAR_P that
+ allows the SUBREG in Y as an exception. We must
+ therefore preserve that guarantee and treat the
+ upper bits of the inner register as live
+ 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 ();
More information about the Gcc-cvs
mailing list