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]

[PATCH] PR target/19137: ICE with load of TImode constant


This fixes an ICE on powerpc-linux, found running the gcc testsuite.
The problem being that rs6000.md has no TImode move pattern handling
constants (*), and the existing splitter doesn't do anything until after
reload.  This ICE happens in regclass.

*) The movti_string pattern that might seem to be available for
powerpc-linux has a too restrictive operand predicate.
reg_or_mem_operand won't match a constant.  An alternative fix is to
relax this predicate to "input_operand".  That unfortunately results in
reload forcing the zero to memory, so generated code is poor.  OK, you
could add an "n" alternative..  See below for a patch to do that.

Here's my first attempt at a fix.

	PR target/19137
	* config/rs6000/rs6000.c (rs6000_emit_move): Split TImode constant
	loads.

diff -u6rp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c	2004-12-23 17:46:27.419162669 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.c	2004-12-23 20:05:46.989764716 +1030
@@ -4334,16 +4334,17 @@ rs6000_emit_move (rtx dest, rtx source, 
   if (reload_in_progress && mode == Pmode
       && (! general_operand (operands[1], mode)
 	  || ! nonimmediate_operand (operands[0], mode)))
     goto emit_set;
 
   /* 128-bit constant floating-point values on Darwin should really be
-     loaded as two parts.  */
-  if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
-      && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
-      && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+     loaded as two parts.  Similarly, split TImode constants.  */
+  if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+       && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
+       && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+      || (mode == TImode && GET_CODE (operands[1]) == CONST_INT))
     {
       /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
 	 know how to get a DFmode SUBREG of a TFmode.  */
       rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
 			simplify_gen_subreg (DImode, operands[1], mode, 0),
 			DImode);


Alternative fix.  I'm inclined to think this one is better because it
delays splitting, which means less rtl to process in earlier passes.

	PR target/19137
	* config/rs6000/rs6000.md (movti_power, movti_string): Relax
	operand[1] predicate to input_operand, and add r<-n alternative.

powerpc-linux bootstrap and regression test in progress.  OK mainline?

diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md
--- gcc-virgin/gcc/config/rs6000/rs6000.md	2004-12-18 20:17:55.000000000 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.md	2004-12-24 00:53:07.155150191 +1030
@@ -8692,8 +8695,8 @@
 ;; giving the SCRATCH mq.
 
 (define_insn "*movti_power"
-  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
-	(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
+  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r,r")
+	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))
    (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
   "TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
@@ -8718,14 +8721,15 @@
 	return \"{lsi|lswi} %0,%P1,16\";
       /* ... fall through ...  */
     case 4:
+    case 5:
       return \"#\";
     }
 }"
-  [(set_attr "type" "store,store,*,load,load")])
+  [(set_attr "type" "store,store,*,load,load,*")])
 
 (define_insn "*movti_string"
-  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r")
-	(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
+  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r")
+	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))]
   "! TARGET_POWER && ! TARGET_POWERPC64
    && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
   "*
@@ -8748,10 +8752,11 @@
 	return \"{lsi|lswi} %0,%P1,16\";
       /* ... fall through ...  */
     case 4:
+    case 5:
       return \"#\";
     }
 }"
-  [(set_attr "type" "store,store,*,load,load")])
+  [(set_attr "type" "store,store,*,load,load,*")])
 
 (define_insn "*movti_ppc64"
   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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