re PR tree-optimization/54098 (ICE on valid code)
authorRichard Guenther <rguenther@suse.de>
Thu, 26 Jul 2012 10:25:15 +0000 (10:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 26 Jul 2012 10:25:15 +0000 (10:25 +0000)
2012-07-26  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/54098
* tree-vrp.c (vrp_visit_phi_node): Iterate once more if the
original range was UNDEFINED.

* gcc.dg/torture/pr54098.c: New testcase.

From-SVN: r189885

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr54098.c [new file with mode: 0644]
gcc/tree-vrp.c

index 55075a407e159b8955a686ce4d584fc06c04fc0f..ec68693eba2e142d05573bde3ef9fdb885b5285a 100644 (file)
@@ -1,3 +1,9 @@
+2012-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/54098
+       * tree-vrp.c (vrp_visit_phi_node): Iterate once more if the
+       original range was UNDEFINED.
+
 2012-07-26  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        * config/arm/neon.ml (ops): Fix regexp for vld1Q_dups64 and
index bc12992365cc734f4c666424bbf5c757295ee935..3092b9072bfafe1d6c6c05274c6850f1c6210b72 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-26  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/54098
+       * gcc.dg/torture/pr54098.c: New testcase.
+
 2012-07-26  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        * gcc.target/arm/neon/vld1Q_dupu64.c: Regenerate.
diff --git a/gcc/testsuite/gcc.dg/torture/pr54098.c b/gcc/testsuite/gcc.dg/torture/pr54098.c
new file mode 100644 (file)
index 0000000..74398b6
--- /dev/null
@@ -0,0 +1,72 @@
+/* { dg-do compile } */
+
+extern int printf(const char *, ...);
+struct list_head {
+       struct list_head *next, *prev;
+};
+struct resource {
+       unsigned long long start;
+       unsigned long long end;
+       unsigned long flags;
+       struct resource *parent, *sibling, *child;
+};
+struct pci_dev {
+       struct list_head bus_list;
+       struct resource resource[12];
+};
+struct pci_bus {
+       struct list_head devices;
+       unsigned char secondary;
+       unsigned char subordinate;
+};
+struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
+static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type) {
+       int i;
+       struct resource *r;
+       unsigned long type_mask = 0x00000100 | 0x00000200 | 0x00002000;
+       for (i = 0; (r = pci_bus_resource_n(bus, i)) || i < 4; i++) {
+               if (r && (r->flags & type_mask) == type && !r->parent) return r;
+       }
+       return ((void *)0);
+}
+static unsigned long long calculate_memsize(unsigned long long size, unsigned long long min_size, unsigned long long size1, unsigned long long old_size, unsigned long long align) {
+       if (old_size == 1 ) old_size = 0;
+       if (size < old_size) size = old_size;
+       return size;
+}
+void pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type, unsigned long long min_size, unsigned long long add_size, void *realloc_head) {
+       struct pci_dev *dev;
+       unsigned long long min_align, align, size, size0, size1;
+       int order;
+       struct resource *b_res = find_free_bus_resource(bus, type);
+       unsigned long long children_add_size = 0;
+       if (!b_res) return;
+       for (dev = ({
+                               const typeof( ((typeof(*dev) *)0)->bus_list ) *__mptr = ((&bus->devices)->next);
+                               (typeof(*dev) *)( (char *)__mptr - __builtin_offsetof(typeof(*dev),bus_list) );
+                               }
+                  );
+                       &dev->bus_list != (&bus->devices);
+                       dev = ({
+                               const typeof( ((typeof(*dev) *)0)->bus_list ) *__mptr = (dev->bus_list.next);
+                               (typeof(*dev) *)( (char *)__mptr - __builtin_offsetof(typeof(*dev),bus_list) );
+                               }
+                             )) {
+               int i;
+               for (i = 0; i < 12; i++) {
+                       struct resource *r = &dev->resource[i];
+                       unsigned long long r_size;
+                       if (r->parent || (r->flags & mask) != type) continue;
+                       r_size = r->end - r->start + 1;
+                       if (order > 11) {
+                               printf("%d: %pR %#llx\n", i, r, (unsigned long long) align);
+                       }
+                       size += r_size;
+               }
+       }
+       if (children_add_size > add_size) add_size = children_add_size;
+       size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : calculate_memsize(size, min_size+add_size, 0, b_res->end - b_res->start + 1, min_align);
+       if (!size0 && !size1) {
+               printf("%pR %02x-%02x\n", b_res, bus->secondary, bus->subordinate);
+       }
+}
index 2d1628dee3d48d25663e4357033897c6f7b819c5..1a4c7c9f3afebba01261cd0d3a44cf0f358e98d2 100644 (file)
@@ -7684,10 +7684,12 @@ vrp_visit_phi_node (gimple phi)
      when the new value is slightly bigger or smaller than the
      previous one.  We don't do this if we have seen a new executable
      edge; this helps us avoid an overflow infinity for conditionals
-     which are not in a loop.  */
+     which are not in a loop.  If the old value-range was VR_UNDEFINED
+     use the updated range and iterate one more time.  */
   if (edges > 0
       && gimple_phi_num_args (phi) > 1
-      && edges == old_edges)
+      && edges == old_edges
+      && lhs_vr->type != VR_UNDEFINED)
     {
       int cmp_min = compare_values (lhs_vr->min, vr_result.min);
       int cmp_max = compare_values (lhs_vr->max, vr_result.max);