On Mon, Jan 12, 2026 at 10:13 AM Wilco Dijkstra <[email protected]> wrote: > > > Improve immediate generation to support 2-instruction MOV+ADD/SUB > of 12-bit shifted immediate. Eg. > > long f1 (void) > { > return 0x123400567000; > } > > now generates: > > mov x0, 20014547599360 > add x0, x0, 5664768 > ret > > Passes regress, OK for commit?
I am trying to compare this to what Eikansh implemented last year: https://patchwork.sourceware.org/project/gcc/patch/[email protected]/ He is in the process of updating his patch (other things came up internally). One thing he had noticed while working on it was that putting it too early meant that the 2 instruction mov/movk form was not being generated when they still should be. mov/movk form is fused on some micro-arch (AARCH64_FUSE_MOV_MOVK) so we had wanted to keep that output around. For an example his f4 (0xffffffff0001fedc) would be better if done using mov/movk rather than mov/sub. Thanks, Andrew > > gcc: > PR target/114528 > * config/aarch64/aarch64.cc (aarch64_check_mov_add_imm12): > New function to check and emit MOV+ADD/SUB immediates. > (aarch64_internal_mov_immediate): Add support for MOV+ADD/SUB > immediates. > > gcc/testsuite: > PR target/114528 > * gcc.target/aarch64/pr114528.c: New test. > > --- > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index > 293afa52b3b38781b765ca939ed51c280313bab4..4784d3dadc5c8811e84d042bcb24cf2928520219 > 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -4915,6 +4915,26 @@ aarch64_move_imm (unsigned HOST_WIDE_INT val, > machine_mode mode) > } > > > +/* Return true is VAL is a move immediate that can be created by add/sub of > the > + 12-bit shifted immediate VAL2. If GENERATE is true, emit the sequence. > */ > +static inline bool > +aarch64_check_mov_add_imm12 (rtx dest, unsigned HOST_WIDE_INT val, > + unsigned HOST_WIDE_INT val2, bool generate) > +{ > + if (!aarch64_move_imm (val - val2, DImode)) > + { > + val2 = val2 < 0x1000000 ? val2 - 0x1000000 : val2 + 0x1000000; > + if (!aarch64_move_imm (val - val2, DImode)) > + return false; > + } > + if (generate) > + { > + emit_insn (gen_rtx_SET (dest, GEN_INT (val - val2))); > + emit_insn (gen_adddi3 (dest, dest, GEN_INT (val2))); > + } > + return true; > +} > + > static int > aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate, > machine_mode mode) > @@ -5003,6 +5023,14 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, > bool generate, > } > return 2; > } > + > + /* Try a mov/bitmask immediate with a shifted add/sub. */ > + val2 = val & 0xfff000; > + val3 = val2 - ((val >> 32) & 0xfff000); > + if (aarch64_check_mov_add_imm12 (dest, val, val2, generate) > + || aarch64_check_mov_add_imm12 (dest, val, val2 - 0xfff000, > generate) > + || aarch64_check_mov_add_imm12 (dest, val, val3, generate)) > + return 2; > } > > /* Try a bitmask plus 2 movk to generate the immediate in 3 instructions. > */ > @@ -5073,7 +5101,7 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool > generate, > if (generate) > emit_insn (gen_insv_immdi (dest, GEN_INT (i), > GEN_INT ((val >> i) & 0xffff))); > - num_insns ++; > + num_insns++; > } > > return num_insns; > diff --git a/gcc/testsuite/gcc.target/aarch64/pr114528.c > b/gcc/testsuite/gcc.target/aarch64/pr114528.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..9cfe15abc33cddfb42175fd254f0bf8c06cbb564 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/pr114528.c > @@ -0,0 +1,76 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > +/* { dg-final { check-function-bodies "**" "" } } */ > + > + > +/* > +** f1: > +** mov x0, 20014547599360 > +** add x0, x0, 5664768 > +** ret > +*/ > + > +long f1 (void) > +{ > + return 0x123400567000; > +} > + > +/* > +** f2: > +** mov x0, 20014547599360 > +** sub x0, x0, #11112448 > +** ret > +*/ > + > +long f2 (void) > +{ > + return 0x1233ff567000; > +} > + > +/* > +** f3: > +** mov x0, 1311673391471656959 > +** add x0, x0, 5668864 > +** ret > +*/ > + > +long f3 (void) > +{ > + return 0x1234000000567fff; > +} > + > +/* > +** f4: > +** mov x0, 1312236341425078271 > +** sub x0, x0, #11108352 > +** ret > +*/ > + > +long f4 (void) > +{ > + return 0x1235ffffff567fff; > +} > + > +/* > +** f5: > +** mov x0, 8102099357864587376 > +** add x0, x0, 10600448 > +** ret > +*/ > + > +long f5 (void) > +{ > + return 0x7070707071123070; > +} > + > +/* > +** f6: > +** mov x0, 8102099357864587376 > +** sub x0, x0, #8273920 > +** ret > +*/ > + > +long f6 (void) > +{ > + return 0x707070706ff23070; > +} > >
