This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR target/66824: -miamcu doesn't load FP constant into register directly


On Thu, Jul 09, 2015 at 12:13:38PM -0700, H.J. Lu wrote:
> ix86_split_long_move can optimize floating point constant move, which
> can be used to optimize SFmode move for IA MCU.
> 
> OK for trunk if there is no regression?
> 
> 
> H.J.
> ---
> gcc/
> 
> 	PR target/66824
> 	* config/i386/i386.c (ix86_split_to_parts): Allow SFmode move
> 	for IA MCU.
> 	(ix86_split_long_move): Support single move.
> 	* config/i386/i386.md (FP splitter): Allow SFmode for IA MCU.
> 
> gcc/testsuite/
> 
> 	PR target/66824
> 	* gcc.target/i386/pr66824.c: New test.
> ---


I missed the testcase.  Here is the updated patch.

H.J.
---
---
 gcc/config/i386/i386.c                  | 14 +++++++++++++-
 gcc/config/i386/i386.md                 |  3 ++-
 gcc/testsuite/gcc.target/i386/pr66824.c | 23 +++++++++++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr66824.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a18c733..d2925bc 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -22744,7 +22744,9 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode)
     size = (GET_MODE_SIZE (mode) + 4) / 8;
 
   gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
-  gcc_assert (size >= 2 && size <= 4);
+  /* For IA MCU, we can optimize SFmode move.  */
+  gcc_assert ((size >= 2 || (TARGET_IAMCU && mode == SFmode))
+	      && size <= 4);
 
   /* Optimize constant pool reference to immediates.  This is used by fp
      moves, that force all constants to memory to allow combining.  */
@@ -22822,10 +22824,14 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode)
 		case DFmode:
 		  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
 		  break;
+		case SFmode:
+		  REAL_VALUE_TO_TARGET_SINGLE (r, l[0]);
+		  goto part0;
 		default:
 		  gcc_unreachable ();
 		}
 	      parts[1] = gen_int_mode (l[1], SImode);
+part0:
 	      parts[0] = gen_int_mode (l[0], SImode);
 	    }
 	  else
@@ -22932,6 +22938,12 @@ ix86_split_long_move (rtx operands[])
   nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0]));
   ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0]));
 
+  if (nparts == 1)
+    {
+      emit_move_insn (part[0][0], part[1][0]);
+      return;
+    }
+
   /* When emitting push, take care for source operands on the stack.  */
   if (push && MEM_P (operands[1])
       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1d43aaf..e723eab 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3507,7 +3507,8 @@
   "reload_completed
    && (GET_MODE (operands[0]) == TFmode
        || GET_MODE (operands[0]) == XFmode
-       || GET_MODE (operands[0]) == DFmode)
+       || GET_MODE (operands[0]) == DFmode
+       || (TARGET_IAMCU && GET_MODE (operands[0]) == SFmode))
    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
   [(const_int 0)]
   "ix86_split_long_move (operands); DONE;")
diff --git a/gcc/testsuite/gcc.target/i386/pr66824.c b/gcc/testsuite/gcc.target/i386/pr66824.c
new file mode 100644
index 0000000..0966736
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr66824.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -miamcu" } */
+/* { dg-final { scan-assembler-not "\.LC\[0-9\]" } } */
+
+double foo (float);
+
+double
+f1 (void)
+{
+  return foo (1.0);
+}
+
+double
+f2 (void)
+{
+  return foo (0.0);
+}
+
+void
+f3 (float *x, float t)
+{
+  *x = 0.0 + t;
+}
-- 
2.4.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]