This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix e500 vector ICE with string constants
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dje dot gcc at gmail dot com
- Date: Tue, 19 Jun 2012 21:56:22 +0000 (UTC)
- Subject: Fix e500 vector ICE with string constants
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.
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))]
--
Joseph S. Myers
joseph@codesourcery.com