From: Richard Sandiford Date: Thu, 8 Aug 2013 18:42:21 +0000 (+0000) Subject: re PR rtl-optimization/58079 (internal compiler error: in do_SUBST, at combine.c... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f40423e28fa50514ff92f01846bd7ae89318b3bc;p=gcc.git re PR rtl-optimization/58079 (internal compiler error: in do_SUBST, at combine.c:711) gcc/ PR rtl-optimization/58079 * combine.c (combine_simplify_rtx): Avoid using SUBST if simplify_comparison has widened a comparison with an integer. gcc/testsuite/ * gcc.dg/torture/pr58079.c: New test. From-SVN: r201609 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 45905ccd3e8..8b4d41ffb01 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-08-08 Richard Sandiford + + PR rtl-optimization/58079 + * combine.c (combine_simplify_rtx): Avoid using SUBST if + simplify_comparison has widened a comparison with an integer. + 2013-08-08 Kyrylo Tkachov * config/arm/neon.md (movmisalign): Disable when we diff --git a/gcc/combine.c b/gcc/combine.c index d0aae69f269..29dfd15cc9f 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -5803,8 +5803,15 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest, return x; } - /* If the code changed, return a whole new comparison. */ - if (new_code != code) + /* If the code changed, return a whole new comparison. + We also need to avoid using SUBST in cases where + simplify_comparison has widened a comparison with a CONST_INT, + since in that case the wider CONST_INT may fail the sanity + checks in do_SUBST. */ + if (new_code != code + || (CONST_INT_P (op1) + && GET_MODE (op0) != GET_MODE (XEXP (x, 0)) + && GET_MODE (op0) != GET_MODE (XEXP (x, 1)))) return gen_rtx_fmt_ee (new_code, mode, op0, op1); /* Otherwise, keep this operation, but maybe change its operands. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffa5fcac832..d86db3082a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-08-08 Richard Sandiford + + * gcc.dg/torture/pr58079.c: New test. + 2013-08-07 Eric Botcazou * gnat.dg/warn9.adb: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr58079.c b/gcc/testsuite/gcc.dg/torture/pr58079.c new file mode 100644 index 00000000000..99a30181f1e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr58079.c @@ -0,0 +1,107 @@ +/* { dg-options "-mlong-calls" { target mips*-*-* } } */ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int __kernel_size_t; +typedef __kernel_size_t size_t; +struct list_head { + struct list_head *next; +}; + +struct dmx_ts_feed { + int is_filtering; +}; +struct dmx_section_feed { + u16 secbufp; + u16 seclen; + u16 tsfeedp; +}; + +typedef int (*dmx_ts_cb) ( + const u8 * buffer1, + size_t buffer1_length, + const u8 * buffer2, + size_t buffer2_length +); + +struct dvb_demux_feed { + union { + struct dmx_ts_feed ts; + struct dmx_section_feed sec; + } feed; + union { + dmx_ts_cb ts; + } cb; + int type; + u16 pid; + int ts_type; + struct list_head list_head; +}; + +struct dvb_demux { + int (*stop_feed)(struct dvb_demux_feed *feed); + struct list_head feed_list; +}; + + +static +inline +__attribute__((always_inline)) +u8 +payload(const u8 *tsp) +{ + if (tsp[3] & 0x20) { + return 184 - 1 - tsp[4]; + } + return 184; +} + +static +inline +__attribute__((always_inline)) +int +dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, const u8 *buf) +{ + int count = payload(buf); + int p; + if (count == 0) + return -1; + return feed->cb.ts(&buf[p], count, ((void *)0), 0); +} + +static +inline +__attribute__((always_inline)) +void +dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf) +{ + switch (feed->type) { + case 0: + if (feed->ts_type & 1) { + dvb_dmx_swfilter_payload(feed, buf); + } + if (dvb_dmx_swfilter_section_packet(feed, buf) < 0) + feed->feed.sec.seclen = feed->feed.sec.secbufp = 0; + } +} + +static +void +dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) +{ + struct dvb_demux_feed *feed; + int dvr_done = 0; + + for (feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = ((&demux->feed_list)->next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );}); __builtin_prefetch(feed->list_head.next), &feed->list_head != (&demux->feed_list); feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = (feed->list_head.next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );})) { + if (((((feed)->type == 0) && ((feed)->feed.ts.is_filtering) && (((feed)->ts_type & (1 | 8)) == 1))) && (dvr_done++)) + dvb_dmx_swfilter_packet_type(feed, buf); + else if (feed->pid == 0x2000) + feed->cb.ts(buf, 188, ((void *)0), 0); + } +} +void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count) +{ + while (count--) { + dvb_dmx_swfilter_packet(demux, buf); + } +}