[v3,12/14] MIPS: Check anti-dependence between 0 and 3 for loads

Message ID 20260717125453.74473-13-eldar.osmanovic@htecgroup.com
State New
Headers
Series Mips target improvements |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed

Commit Message

Eldar Osmanovic July 17, 2026, 12:56 p.m. UTC
  From: Chao-ying Fu <cfu@wavecomp.com>

Correct anti-dependence handling for bonded load pairs by checking the
first destination against the second load address. Reverse the load
order when necessary and verify that the reordered pair is safe.

gcc/ChangeLog:

	* config/mips/mips.md (join2_load_store<JOIN_MODE:mode>): Check
	operand 0 and 3. Assert other two operands do not overlap after
	they are reordered.
	(*join2_loadhi): Same.

Cherry-picked 63175687761e51dfe2f75dfab7b4de7f44bb4abe
from https://github.com/MIPS/gcc

Signed-off-by: Chao-ying Fu <cfu@mips.com>
Signed-off-by: Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
Signed-off-by: Eldar Osmanovic <eldar.osmanovic@htecgroup.com>
---
 gcc/config/mips/mips.md | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index afad8e6de83..62cb1c270af 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -7997,7 +7997,7 @@ 
     /* Reg-renaming pass reuses base register if it is dead after bonded loads.
        Hardware does not bond those loads, even when they are consecutive.
        However, order of the loads need to be checked for correctness.  */
-    if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[1]))
+    if (!load_p || !reg_overlap_mentioned_p (operands[0], operands[3]))
       {
 	output_asm_insn (mips_output_move (insn, operands[0], operands[1]),
 			 operands);
@@ -8006,6 +8006,8 @@ 
       }
     else
       {
+	/* Check the other two registers.  */
+	gcc_assert (!reg_overlap_mentioned_p (operands[2], operands[1]));
 	output_asm_insn (mips_output_move (insn, operands[2], operands[3]),
 			 &operands[2]);
 	output_asm_insn (mips_output_move (insn, operands[0], operands[1]),
@@ -8060,13 +8062,15 @@ 
     /* Reg-renaming pass reuses base register if it is dead after bonded loads.
        Hardware does not bond those loads, even when they are consecutive.
        However, order of the loads need to be checked for correctness.  */
-    if (!reg_overlap_mentioned_p (operands[0], operands[1]))
+    if (!reg_overlap_mentioned_p (operands[0], operands[3]))
       {
 	output_asm_insn ("lh<u>\t%0,%1", operands);
 	output_asm_insn ("lh<u>\t%2,%3", operands);
       }
     else
       {
+	/* Check the other two registers.  */
+	gcc_assert (!reg_overlap_mentioned_p (operands[2], operands[1]));
 	output_asm_insn ("lh<u>\t%2,%3", operands);
 	output_asm_insn ("lh<u>\t%0,%1", operands);
       }