This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR target/19137: ICE with load of TImode constant
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Edelsohn <dje at watson dot ibm dot com>
- Date: Fri, 24 Dec 2004 01:27:00 +1030
- Subject: [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