https://gcc.gnu.org/g:6fdd184731aadb2d6cf5afa866ec9eb63126516a
commit r16-7483-g6fdd184731aadb2d6cf5afa866ec9eb63126516a Author: Hans-Peter Nilsson <[email protected]> Date: Mon Feb 9 21:30:46 2026 +0100 CRIS: For HI, QI, make sure move patterns don't have two memory operands Further testing showed that the two-memory-operands case that could happen for movsf happened for the HI and QI modes as well, for example in gcc.dg/Wrestrict-5.c. So, for improved performance they'd better get guards as well. The movstrict<m> case is just tagging along for summetry; I don't know of test-cases that expose that. * config/cris/cris.md (BWDSF): New mode_iterator replacing SISF. All callers changed. ("*movhi_internal<setcc><setnz><setnzvc>"): Anonymized from "<acc><anz><anzvc>movhi<setcc><setnz><setnzvc>" to make it a match-only pattern. Add conditions to guard from source and destination both being memory operands. ("*movstricthi_internal", "*movstrictqi_internal"): Similarly for "movstricthi" and "movstrictqi". ("movstrict<mode>"): Add common expander for BW, forcing one operand to be a register or source being zero. Diff: --- gcc/config/cris/cris.md | 51 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index c18813f306a9..5d41a6d0d840 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -173,8 +173,8 @@ (define_mode_iterator BWD [SI HI QI]) (define_mode_iterator BWDD [DI SI HI QI]) -;; Need to handle SI and SF similarly, at least in the expander. -(define_mode_iterator SISF [SI SF]) +;; Need to handle BWD and SF similarly, at least in the expander. +(define_mode_iterator BWDSF [SI HI QI SF]) ;; To be able to refer to the same mode_attr for both a multi-mode ;; and a mode-specific pattern, we use some singleton iterators. @@ -566,8 +566,8 @@ (define_expand "mov<mode>" [(parallel [(set - (match_operand:SISF 0 "nonimmediate_operand") - (match_operand:SISF 1 "general_operand")) + (match_operand:BWDSF 0 "nonimmediate_operand") + (match_operand:BWDSF 1 "general_operand")) (clobber (reg:CC CRIS_CC0_REGNUM))])] "" { @@ -661,14 +661,14 @@ (set_attr "cc<cccc><ccnz><ccnzvc>" "*,*,none,none,*,none,none,*,*,none,none,none,none,none,none,*,none")]) -;; FIXME: See movsi. - -(define_insn "<acc><anz><anzvc>movhi<setcc><setnz><setnzvc>" +(define_insn "*movhi_internal<setcc><setnz><setnzvc>" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r, r,Q>,r,Q>,r,r,r,g,g,r,r,x") (match_operand:HI 1 "general_operand" "r,Q>,M,M, I,r, L,O,n,M,r,g,x,r")) (clobber (reg:CC CRIS_CC0_REGNUM))] - "" + "(register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || operands[1] == const0_rtx)" { switch (which_alternative) { @@ -705,13 +705,32 @@ [(set_attr "slottable" "yes,yes,yes,yes,yes,yes,no,yes,no,no,no,no,yes,yes") (set_attr "cc<cccc><ccnz><ccnzvc>" "*,*,none,none,*,none,*,clobber,*,none,none,*,none,none")]) -(define_insn "movstricthi" +(define_expand "movstrict<mode>" + [(parallel + [(set + (strict_low_part (match_operand:BW 0 "nonimmediate_operand")) + (match_operand:BW 1 "general_operand")) + (clobber (reg:CC CRIS_CC0_REGNUM))])] + "" +{ + /* If the output goes to a MEM, make sure we have zero or a register as + input. */ + if (MEM_P (operands[0]) + && ! REG_S_P (operands[1]) + && operands[1] != const0_rtx + && can_create_pseudo_p ()) + operands[1] = force_reg (<MODE>mode, operands[1]); +}) + +(define_insn "*movstricthi_internal" [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+r,r, r,Q>,Q>,g,r,g")) (match_operand:HI 1 "general_operand" "r,Q>,M,M, r, M,g,r")) (clobber (reg:CC CRIS_CC0_REGNUM))] - "" + "(register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || operands[1] == const0_rtx)" "@ move.w %1,%0 move.w %1,%0 @@ -739,11 +758,13 @@ "" "") -(define_insn "<acc><anz><anzvc>movqi<setcc><setnz><setnzvc>" +(define_insn "*movqi_internal<setcc><setnz><setnzvc>" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,Q>,r, r,Q>,r,g,g,r,r,r,x") (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, I,M,r,O,g,x,r")) (clobber (reg:CC CRIS_CC0_REGNUM))] - "" + "(register_operand (operands[0], QImode) + || register_operand (operands[1], QImode) + || operands[1] == const0_rtx)" "@ move.b %1,%0 move.b %1,%0 @@ -761,12 +782,14 @@ (set_attr "cc<cccc><ccnz><ccnzvc>" "*,none,*,none,none,*,none,none,clobber,*,none,none")]) -(define_insn "movstrictqi" +(define_insn "*movstrictqi_internal" [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+r,Q>,r, r,Q>,g,g,r")) (match_operand:QI 1 "general_operand" "r,r, Q>,M,M, M,r,g")) (clobber (reg:CC CRIS_CC0_REGNUM))] - "" + "(register_operand (operands[0], QImode) + || register_operand (operands[1], QImode) + || operands[1] == const0_rtx)" "@ move.b %1,%0 move.b %1,%0
