On Wed, Mar 4, 2026 at 2:49 PM Radosav Krunic
<[email protected]> wrote:
>
> 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]>

Please state how you tested this patch.

> 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