This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix PR target/29682 - [4.2/4.3 Regression] ICE: in change_pattern, at haifa-sched.c:4066 with -O3 -msched-control-spec
- From: Maxim Kuvyrkov <mkuvyrkov at ispras dot ru>
- To: James E Wilson <wilson at specifix dot com>
- Cc: Vladimir Makarov <vmakarov at redhat dot com>, Martin Michlmayr <tbm at cyrius dot com>, gcc-patches at gcc dot gnu dot org
- Date: Thu, 16 Nov 2006 13:44:51 +0300
- Subject: [PATCH]: Fix PR target/29682 - [4.2/4.3 Regression] ICE: in change_pattern, at haifa-sched.c:4066 with -O3 -msched-control-spec
Hi!
This patch fixes PR target/29682 on ia64.
Though the ICE was detected only with specified flags the problem can
potentially emerge with default -O2 settings.
The bug is that we generate a speculative load into ar.lc register and
fail when try to recognize it. The patch adds necessary check to
ia64.c: speculate_insn () function so that only loads to general or fp
registers will be considered for speculation.
Thanks,
Maxim
2006-11-16 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
PR target/29682
* config/ia64/ia64.c (ia64_speculate_insn): Restrict to memory loads to
general or fp registers. Add comments.
* config/ia64/ia64.md (reg_pred_prefix): Add comment.
2006-11-16 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
PR target/29682
* gcc.c-torture/compile/pr29682.c: New test for ia64 target.
--- testsuite/gcc.c-torture/compile/pr29682.c (/gcc-local/trunk/gcc) (revision 23003)
+++ testsuite/gcc.c-torture/compile/pr29682.c (/gcc-local/fix-pr29682/gcc) (revision 23003)
@@ -0,0 +1,50 @@
+/* { dg-do assemble { target ia64-*-* } } */
+typedef long unsigned int size_t;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+typedef uint8_t byte;
+typedef enum pgpArmor_e
+{
+ PGPARMOR_ERR_CRC_CHECK = -7, PGPARMOR_ERR_BODY_DECODE =
+ -3, PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE = -2, PGPARMOR_ERR_NO_BEGIN_PGP =
+ -1, PGPARMOR_NONE = 0, PGPARMOR_MESSAGE = 1, PGPARMOR_PUBKEY =
+ 5, PGPARMOR_PRIVKEY = 6, PGPARMOR_SECKEY = 7
+}
+pgpArmor;
+pgpCRC (const byte * octets, size_t len)
+{
+ unsigned int crc = 0xb704ce;
+ int i;
+ while (len--)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ crc <<= 1;
+ if (crc & 0x1000000)
+ crc ^= 0x1864cfb;
+ }
+ }
+}
+pgpReadPkts (const char *fn, const byte ** pkt, size_t * pktlen)
+{
+ const byte *b = ((void *) 0);
+ const char *enc = ((void *) 0);
+ byte *dec;
+ size_t declen;
+ uint32_t crcpkt, crc;
+ int pstate = 0;
+ pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP;
+ {
+ switch (pstate)
+ {
+ case 0:
+ if (b64decode (enc, (void **) &dec, &declen) != 0)
+ {
+ goto exit;
+ }
+ crc = pgpCRC (dec, declen);
+ }
+ }
+exit:if (ec > PGPARMOR_NONE && pkt)
+ *pkt = b;
+}
--- config/ia64/ia64.c (/gcc-local/trunk/gcc) (revision 23003)
+++ config/ia64/ia64.c (/gcc-local/fix-pr29682/gcc) (revision 23003)
@@ -6808,13 +6808,19 @@ ia64_speculate_insn (rtx insn, ds_t ts,
if (GET_CODE (pat) == COND_EXEC)
pat = COND_EXEC_CODE (pat);
+ /* This should be a SET ... */
if (GET_CODE (pat) != SET)
return -1;
+
reg = SET_DEST (pat);
- if (!REG_P (reg))
+ /* ... to the general/fp register ... */
+ if (!REG_P (reg) || !(GR_REGNO_P (REGNO (reg)) || FP_REGNO_P (REGNO (reg))))
return -1;
- mem = SET_SRC (pat);
+ /* ... from the mem ... */
+ mem = SET_SRC (pat);
+
+ /* ... that can, possibly, be a zero_extend ... */
if (GET_CODE (mem) == ZERO_EXTEND)
{
mem = XEXP (mem, 0);
@@ -6823,6 +6829,7 @@ ia64_speculate_insn (rtx insn, ds_t ts,
else
extend_p = false;
+ /* ... or a speculative load. */
if (GET_CODE (mem) == UNSPEC)
{
int code;
@@ -6839,8 +6846,12 @@ ia64_speculate_insn (rtx insn, ds_t ts,
mem = XVECEXP (mem, 0, 0);
gcc_assert (MEM_P (mem));
}
+
+ /* Source should be a mem ... */
if (!MEM_P (mem))
return -1;
+
+ /* ... addressed by a register. */
mem_reg = XEXP (mem, 0);
if (!REG_P (mem_reg))
return -1;
@@ -6857,6 +6868,7 @@ ia64_speculate_insn (rtx insn, ds_t ts,
extract_insn_cached (insn);
gcc_assert (reg == recog_data.operand[0] && mem == recog_data.operand[1]);
+
*new_pat = ia64_gen_spec_insn (insn, ts, mode_no, gen_p != 0, extend_p);
return gen_p;
--- config/ia64/ia64.md (/gcc-local/trunk/gcc) (revision 23003)
+++ config/ia64/ia64.md (/gcc-local/fix-pr29682/gcc) (revision 23003)
@@ -474,6 +474,9 @@
(define_mode_attr mem_constr [(BI "*m") (QI "m") (HI "m") (SI "m") (DI "m,Q") (SF "Q,m") (DF "Q,m") (XF "m") (TI "Q")])
+;; Define register predicate prefix.
+;; We can generate speculative loads only for general and fp registers - this
+;; is constrainted in ia64.c: ia64_speculate_insn ().
(define_mode_attr reg_pred_prefix [(BI "gr") (QI "gr") (HI "gr") (SI "gr") (DI "grfr") (SF "grfr") (DF "grfr") (XF "fr") (TI "fr")])
(define_mode_attr ld_class [(BI "ld") (QI "ld") (HI "ld") (SI "ld") (DI "ld,fld") (SF "fld,ld") (DF "fld,ld") (XF "fld") (TI "fldp")])