This patch addresses a regression introduced in r8-568-gf9f69dd651b2f1
(i.e., refactoring ivopts pass) for target mips-r6-linux-gnu. It
corrects the complexity calculation in ivopts. The fix involves
complexity computation reordering and proper invariant variables
handling in address expressions. These changes align with the approach
used before r8-568-gf9f69dd651b2f1 (e.g., in parent commit c2b64ce). The
improved complexity calculations ensure better candidate selection and
reduced code size, particularly for RISC CPUs.

Signed-off-by: Radosav Krunic <[email protected]>
Signed-off-by: Aleksandar Rakic <[email protected]>
Signed-off-by: Jovan Dmitrovic <[email protected]>

gcc/ChangeLog:

        * tree-ssa-loop-ivopts.cc (get_address_cost): Fixed
        complexity calculation.

gcc/testsuite/ChangeLog:

        * gcc.target/mips/bug_tree-optimization_109429.c: New test.
---
 .../mips/bug_tree-optimization_109429.c       | 24 +++++++++
 gcc/tree-ssa-loop-ivopts.cc                   | 54 +++++++++----------
 2 files changed, 50 insertions(+), 28 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/bug_tree-optimization_109429.c

diff --git a/gcc/testsuite/gcc.target/mips/bug_tree-optimization_109429.c 
b/gcc/testsuite/gcc.target/mips/bug_tree-optimization_109429.c
new file mode 100644
index 00000000000..96a62278fcd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/bug_tree-optimization_109429.c
@@ -0,0 +1,24 @@
+/* { dg-do compile} */
+/* { dg-skip-if "" { *-*-* }  { "*" } { "-O2" } } */
+/* { dg-options "-march=mips64r6 -mabi=64" } */
+
+static void daxpy (float *vector1, float *vector2, int n, float fp_const)
+{
+       for (int i = 0; i < n; ++i)
+               vector1[i] += fp_const * vector2[i];
+}
+
+void dgefa (float *vector, int m, int n, int l)
+{
+       for (int i = 0; i < n - 1; ++i)
+       {
+               for (int j = i + 1; j < n; ++j)
+               {
+                       float t = vector[m * j + l];
+                       daxpy (&vector[m * i + i + 1],
+                               &vector[m * j + i + 1], n - (i + 1), t);
+               }
+       }
+}
+
+/* { dg-final { scan-assembler 
"\\.L6:\\n\\tlwc1\t\\\$f1,0\\\(\\\$7\\\)\\n\tdaddiu\t\\\$2,\\\$2,4\\n\tlwc1\t\\\$f0,-4\\\(\\\$2\\\)"
 } } */
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 6ecf5bef7b4..0df365671ef 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -4695,38 +4695,35 @@ get_address_cost (struct ivopts_data *data, struct 
iv_use *use,
          if (!ok_with_ratio_p)
            parts.step = NULL_TREE;
        }
-      if (ok_with_ratio_p || ok_without_ratio_p)
+      if (!(ok_with_ratio_p || ok_without_ratio_p))
+         parts.index = NULL_TREE;
+      if (maybe_ne (aff_inv->offset, 0))
        {
-         if (maybe_ne (aff_inv->offset, 0))
-           {
-             parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
-             /* Addressing mode "base + index [<< scale] + offset".  */
-             if (!valid_mem_ref_p (mem_mode, as, &parts, code))
-               parts.offset = NULL_TREE;
-             else
-               aff_inv->offset = 0;
-           }
+         parts.offset = wide_int_to_tree (sizetype, aff_inv->offset);
+         /* Addressing mode "base[+ index[<< scale]] + offset".  */
+         if (!valid_mem_ref_p (mem_mode, as, &parts, code))
+           parts.offset = NULL_TREE;
+         else
+           aff_inv->offset = 0;
+       }
 
-         move_fixed_address_to_symbol (&parts, aff_inv);
-         /* Base is fixed address and is moved to symbol part.  */
-         if (parts.symbol != NULL_TREE && aff_combination_zero_p (aff_inv))
-           parts.base = NULL_TREE;
+      move_fixed_address_to_symbol (&parts, aff_inv);
+      /* Base is fixed address and is moved to symbol part.  */
+      if (parts.symbol != NULL_TREE && aff_combination_zero_p (aff_inv))
+         parts.base = NULL_TREE;
 
-         /* Addressing mode "symbol + base + index [<< scale] [+ offset]".  */
-         if (parts.symbol != NULL_TREE
-             && !valid_mem_ref_p (mem_mode, as, &parts, code))
-           {
-             aff_combination_add_elt (aff_inv, parts.symbol, 1);
-             parts.symbol = NULL_TREE;
-             /* Reset SIMPLE_INV since symbol address needs to be computed
-                outside of address expression in this case.  */
-             simple_inv = false;
-             /* Symbol part is moved back to base part, it can't be NULL.  */
-             parts.base = integer_one_node;
-           }
+      /* Addressing mode "symbol + base[+ index[<< scale]] [+ offset]".  */
+      if (parts.symbol != NULL_TREE
+         && !valid_mem_ref_p (mem_mode, as, &parts, code))
+       {
+         aff_combination_add_elt (aff_inv, parts.symbol, 1);
+         parts.symbol = NULL_TREE;
+         /* Reset SIMPLE_INV since symbol address needs to be computed
+            outside of address expression in this case.  */
+         simple_inv = false;
+         /* Symbol part is moved back to base part, it can't be NULL.  */
+         parts.base = integer_one_node;
        }
-      else
-       parts.index = NULL_TREE;
     }
   else
     {
@@ -4787,6 +4784,7 @@ get_address_cost (struct ivopts_data *data, struct iv_use 
*use,
         neutralize such effects.  */
       cost.cost = adjust_setup_cost (data, cost.cost, true);
       cost.scratch = cost.cost;
+      cost.complexity += 1;
     }
 
   cost += var_cost;
-- 
2.43.0

Reply via email to