https://gcc.gnu.org/g:bf80c1b42670f9783eaf2a1bc7c6e05428b9d931

commit r17-3865-gbf80c1b42670f9783eaf2a1bc7c6e05428b9d931
Author: Roger Sayle <[email protected]>
Date:   Wed Sep 2 16:39:23 2026 +0100

    aarch64: Use any_or_plus in movk define_insn pattern.
    
    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
    
    2026-09-02  Roger Sayle  <[email protected]>
    
    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.

Diff:
---
 gcc/config/aarch64/aarch64.md             |  9 +++++----
 gcc/testsuite/gcc.target/aarch64/movk_4.c | 12 ++++++++++++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9e441fa7946e..715de93fd516 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1928,11 +1928,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 000000000000..1173e58cf0ff
--- /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 } } */

Reply via email to