[AArch64] Use any_or_plus in movk define_insn pattern.

Message ID 003f01dd3a3e$2aa73f10$7ff5bd30$@nextmovesoftware.com
State New
Headers
Series [AArch64] Use any_or_plus in movk define_insn pattern. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply

Commit Message

Roger Sayle Sept. 1, 2026, 6:17 p.m. UTC
  Many thanks to Linaroo's CI tester (and the folks that run it) for
pointing out that my (upcoming) patch to introduce aop_optab triggers
a testsuite failure on aarch64.  The issue is a missed optimization:
the aarch.md backend recognizes the IOR form of movk, but not the
PLUS (or XOR) forms.  Easily fixed/avoided with the small change
below.

As a motivating example, consider the function:

unsigned int foo(unsigned int x)
{
  return (x & ~0xffff) + 0x02;
}

Currently with gcc -O2, we generate:

foo:    and     w0, w0, -65536
        add     w0, w0, 2
        ret

with this patch, we instead generate:

foo:    movk    w0, #0x2, lsl 0
        ret


This patch has been tested on aarch64-apple-darwin24.3.0 (using
iains' fork) with make bootstrap and make -k check with no new
failures.  Ok for mainline?


2026-09-01  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
        * config/aarch64/aarch64.md (*aarch_movk<mode>): Prepend asterisk.
        Use any_or_plus iterator to also recognize PLUS and XOR forms.

gcc/testsuite/ChangeLog
        * gcc.target/aarch64/movk_4.c: New test case.


Thank in advance,
Roger
--
  

Comments

Kyrylo Tkachov Sept. 2, 2026, 11:58 a.m. UTC | #1
> On 1 Sep 2026, at 20:17, Roger Sayle <roger@nextmovesoftware.com> wrote:
> 
> 
> Many thanks to Linaroo's CI tester (and the folks that run it) for
> pointing out that my (upcoming) patch to introduce aop_optab triggers
> a testsuite failure on aarch64.  The issue is a missed optimization:
> the aarch.md backend recognizes the IOR form of movk, but not the
> PLUS (or XOR) forms.  Easily fixed/avoided with the small change
> below.
> 
> As a motivating example, consider the function:
> 
> unsigned int foo(unsigned int x)
> {
>  return (x & ~0xffff) + 0x02;
> }
> 
> Currently with gcc -O2, we generate:
> 
> foo:    and     w0, w0, -65536
>        add     w0, w0, 2
>        ret
> 
> with this patch, we instead generate:
> 
> foo:    movk    w0, #0x2, lsl 0
>        ret
> 
> 
> This patch has been tested on aarch64-apple-darwin24.3.0 (using
> iains' fork) with make bootstrap and make -k check with no new
> failures.  Ok for mainline?
> 

Nice, ok.
Thanks,
Kyrill

> 
> 2026-09-01  Roger Sayle  <roger@nextmovesoftware.com>
> 
> gcc/ChangeLog
>        * config/aarch64/aarch64.md (*aarch_movk<mode>): Prepend asterisk.
>        Use any_or_plus iterator to also recognize PLUS and XOR forms.
> 
> gcc/testsuite/ChangeLog
>        * gcc.target/aarch64/movk_4.c: New test case.
> 
> 
> Thank in advance,
> Roger
> --
> 
> <patchaa.txt>
  

Patch

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 8e844beaee9..b3452d89989 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1915,11 +1915,12 @@ 
 )
 
 ;; Match MOVK as a normal AND and IOR operation.
-(define_insn "aarch64_movk<mode>"
+(define_insn "*aarch64_movk<mode>"
   [(set (match_operand:GPI 0 "register_operand" "=r")
-	(ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "0")
-			  (match_operand:GPI 2 "const_int_operand"))
-		 (match_operand:GPI 3 "const_int_operand")))]
+	(any_or_plus:GPI
+	  (and:GPI (match_operand:GPI 1 "register_operand" "0")
+		   (match_operand:GPI 2 "const_int_operand"))
+	  (match_operand:GPI 3 "const_int_operand")))]
   "aarch64_movk_shift (rtx_mode_t (operands[2], <MODE>mode),
 		       rtx_mode_t (operands[3], <MODE>mode)) >= 0"
   {
diff --git a/gcc/testsuite/gcc.target/aarch64/movk_4.c b/gcc/testsuite/gcc.target/aarch64/movk_4.c
new file mode 100644
index 00000000000..1173e58cf0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/movk_4.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int iorhi(unsigned int x) { return (x & 0xffff) | 0x20000; }
+unsigned int xorhi(unsigned int x) { return (x & 0xffff) ^ 0x20000; }
+unsigned int addhi(unsigned int x) { return (x & 0xffff) + 0x20000; }
+
+unsigned int iorlo(unsigned int x) { return (x & ~0xffff) | 0x02; }
+unsigned int xorlo(unsigned int x) { return (x & ~0xffff) ^ 0x02; }
+unsigned int addlo(unsigned int x) { return (x & ~0xffff) + 0x02; }
+
+/* { dg-final { scan-assembler-times "movk\t" 6 } } */