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]

plus_constant & stack temporaries in rs6000 fp<->int conversions


This fixes target/20813.

There are only really two substantive changes in this patch:

- plus_constant is no longer used anywhere in rs6000.md (yay!).
  plus_constant is undesirable because it doesn't propagate aliasing
  information.  adjust_address is also smarter: when !no_new_pseudos,
  it can take even non-offsettable addresses and adjust them.
- The patch makes all these patterns consistent in when they can be
  split: exactly those times when adjust_address would work.  This
  should give better scheduling but worse constant folding; since most
  constant folding happens on trees now, I think that should be
  better.

It also moves to define_insn_and_split, which shrinks the .md file a
bit.

Bootstrapped & tested on powerpc-darwin, with default options,
-mpowerpc64, and -mno-powerpc-gfxopt.  (I'm pleased to see that the
only additional tests that fail with either of the last two options
are tests that are trying to test -mno-powerpc64 or -mpowerpc-gfxopt!)

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-stfiwxplusconstant.patch==============
2005-04-29  Geoffrey Keating  <geoffk@apple.com>

	* config/rs6000/rs6000.md (floatsidf2_internal): Merge to create
	define_insn_and_split.  Split only when memory operand is
	offsettable.  Use adjust_address rather than plus_constant.
	(floatunssidf2_internal): Likewise.
	(fix_truncdfsi2_internal): Split only when memory operand is
	offsettable.  Use adjust_address rather than plus_constant.
	(fix_trunctfsi2_internal): Likewise.
	(floatsidf2_internal): Likewise.

Index: testsuite/ChangeLog
2005-05-02  Geoffrey Keating  <geoffk@apple.com>

	* gcc.dg/rs6000-fpint-2.c: New.

Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.362
diff -u -p -u -p -r1.362 rs6000.md
--- config/rs6000/rs6000.md	24 Apr 2005 12:53:31 -0000	1.362
+++ config/rs6000/rs6000.md	2 May 2005 23:22:23 -0000
@@ -5163,7 +5163,7 @@
   operands[6] = gen_reg_rtx (SImode);
 }")
 
-(define_insn "*floatsidf2_internal"
+(define_insn_and_split "*floatsidf2_internal"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
 	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
@@ -5173,30 +5173,14 @@
    (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  [(set_attr "length" "24")])
-
-(define_split
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
-   (use (match_operand:SI 2 "gpc_reg_operand" ""))
-   (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))
-   (clobber (match_operand:SI 6 "gpc_reg_operand" ""))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
-   (use (match_operand:SI 2 "gpc_reg_operand" ""))
-   (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))
-   (clobber (match_operand:SI 6 "gpc_reg_operand" ""))]
+  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
+  [(pc)]
   "
 {
   rtx lowword, highword;
-  gcc_assert (GET_CODE (operands[4]) == MEM);
-  highword = XEXP (operands[4], 0);
-  lowword = plus_constant (highword, 4);
+  gcc_assert (MEM_P (operands[4]));
+  highword = adjust_address (operands[4], SImode, 0);
+  lowword = adjust_address (operands[4], SImode, 4);
   if (! WORDS_BIG_ENDIAN)
     {
       rtx tmp;
@@ -5205,12 +5189,13 @@
 
   emit_insn (gen_xorsi3 (operands[6], operands[1],
 			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
-  emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[6]);
-  emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]);
+  emit_move_insn (lowword, operands[6]);
+  emit_move_insn (highword, operands[2]);
   emit_move_insn (operands[5], operands[4]);
   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
   DONE;
-}")
+}"
+  [(set_attr "length" "24")])
 
 (define_expand "floatunssisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
@@ -5249,7 +5234,7 @@
   operands[5] = gen_reg_rtx (DFmode);
 }")
 
