On 1/3/24 16:39, Richard Sandiford wrote:
YunQiang Su <s...@gcc.gnu.org> writes:
On TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) == true platforms,
if 31 or above bits is polluted by an bitops, we will need an
truncate. Let's emit one, and mark let's use the same hardreg
as in and out, the RTL may like:

(insn 21 20 24 2 (set (subreg/s/u:SI (reg/v:DI 200 [ val ]) 0)
         (truncate:SI (reg/v:DI 200 [ val ]))) "../xx.c":7:29 -1
      (nil))

We use /s/u flags to mark it as really needed, as in
combine_simplify_rtx, this insn may be considered as truncated,
so let's skip this combination.

gcc/ChangeLog:
         PR: 104914.
         * combine.cc (try_combine): Skip combine with truncate if
        dest is subreg and has /u/s flags on platforms
        TRULY_NOOP_TRUNCATION_MODES_P (DImode, SImode)) == true.
        * expr.cc (expand_assignment): Emit a truncate insn, if
        31+ bits is polluted for SImode.

gcc/testsuite/ChangeLog:
        PR: 104914.
        * gcc.target/mips/pr104914.c: New testcase.

Sorry for not looking at this earlier.  I've got a bit lost in the
various threads, so apologies if this has been discussed already
but I think the fix is:

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 4f42c0ff487..9847eba19fe 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -6275,9 +6275,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
              else
                {
                  rtx to_rtx1
-                   = lowpart_subreg (subreg_unpromoted_mode (to_rtx),
-                                     SUBREG_REG (to_rtx),
-                                     subreg_promoted_mode (to_rtx));
+                   = convert_to_mode (subreg_unpromoted_mode (to_rtx),
+                                      SUBREG_REG (to_rtx), false);
                  result = store_field (to_rtx1, bitsize, bitpos,
                                        bitregion_start, bitregion_end,
                                        mode1, from, get_alias_set (to),

(completely untested apart from the test case).  That should still
produce a subreg on most targets, but generates the required trunc
on MIPS.
I think this is a subset of Roger's work that got committed a few days back.

jeff

Reply via email to