From: Chao-ying Fu <[email protected]>
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 <[email protected]>
Signed-off-by: Aleksandar Rakic <[email protected]>
Signed-off-by: Eldar Osmanovic <[email protected]>
---
gcc/config/mips/mips.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
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);
}
--
2.43.0