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 } } */