-(define_insn "*floatunssidf2_internal"
+(define_insn_and_split "*floatunssidf2_internal"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
 	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
    (use (match_operand:SI 2 "gpc_reg_operand" "r"))
@@ -5258,40 +5243,27 @@
    (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
   "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  [(set_attr "length" "20")])
-
-(define_split
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
-   (use (match_operand:SI 2 "gpc_reg_operand" ""))
-   (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))]
-  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
-  [(set (match_operand:DF 0 "gpc_reg_operand" "")
-	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
-   (use (match_operand:SI 2 "gpc_reg_operand" ""))
-   (use (match_operand:DF 3 "gpc_reg_operand" ""))
-   (clobber (match_operand:DF 4 "offsettable_mem_operand" ""))
-   (clobber (match_operand:DF 5 "gpc_reg_operand" ""))]
+  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
+  [(pc)]
   "
 {
   rtx lowword, highword;
-  gcc_assert (GET_CODE (operands[4]) == MEM);
-  highword = XEXP (operands[4], 0);
-  lowword = plus_constant (highword, 4);
+  gcc_assert (MEM_P (operands[4]));
+  highword = adjust_address (operands[4], SImode, 0);
+  lowword = adjust_address (operands[4], SImode, 4);
   if (! WORDS_BIG_ENDIAN)
     {
       rtx tmp;
       tmp = highword; highword = lowword; lowword = tmp;
     }
 
-  emit_move_insn (gen_rtx_MEM (SImode, lowword), operands[1]);
-  emit_move_insn (gen_rtx_MEM (SImode, highword), operands[2]);
+  emit_move_insn (lowword, operands[1]);
+  emit_move_insn (highword, operands[2]);
   emit_move_insn (operands[5], operands[4]);
   emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
   DONE;
-}")
+}"
+  [(set_attr "length" "20")])
 
 ; In the TARGET_PPC_GFXOPT case, this could and probably should
 ; take a memory destination; but actually making this work is hard.
@@ -5331,19 +5303,17 @@
    (clobber (match_operand:DI 3 "memory_operand" "=o"))]
   "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
   "#"
-  "&& 1"
+  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[3]))"
   [(pc)]
   "
 {
   rtx lowword;
-  gcc_assert (GET_CODE (operands[3]) == MEM);
-  lowword = XEXP (operands[3], 0);
-  if (WORDS_BIG_ENDIAN)
-    lowword = plus_constant (lowword, 4);
+  gcc_assert (MEM_P (operands[3]));
+  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
 
   emit_insn (gen_fctiwz (operands[2], operands[1]));
   emit_move_insn (operands[3], operands[2]);
-  emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
+  emit_move_insn (operands[0], lowword);
   DONE;
 }"
   [(set_attr "length" "16")])
@@ -8476,20 +8446,18 @@
   "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
    && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
   "#"
-  "&& reload_completed"
+  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
   [(pc)]
 {
   rtx lowword;
   emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
 
-  gcc_assert (GET_CODE (operands[5]) == MEM);
-  lowword = XEXP (operands[5], 0);
-  if (WORDS_BIG_ENDIAN)
-    lowword = plus_constant (lowword, 4);
+  gcc_assert (MEM_P (operands[5]));
+  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
 
   emit_insn (gen_fctiwz (operands[4], operands[2]));
   emit_move_insn (operands[5], operands[4]);
-  emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
+  emit_move_insn (operands[0], lowword);
   DONE;
 })
 
Index: testsuite/gcc.dg/rs6000-fpint-2.c
===================================================================
RCS file: testsuite/gcc.dg/rs6000-fpint-2.c
diff -N testsuite/gcc.dg/rs6000-fpint-2.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/rs6000-fpint-2.c	2 May 2005 23:22:24 -0000
@@ -0,0 +1,11 @@
+/* { dg-do compile { target powerpc*-*-* rs6000-*-* } } */
+/* { dg-options "-mno-powerpc-gfxopt -mpowerpc64" } */
+extern void bar (void *);
+extern double x;
+void
+foo (void)
+{
+  char buf2 [32][1024];
+  bar (buf2 [(int) x]);
+}
+
============================================================


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