re PR rtl-optimization/58079 (internal compiler error: in do_SUBST, at combine.c...
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 8 Aug 2013 18:42:21 +0000 (18:42 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 8 Aug 2013 18:42:21 +0000 (18:42 +0000)
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

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr58079.c [new file with mode: 0644]

index 45905cc..8b4d41f 100644 (file)
@@ -1,3 +1,9 @@
+2013-08-08  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       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  <kyrylo.tkachov@arm.com>
 
        * config/arm/neon.md (movmisalign<mode>): Disable when we
index d0aae69..29dfd15 100644 (file)
@@ -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.
index ffa5fca..d86db30 100644 (file)
@@ -1,3 +1,7 @@
+2013-08-08  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * gcc.dg/torture/pr58079.c: New test.
+
 2013-08-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        * 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 (file)
index 0000000..99a3018
--- /dev/null
@@ -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);
+ }
+}