[AArch64] Add support for 16-bit FMOV immediates

Message ID 878t684es0.fsf@arm.com
State New
Headers show
Series
  • [AArch64] Add support for 16-bit FMOV immediates
Related show

Commit Message

Richard Sandiford July 18, 2018, 5:47 p.m.
aarch64_float_const_representable_p was still returning false for
HFmode, so we wouldn't use 16-bit FMOV immediate.  E.g. before the
patch:

    __fp16 foo (void) { return 0x1.1p-3; }

gave:

       mov     w0, 12352
       fmov    h0, w0

with -march=armv8.2-a+fp16, whereas now it gives:

       fmov    h0, 1.328125e-1

Tested on aarch64-linux-gnu, both with and without SVE.  OK to install?

Richard


2018-07-18  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* config/aarch64/aarch64.c (aarch64_float_const_representable_p):
	Allow HFmode constants if TARGET_FP_F16INST.

gcc/testsuite/
	* gcc.target/aarch64/f16_mov_immediate_1.c: Expect fmov immediate
	to be used.
	* gcc.target/aarch64/f16_mov_immediate_2.c: Likewise.
	* gcc.target/aarch64/f16_mov_immediate_3.c: Force +nofp16.
	* gcc.target/aarch64/sve/single_1.c: Except fmov immediate to be used
	for .h.
	* gcc.target/aarch64/sve/single_2.c: Likewise.
	* gcc.target/aarch64/sve/single_3.c: Likewise.
	* gcc.target/aarch64/sve/single_4.c: Likewise.

Comments

James Greenhalgh July 31, 2018, 9:44 p.m. | #1
On Wed, Jul 18, 2018 at 12:47:27PM -0500, Richard Sandiford wrote:
> aarch64_float_const_representable_p was still returning false for

> HFmode, so we wouldn't use 16-bit FMOV immediate.  E.g. before the

> patch:

> 

>     __fp16 foo (void) { return 0x1.1p-3; }

> 

> gave:

> 

>        mov     w0, 12352

>        fmov    h0, w0

> 

> with -march=armv8.2-a+fp16, whereas now it gives:

> 

>        fmov    h0, 1.328125e-1

> 

> Tested on aarch64-linux-gnu, both with and without SVE.  OK to install?


OK.

Thanks,
James

> 

> Richard

> 

> 

> 2018-07-18  Richard Sandiford  <richard.sandiford@arm.com>

> 

> gcc/

> 	* config/aarch64/aarch64.c (aarch64_float_const_representable_p):

> 	Allow HFmode constants if TARGET_FP_F16INST.

> 

> gcc/testsuite/

> 	* gcc.target/aarch64/f16_mov_immediate_1.c: Expect fmov immediate

> 	to be used.

> 	* gcc.target/aarch64/f16_mov_immediate_2.c: Likewise.

> 	* gcc.target/aarch64/f16_mov_immediate_3.c: Force +nofp16.

> 	* gcc.target/aarch64/sve/single_1.c: Except fmov immediate to be used

> 	for .h.

> 	* gcc.target/aarch64/sve/single_2.c: Likewise.

> 	* gcc.target/aarch64/sve/single_3.c: Likewise.

> 	* gcc.target/aarch64/sve/single_4.c: Likewise.

> 

> Index: gcc/config/aarch64/aarch64.c

> ===================================================================

> --- gcc/config/aarch64/aarch64.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/config/aarch64/aarch64.c	2018-07-18 18:45:27.025332090 +0100

> @@ -14908,8 +14908,8 @@ aarch64_float_const_representable_p (rtx

>    if (!CONST_DOUBLE_P (x))

>      return false;

>  

> -  /* We don't support HFmode constants yet.  */

> -  if (GET_MODE (x) == VOIDmode || GET_MODE (x) == HFmode)

> +  if (GET_MODE (x) == VOIDmode

> +      || (GET_MODE (x) == HFmode && !TARGET_FP_F16INST))

>      return false;

>  

>    r = *CONST_DOUBLE_REAL_VALUE (x);

> Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c	2018-07-18 18:45:27.025332090 +0100

> @@ -44,6 +44,6 @@ __fp16 f5 ()

>    return a;

>  }

>  

> -/* { dg-final { scan-assembler-times "mov\tw\[0-9\]+, #?19520"           3 } } */

> -/* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0xbc, lsl 8"  1 } } */

> -/* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x4c, lsl 8"  1 } } */

> +/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1\.7e\+1}  3 } } */

> +/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?-1\.0e\+0} 1 } } */

> +/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1\.6e\+1}  1 } } */

> Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c	2018-07-18 18:45:27.025332090 +0100

> @@ -40,6 +40,4 @@ float16_t f3(void)

>  /* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x5c, lsl 8" 1 } } */

>  /* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x7c, lsl 8" 1 } } */

>  

> -/* { dg-final { scan-assembler-times "mov\tw\[0-9\]+, 19520"              1 } } */

> -/* { dg-final { scan-assembler-times "fmov\th\[0-9\], w\[0-9\]+"          1 } } */

> -

> +/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1.7e\+1}           1 } } */

> Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c	2018-07-18 18:45:27.025332090 +0100

