]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Improve rtx_cost for constants in COMPARE [PR120372]
authorAndrew Pinski <quic_apinski@quicinc.com>
Tue, 20 May 2025 22:10:15 +0000 (15:10 -0700)
committerAndrew Pinski <quic_apinski@quicinc.com>
Thu, 22 May 2025 13:09:46 +0000 (06:09 -0700)
The middle-end uses rtx_cost on constants with the outer of being COMPARE
to find out the cost of a constant formation for a comparison instruction.
So for aarch64 backend, we would just return the cost of constant formation
in general. We can improve this by seeing if the outer is COMPARE and if
the constant fits the constraints of the cmp instruction just set the costs
to being one instruction.

Built and tested for aarch64-linux-gnu.

PR target/120372

gcc/ChangeLog:

* config/aarch64/aarch64.cc (aarch64_rtx_costs <case CONST_INSN>): Handle
if outer is COMPARE and the constant can be handled by the cmp instruction.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/imm_choice_comparison-2.c: New test.

Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
gcc/config/aarch64/aarch64.cc
gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c [new file with mode: 0644]

index 2b837ec8e6736e5c879f445da34f8ab5401c18aa..ecb0bac2e5501f638f8e4f933af4d430ab96abe0 100644 (file)
@@ -14578,6 +14578,13 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED,
         we don't need to consider that here.  */
       if (x == const0_rtx)
        *cost = 0;
+      /* If the outer is a COMPARE which is used by the middle-end
+        and the constant fits how the cmp instruction allows, say the cost
+        is the same as 1 insn.  */
+      else if (outer == COMPARE
+              && (aarch64_uimm12_shift (INTVAL (x))
+                  || aarch64_uimm12_shift (-UINTVAL (x))))
+       *cost = COSTS_N_INSNS (1);
       else
        {
          /* To an approximation, building any other constant is
diff --git a/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c b/gcc/testsuite/gcc.target/aarch64/imm_choice_comparison-2.c
new file mode 100644 (file)
index 0000000..379fc50
--- /dev/null
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* PR target/120372 */
+
+/* Go from 2 moves to none.  */
+
+/*
+** GT:
+**     ...
+**     cmp     w0, 11182080
+**     ...
+*/
+
+int
+GT (unsigned int x)
+{
+  return x > 0xaa9fff;
+}
+
+/*
+** LE:
+**     ...
+**     cmp     w0, 11182080
+**     ...
+*/
+
+int
+LE (unsigned int x)
+{
+  return x <= 0xaa9fff;
+}
+
+/*
+** GE:
+**     ...
+**     cmp     x0, 11182080
+**     ...
+*/
+
+int
+GE (long long x)
+{
+  return x >= 0xaaa000;
+}
+
+/*
+** LT:
+**     ...
+**     cmp     w0, 11182080
+**     ...
+*/
+
+int
+LT (int x)
+{
+  return x < 0xaaa000;
+}
+
+/* Optimize the immediate in conditionals.  */
+
+/*
+** check:
+**     ...
+**     cmp     w0, 11182080
+**     ...
+*/
+
+int
+check (int x, int y)
+{
+  if (x > y && GT (x))
+    return 100;
+
+  return x;
+}
+
+/*
+** tern:
+**     ...
+**     cmp     w0, 11182080
+**     ...
+*/
+
+int
+tern (int x)
+{
+  return x >= 0xaaa000 ? 5 : -3;
+}