diff mbox

Fix e500 vector ICE with string constants

Message ID Pine.LNX.4.64.1206192153310.13375@digraph.polyomino.org.uk
State New
Headers show

Commit Message

Joseph Myers June 19, 2012, 9:56 p.m. UTC
On some tests involving storing a pointer to a string constant in a
vector, on powerpc with SPE vectors, an ICE occurs of the form:

t2.c: In function 'f':
t2.c:7:1: error: unrecognizable insn:
 }
 ^
(insn 9 8 10 2 (set (subreg:SI (reg:V2SI 125 [ D.1618 ]) 4)
        (lo_sum:SI (reg:SI 126)
            (symbol_ref/f:SI ("*.LC0") [flags 0x82] <var_decl
	    0xf745b000 *.LC0>))) t2.c:6 -1
     (nil))
t2.c:7:1: internal compiler error: in extract_insn, at recog.c:2130
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

The patterns to set individual words of SPE vectors only allow
input_operand and do not allow for the LO_SUM constructs used for
pointers to strings.  This patch fixes things by adding further
patterns for the LO_SUM case.  (It's possible the issue could also
arise with the patterns for subregs of TFmode at offset 8 and 12, but
I couldn't get the compiler to generate stores of string constant
pointers to such subregs.)

The original test I had for this issue in a 4.6-based compiler
simplified to

char *a1[20];
int a2[20];
char a3[1];

void
f (void)
{
  int i;
  for (i = 1; i < 20; i++)
    {
      a1[i] = "";
      a2[i] = 0;
    }
}

with -O3, where the vectors were generated internally, but that
doesn't ICE with trunk, so I created the synthetic testcases in this
patch that do ICE with trunk.

Tested with no regressions with cross to powerpc-eabispe.  OK to
commit?

2012-06-19  Joseph Myers  <joseph@codesourcery.com>

	* config/rs6000/spe.md (*mov_si<mode>_e500_subreg0): Rename to
	mov_si<mode>_e500_subreg0.
	(*mov_si<mode>_e500_subreg0_elf_low)
	(*mov_si<mode>_e500_subreg4_elf_low): New patterns.

testsuite:
2012-06-19  Joseph Myers  <joseph@codesourcery.com>

	* gcc.c-torture/compile/vector-5.c,
	gcc.c-torture/compile/vector-6.c: New tests.

Comments

David Edelsohn June 19, 2012, 10:04 p.m. UTC | #1
On Tue, Jun 19, 2012 at 5:56 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:

> 2012-06-19  Joseph Myers  <joseph@codesourcery.com>
>
>        * config/rs6000/spe.md (*mov_si<mode>_e500_subreg0): Rename to
>        mov_si<mode>_e500_subreg0.
>        (*mov_si<mode>_e500_subreg0_elf_low)
>        (*mov_si<mode>_e500_subreg4_elf_low): New patterns.
>
> testsuite:
> 2012-06-19  Joseph Myers  <joseph@codesourcery.com>
>
>        * gcc.c-torture/compile/vector-5.c,
>        gcc.c-torture/compile/vector-6.c: New tests.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/testsuite/gcc.c-torture/compile/vector-5.c
===================================================================
--- gcc/testsuite/gcc.c-torture/compile/vector-5.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/vector-5.c	(revision 0)
@@ -0,0 +1,7 @@ 
+typedef int v2si __attribute__((__vector_size__(8)));
+
+v2si
+f (int x)
+{
+  return (v2si) { x, (__INTPTR_TYPE__) "" };
+}
Index: gcc/testsuite/gcc.c-torture/compile/vector-6.c
===================================================================
--- gcc/testsuite/gcc.c-torture/compile/vector-6.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/vector-6.c	(revision 0)
@@ -0,0 +1,7 @@ 
+typedef int v2si __attribute__((__vector_size__(8)));
+
+v2si
+f (int x)
+{
+  return (v2si) { (__INTPTR_TYPE__) "", x };
+}
Index: gcc/config/rs6000/spe.md
===================================================================
--- gcc/config/rs6000/spe.md	(revision 188753)
+++ gcc/config/rs6000/spe.md	(working copy)
@@ -1,5 +1,5 @@ 
 ;; e500 SPE description
-;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+;; Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
 ;; Free Software Foundation, Inc.
 ;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
 
@@ -2329,7 +2329,7 @@ 
   "evmergehi %0,%1,%1\;mr %L0,%1\;evmergehi %Y0,%L1,%L1\;mr %Z0,%L1"
   [(set_attr "length" "16")])
 
-(define_insn "*mov_si<mode>_e500_subreg0"
+(define_insn "mov_si<mode>_e500_subreg0"
   [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r,&r") 0)
 	(match_operand:SI 1 "input_operand" "r,m"))]
   "(TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
@@ -2339,6 +2339,24 @@ 
    evmergelohi %0,%0,%0\;{l%U1%X1|lwz%U1%X1} %0,%1\;evmergelohi %0,%0,%0"
   [(set_attr "length" "4,12")])
 
+(define_insn_and_split "*mov_si<mode>_e500_subreg0_elf_low"
+  [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 0)
+	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		   (match_operand 2 "" "")))]
+  "((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
+    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
+   && TARGET_ELF && !TARGET_64BIT && can_create_pseudo_p ()"
+  "#"
+  "&& 1"
+  [(pc)]
+{
+  rtx tmp = gen_reg_rtx (SImode);
+  emit_insn (gen_elf_low (tmp, operands[1], operands[2]));
+  emit_insn (gen_mov_si<mode>_e500_subreg0 (operands[0], tmp));
+  DONE;
+}
+  [(set_attr "length" "8")])
+
 ;; ??? Could use evstwwe for memory stores in some cases, depending on
 ;; the offset.
 (define_insn "*mov_si<mode>_e500_subreg0_2"
@@ -2360,6 +2378,15 @@ 
    mr %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1")
 
+(define_insn "*mov_si<mode>_e500_subreg4_elf_low"
+  [(set (subreg:SI (match_operand:SPE64TF 0 "register_operand" "+r") 4)
+	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+		   (match_operand 2 "" "")))]
+  "((TARGET_E500_DOUBLE && (<MODE>mode == DFmode || <MODE>mode == TFmode))
+    || (TARGET_SPE && <MODE>mode != DFmode && <MODE>mode != TFmode))
+   && TARGET_ELF && !TARGET_64BIT"
+  "{ai|addic} %0,%1,%K2")
+
 (define_insn "*mov_si<mode>_e500_subreg4_2"
   [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "+r,m")
 	(subreg:SI (match_operand:SPE64TF 1 "register_operand" "r,r") 4))]