Hi all,

This is a simple patch to enable two simplifications for UNSIGNED_FLOAT
expression.

For the following rtx patterns, they can be simplified when the integer x can be
represented in float mode without precision loss:

float_truncate (float x) --> float x
float_extend (float x) --> float x

Those two simplifications are also applicable to UNSIGNED_FLOAT expression.

For example, compile the following code using aarch64-none-elf toolchain with -O1 flag.
double
f1 (uint16_t x)
{
  return (double)(float)x;
}
Before the change, the compiler generates the following code:
f1:
        uxth    w0, w0
        ucvtf   s0, w0
        fcvt    d0, s0
        ret
After the change, the following simplified asm code snipts are generated.
f1:
        uxth    w0, w0
        ucvtf   d0, w0
        ret


aarch64-none-elf regression test runs Okay. x86_64 bootstraps Okay.
Okay to commit?

gcc/ChangeLog:

2015-03-20  Renlin Li  <renlin...@arm.com>

    * simplify-rtx.c (simplify_unary_operation_1): Fix a typo. Enable two
    simplifications for UNSIGNED_FLOAT.

gcc/testsuite/ChangeLog:

2015-03-20  Renlin Li  <renlin...@arm.com>

    * gcc.target/aarch64/unsigned-float.c: New.
    * gcc.target/arm/unsigned-float.c: New.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 5d17498..4b18d3c 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1171,7 +1171,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
          = (float_truncate:SF foo:DF).
 
          (float_truncate:DF (float_extend:XF foo:SF))
-         = (float_extend:SF foo:DF).  */
+         = (float_extend:DF foo:SF).  */
       if ((GET_CODE (op) == FLOAT_TRUNCATE
 	   && flag_unsafe_math_optimizations)
 	  || GET_CODE (op) == FLOAT_EXTEND)
@@ -1183,14 +1183,14 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 				   XEXP (op, 0), mode);
 
       /*  (float_truncate (float x)) is (float x)  */
-      if (GET_CODE (op) == FLOAT
+      if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
 	  && (flag_unsafe_math_optimizations
 	      || (SCALAR_FLOAT_MODE_P (GET_MODE (op))
 		  && ((unsigned)significand_size (GET_MODE (op))
 		      >= (GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))
 			  - num_sign_bit_copies (XEXP (op, 0),
 						 GET_MODE (XEXP (op, 0))))))))
-	return simplify_gen_unary (FLOAT, mode,
+	return simplify_gen_unary (GET_CODE (op), mode,
 				   XEXP (op, 0),
 				   GET_MODE (XEXP (op, 0)));
 
@@ -1221,7 +1221,7 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
 	  rounding can't happen.
           */
       if (GET_CODE (op) == FLOAT_EXTEND
-	  || (GET_CODE (op) == FLOAT
+	  || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
 	      && SCALAR_FLOAT_MODE_P (GET_MODE (op))
 	      && ((unsigned)significand_size (GET_MODE (op))
 		  >= (GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))
diff --git a/gcc/testsuite/gcc.target/aarch64/unsigned-float.c b/gcc/testsuite/gcc.target/aarch64/unsigned-float.c
new file mode 100644
index 0000000..c5ad680
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/unsigned-float.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include <stdint.h>
+
+double
+f1 (uint16_t x)
+{
+  return (double)(float)x;
+}
+
+float
+f2 (uint16_t x)
+{
+  return (float)(double)x;
+}
+
+/* { dg-final { scan-assembler-not "fcvt" } } */
diff --git a/gcc/testsuite/gcc.target/arm/unsigned-float.c b/gcc/testsuite/gcc.target/arm/unsigned-float.c
new file mode 100644
index 0000000..bb05c85
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/unsigned-float.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp_ok } */
+/* { dg-options "-march=armv7-a -O1 -mfloat-abi=softfp" } */
+/* { dg-skip-if "need fp instructions" { *-*-* } { "-mfloat-abi=soft" } { "" } } */
+
+#include <stdint.h>
+
+double
+f1 (uint16_t x)
+{
+  return (double)(float)x;
+}
+
+float
+f2 (uint16_t x)
+{
+  return (float)(double)x;
+}
+
+/* { dg-final { scan-assembler-not "vcvt.(f32.f64|f64.f32)" } } */

Reply via email to