AArch64: Improve immediate generation
Further improve immediate generation by adding support for 2-instruction MOV/EOR bitmask immediates. This reduces the number of 3/4-instruction immediates in SPECCPU2017 by ~2%. Reviewed-by: Richard Earnshaw <Richard.Earnshaw@arm.com> gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_internal_mov_immediate) Add support for immediates using MOV/EOR bitmask. gcc/testsuite: * gcc.target/aarch64/imm_choice_comparison.c: Change tests. * gcc.target/aarch64/moveor_imm.c: Add new test. * gcc.target/aarch64/pr106583.c: Change tests.
This commit is contained in:
parent
406709b1c7
commit
668c4c3783
4 changed files with 207 additions and 11 deletions
|
@ -5748,6 +5748,26 @@ aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
|
|||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Try 2 bitmask immediates which are xor'd together. */
|
||||
for (i = 0; i < 64; i += 16)
|
||||
{
|
||||
val2 = (val >> i) & mask;
|
||||
val2 |= val2 << 16;
|
||||
val2 |= val2 << 32;
|
||||
if (aarch64_bitmask_imm (val2) && aarch64_bitmask_imm (val ^ val2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i != 64)
|
||||
{
|
||||
if (generate)
|
||||
{
|
||||
emit_insn (gen_rtx_SET (dest, GEN_INT (val2)));
|
||||
emit_insn (gen_xordi3 (dest, dest, GEN_INT (val ^ val2)));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try a bitmask plus 2 movk to generate the immediate in 3 instructions. */
|
||||
|
|
|
@ -1,32 +1,69 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/* Go from four moves to two. */
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** ...
|
||||
** mov w[0-9]+, 2576980377
|
||||
** movk x[0-9]+, 0x9999, lsl 32
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
foo (long long x)
|
||||
{
|
||||
return x <= 0x1999999999999998;
|
||||
return x <= 0x0000999999999998;
|
||||
}
|
||||
|
||||
/*
|
||||
** GT:
|
||||
** ...
|
||||
** mov w[0-9]+, -16777217
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
GT (unsigned int x)
|
||||
{
|
||||
return x > 0xfefffffe;
|
||||
}
|
||||
|
||||
/*
|
||||
** LE:
|
||||
** ...
|
||||
** mov w[0-9]+, -16777217
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
LE (unsigned int x)
|
||||
{
|
||||
return x <= 0xfefffffe;
|
||||
}
|
||||
|
||||
/*
|
||||
** GE:
|
||||
** ...
|
||||
** mov w[0-9]+, 4278190079
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
GE (long long x)
|
||||
{
|
||||
return x >= 0xff000000;
|
||||
}
|
||||
|
||||
/*
|
||||
** LT:
|
||||
** ...
|
||||
** mov w[0-9]+, -16777217
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
LT (int x)
|
||||
{
|
||||
|
@ -35,6 +72,13 @@ LT (int x)
|
|||
|
||||
/* Optimize the immediate in conditionals. */
|
||||
|
||||
/*
|
||||
** check:
|
||||
** ...
|
||||
** mov w[0-9]+, -16777217
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
check (int x, int y)
|
||||
{
|
||||
|
@ -44,11 +88,15 @@ check (int x, int y)
|
|||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
** tern:
|
||||
** ...
|
||||
** mov w[0-9]+, -16777217
|
||||
** ...
|
||||
*/
|
||||
|
||||
int
|
||||
tern (int x)
|
||||
{
|
||||
return x >= 0xff000000 ? 5 : -3;
|
||||
}
|
||||
|
||||
/* baz produces one movk instruction. */
|
||||
/* { dg-final { scan-assembler-times "movk" 1 } } */
|
||||
|
|
68
gcc/testsuite/gcc.target/aarch64/moveor_imm.c
Normal file
68
gcc/testsuite/gcc.target/aarch64/moveor_imm.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** f1:
|
||||
** ...
|
||||
** mov x0, -6148914691236517206
|
||||
** eor x0, x0, -9223372036854775807
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f1 (void)
|
||||
{
|
||||
return 0x2aaaaaaaaaaaaaab;
|
||||
}
|
||||
|
||||
/*
|
||||
** f2:
|
||||
** ...
|
||||
** mov x0, -1085102592571150096
|
||||
** eor x0, x0, -2305843009213693951
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f2 (void)
|
||||
{
|
||||
return 0x10f0f0f0f0f0f0f1;
|
||||
}
|
||||
|
||||
/*
|
||||
** f3:
|
||||
** ...
|
||||
** mov x0, -3689348814741910324
|
||||
** eor x0, x0, -4611686018427387903
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f3 (void)
|
||||
{
|
||||
return 0xccccccccccccccd;
|
||||
}
|
||||
|
||||
/*
|
||||
** f4:
|
||||
** ...
|
||||
** mov x0, -7378697629483820647
|
||||
** eor x0, x0, -9223372036854775807
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f4 (void)
|
||||
{
|
||||
return 0x1999999999999998;
|
||||
}
|
||||
|
||||
/*
|
||||
** f5:
|
||||
** ...
|
||||
** mov x0, 3689348814741910323
|
||||
** eor x0, x0, 864691128656461824
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f5 (void)
|
||||
{
|
||||
return 0x3f3333333f333333;
|
||||
}
|
|
@ -1,41 +1,101 @@
|
|||
/* { dg-do assemble } */
|
||||
/* { dg-options "-O2 --save-temps" } */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { check-function-bodies "**" "" } } */
|
||||
|
||||
/*
|
||||
** f1:
|
||||
** ...
|
||||
** mov x0, -72340172838076674
|
||||
** movk x0, 0xfeff, lsl 0
|
||||
** movk x0, 0x75fe, lsl 48
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f1 (void)
|
||||
{
|
||||
return 0x7efefefefefefeff;
|
||||
return 0x75fefefefefefeff;
|
||||
}
|
||||
|
||||
/*
|
||||
** f2:
|
||||
** ...
|
||||
** mov x0, -6148914691236517206
|
||||
** movk x0, 0x5678, lsl 32
|
||||
** movk x0, 0x1234, lsl 48
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f2 (void)
|
||||
{
|
||||
return 0x12345678aaaaaaaa;
|
||||
}
|
||||
|
||||
/*
|
||||
** f3:
|
||||
** ...
|
||||
** mov x0, -3689348814741910324
|
||||
** movk x0, 0x5678, lsl 0
|
||||
** movk x0, 0x1234, lsl 48
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f3 (void)
|
||||
{
|
||||
return 0x1234cccccccc5678;
|
||||
}
|
||||
|
||||
/*
|
||||
** f4:
|
||||
** ...
|
||||
** mov x0, 8608480567731124087
|
||||
** movk x0, 0x5678, lsl 16
|
||||
** movk x0, 0x1234, lsl 32
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f4 (void)
|
||||
{
|
||||
return 0x7777123456787777;
|
||||
}
|
||||
|
||||
/*
|
||||
** f5:
|
||||
** ...
|
||||
** mov x0, 6148914691236517205
|
||||
** movk x0, 0x5678, lsl 0
|
||||
** movk x0, 0x1234, lsl 16
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f5 (void)
|
||||
{
|
||||
return 0x5555555512345678;
|
||||
}
|
||||
|
||||
/*
|
||||
** f6:
|
||||
** ...
|
||||
** mov x0, -4919131752989213765
|
||||
** movk x0, 0x5678, lsl 16
|
||||
** movk x0, 0x1234, lsl 48
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f6 (void)
|
||||
{
|
||||
return 0x1234bbbb5678bbbb;
|
||||
}
|
||||
|
||||
/*
|
||||
** f7:
|
||||
** ...
|
||||
** mov x0, 4919131752989213764
|
||||
** movk x0, 0x5678, lsl 0
|
||||
** movk x0, 0x1234, lsl 32
|
||||
** ...
|
||||
*/
|
||||
|
||||
long f7 (void)
|
||||
{
|
||||
return 0x4444123444445678;
|
||||
}
|
||||
|
||||
|
||||
/* { dg-final { scan-assembler-times {\tmovk\t} 14 } } */
|
||||
/* { dg-final { scan-assembler-times {\tmov\t} 7 } } */
|
||||
|
|
Loading…
Add table
Reference in a new issue