> @@ -1,6 +1,8 @@

>  /* { dg-do compile } */

>  /* { dg-options "-O2" } */

>  

> +#pragma GCC target "+nofp16"

> +

>  __fp16 f4 ()

>  {

>    __fp16 a = 0.1;

> Index: gcc/testsuite/gcc.target/aarch64/sve/single_1.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/sve/single_1.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/sve/single_1.c	2018-07-18 18:45:27.025332090 +0100

> @@ -36,7 +36,7 @@ TEST_LOOP (double, 3.0)

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */

> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */

> +/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */

>  

> Index: gcc/testsuite/gcc.target/aarch64/sve/single_2.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/sve/single_2.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/sve/single_2.c	2018-07-18 18:45:27.025332090 +0100

> @@ -12,7 +12,7 @@ #define N 64

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */

> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */

> +/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */

>  

> Index: gcc/testsuite/gcc.target/aarch64/sve/single_3.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/sve/single_3.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/sve/single_3.c	2018-07-18 18:45:27.025332090 +0100

> @@ -12,7 +12,7 @@ #define N 128

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */

> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */

> +/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */

>  

> Index: gcc/testsuite/gcc.target/aarch64/sve/single_4.c

> ===================================================================

> --- gcc/testsuite/gcc.target/aarch64/sve/single_4.c	2018-07-18 18:45:26.000000000 +0100

> +++ gcc/testsuite/gcc.target/aarch64/sve/single_4.c	2018-07-18 18:45:27.025332090 +0100

> @@ -12,7 +12,7 @@ #define N 256

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */

> -/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */

> +/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */

>  /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */

>

Patch

Index: gcc/config/aarch64/aarch64.c
===================================================================
--- gcc/config/aarch64/aarch64.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/config/aarch64/aarch64.c	2018-07-18 18:45:27.025332090 +0100
@@ -14908,8 +14908,8 @@  aarch64_float_const_representable_p (rtx
   if (!CONST_DOUBLE_P (x))
     return false;
 
-  /* We don't support HFmode constants yet.  */
-  if (GET_MODE (x) == VOIDmode || GET_MODE (x) == HFmode)
+  if (GET_MODE (x) == VOIDmode
+      || (GET_MODE (x) == HFmode && !TARGET_FP_F16INST))
     return false;
 
   r = *CONST_DOUBLE_REAL_VALUE (x);
Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_1.c	2018-07-18 18:45:27.025332090 +0100
@@ -44,6 +44,6 @@  __fp16 f5 ()
   return a;
 }
 
-/* { dg-final { scan-assembler-times "mov\tw\[0-9\]+, #?19520"           3 } } */
-/* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0xbc, lsl 8"  1 } } */
-/* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x4c, lsl 8"  1 } } */
+/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1\.7e\+1}  3 } } */
+/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?-1\.0e\+0} 1 } } */
+/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1\.6e\+1}  1 } } */
Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_2.c	2018-07-18 18:45:27.025332090 +0100
@@ -40,6 +40,4 @@  float16_t f3(void)
 /* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x5c, lsl 8" 1 } } */
 /* { dg-final { scan-assembler-times "movi\tv\[0-9\]+\\\.4h, 0x7c, lsl 8" 1 } } */
 
-/* { dg-final { scan-assembler-times "mov\tw\[0-9\]+, 19520"              1 } } */
-/* { dg-final { scan-assembler-times "fmov\th\[0-9\], w\[0-9\]+"          1 } } */
-
+/* { dg-final { scan-assembler-times {fmov\th[0-9]+, #?1.7e\+1}           1 } } */
Index: gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/f16_mov_immediate_3.c	2018-07-18 18:45:27.025332090 +0100
@@ -1,6 +1,8 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O2" } */
 
+#pragma GCC target "+nofp16"
+
 __fp16 f4 ()
 {
   __fp16 a = 0.1;
Index: gcc/testsuite/gcc.target/aarch64/sve/single_1.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/sve/single_1.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/sve/single_1.c	2018-07-18 18:45:27.025332090 +0100
@@ -36,7 +36,7 @@  TEST_LOOP (double, 3.0)
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
 
Index: gcc/testsuite/gcc.target/aarch64/sve/single_2.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/sve/single_2.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/sve/single_2.c	2018-07-18 18:45:27.025332090 +0100
@@ -12,7 +12,7 @@  #define N 64
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
 
Index: gcc/testsuite/gcc.target/aarch64/sve/single_3.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/sve/single_3.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/sve/single_3.c	2018-07-18 18:45:27.025332090 +0100
@@ -12,7 +12,7 @@  #define N 128
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
 
Index: gcc/testsuite/gcc.target/aarch64/sve/single_4.c
===================================================================
--- gcc/testsuite/gcc.target/aarch64/sve/single_4.c	2018-07-18 18:45:26.000000000 +0100
+++ gcc/testsuite/gcc.target/aarch64/sve/single_4.c	2018-07-18 18:45:27.025332090 +0100
@@ -12,7 +12,7 @@  #define N 256
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.s, #6\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #7\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #8\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, #15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #1\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */