--- /dev/null
+/* { dg-do compile } */\r
+/* { dg-options "-O2 -mjsr" } */\r
+\r
+void *malloc (__SIZE_TYPE__);\r
+void *realloc (void *, __SIZE_TYPE__);\r
+\r
+struct A { double x, y; };\r
+struct B { double x0, y0, x1, y1; };\r
+struct C { int n_points; int dir; struct B bbox; struct A *points; };\r
+struct D { int n_segs; struct C segs[1]; };\r
+\r
+void foo (int, int, int *, int, int *, struct A **, int *, int *,\r
+ struct D *, int *, struct D **, int *, int **);\r
+int baz (struct A, struct A, struct A, struct A);\r
+\r
+static void\r
+bar (struct D *svp, int *n_points_max,\r
+ struct A p, int *seg_map, int *active_segs, int i)\r
+{\r
+ int asi, n_points;\r
+ struct C *seg;\r
+\r
+ asi = seg_map[active_segs[i]];\r
+ seg = &svp->segs[asi];\r
+ n_points = seg->n_points;\r
+ seg->points = ((struct A *)\r
+ realloc (seg->points, (n_points_max[asi] <<= 1) * sizeof (struct A)));\r
+ seg->points[n_points] = p;\r
+ seg->bbox.y1 = p.y;\r
+ seg->n_points++;\r
+}\r
+\r
+struct D *\r
+test (struct D *vp)\r
+{\r
+ int *active_segs, n_active_segs, *cursor, seg_idx;\r
+ double y, share_x;\r
+ int tmp1, tmp2, asi, i, j, *n_ips, *n_ips_max, n_segs_max;\r
+ struct A **ips, p_curs, *pts;\r
+ struct D *new_vp;\r
+ int *n_points_max, *seg_map, first_share;\r
+\r
+ n_segs_max = 16;\r
+ new_vp = (struct D *) malloc (sizeof (struct D) +\r
+ (n_segs_max - 1) * sizeof (struct C));\r
+ new_vp->n_segs = 0;\r
+\r
+ if (vp->n_segs == 0)\r
+ return new_vp;\r
+\r
+ active_segs = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+ cursor = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+\r
+ seg_map = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+ n_ips = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+ n_ips_max = ((int *) malloc ((vp->n_segs) * sizeof (int)));\r
+ ips = ((struct A * *) malloc ((vp->n_segs) * sizeof (struct A *)));\r
+\r
+ n_points_max = ((int *) malloc ((n_segs_max) * sizeof (int)));\r
+\r
+ n_active_segs = 0;\r
+ seg_idx = 0;\r
+ y = vp->segs[0].points[0].y;\r
+ while (seg_idx < vp->n_segs || n_active_segs > 0)\r
+ {\r
+ for (i = 0; i < n_active_segs; i++)\r
+ {\r
+ asi = active_segs[i];\r
+ if (vp->segs[asi].n_points - 1 == cursor[asi] &&\r
+ vp->segs[asi].points[cursor[asi]].y == y)\r
+ i--;\r
+ }\r
+\r
+ while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)\r
+ {\r
+ cursor[seg_idx] = 0;\r
+ n_ips[seg_idx] = 1;\r
+ n_ips_max[seg_idx] = 2;\r
+ ips[seg_idx] =\r
+ ((struct A *) malloc ((n_ips_max[seg_idx]) * sizeof (struct A)));\r
+ ips[seg_idx][0] = vp->segs[seg_idx].points[0];\r
+ pts = ((struct A *) malloc ((16) * sizeof (struct A)));\r
+ pts[0] = vp->segs[seg_idx].points[0];\r
+ tmp1 = seg_idx;\r
+ for (j = i; j < n_active_segs; j++)\r
+ {\r
+ tmp2 = active_segs[j];\r
+ active_segs[j] = tmp1;\r
+ tmp1 = tmp2;\r
+ }\r
+ active_segs[n_active_segs] = tmp1;\r
+ n_active_segs++;\r
+ seg_idx++;\r
+ }\r
+ first_share = -1;\r
+ share_x = 0;\r
+\r
+ for (i = 0; i < n_active_segs; i++)\r
+ {\r
+ asi = active_segs[i];\r
+ p_curs = ips[asi][1];\r
+ if (p_curs.y == y)\r
+ {\r
+ bar (new_vp, n_points_max,\r
+ p_curs, seg_map, active_segs, i);\r
+\r
+ n_ips[asi]--;\r
+ for (j = 0; j < n_ips[asi]; j++)\r
+ ips[asi][j] = ips[asi][j + 1];\r
+\r
+ if (first_share < 0 || p_curs.x != share_x)\r
+ {\r
+ foo (first_share, i,\r
+ active_segs, n_active_segs,\r
+ cursor, ips, n_ips, n_ips_max, vp, seg_map,\r
+ &new_vp, &n_segs_max, &n_points_max);\r
+ first_share = i;\r
+ share_x = p_curs.x;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ foo (first_share, i,\r
+ active_segs, n_active_segs,\r
+ cursor, ips, n_ips, n_ips_max, vp, seg_map,\r
+ &new_vp, &n_segs_max, &n_points_max);\r
+ first_share = -1;\r
+ }\r
+ }\r
+ }\r
+ return new_vp;\r
+}\r
+\r
+/* { dg-final { scan-assembler-not "bsr" } } */\r