new file mode 100644
@@ -0,0 +1,132 @@
+/* { dg-do run } */
+
+int printf(const char *, ...);
+void __assert_fail();
+int a, g, h, i, v, w = 2, x, y, ab, ac, ad, ae, af, ag;
+static int f, j, m, n, p, r, u, aa;
+struct b {
+ int c : 20;
+ int d : 20;
+ int e : 10;
+};
+static struct b l, o, q = {3, 3, 5};
+int s(int z) {
+ struct b ah;
+ int ai = 1, aj[7] = {1, 1, 1, 1, 1, 1, 1};
+ak:
+ for (u = -22; u < 2; ++u) {
+ struct b al[8] = {{2, 7, 9}, {8, 7, 1}, {2, 7, 9}, {8, 7, 1}, {2, 7, 9}, {8, 7, 1}, {2, 7, 9}};
+ y = z = 0;
+ for (; z < 2; z++) {
+ int am[18], k;
+ ab = ac = 0;
+ for (; ac < 1; ac++)
+ for (k = 0; k < 9; k++)
+ am[k] = 0;
+ n = 0;
+ while (1) {
+ v = u < 0 || a;
+ h = z < ~u && 4 & q.c;
+ if ((aa <= l.c) > q.d && p)
+ return o.c;
+ if (w)
+ break;
+ return q.e;
+ }
+ a = j;
+ }
+ }
+ for (x = 0; x < 2; x++) {
+ struct b an = {1, 8, 4};
+ int ao[28] = {5, 0, 0, 9, 0, 3, 0, 5, 0, 0, 9, 0, 3, 0, 5, 0, 0, 9, 0, 3, 0, 5, 0, 0, 9, 0, 3, 0};
+ if (q.e) {
+ int ap = ai || l.c + q.c, aq = q.d, ar = p & f;
+ q.d = q.d || ar || ap;
+ p = 0;
+ if (!j && ai)
+ goto as;
+ if (q.d) {
+ printf("", l);
+ q.d = f >> j;
+ }
+ p = l.c = aq;
+ an = q;
+ } else {
+ int at[12][1] = {{9}, {9}, {5}, {9}, {9}, {5}, {9}, {9}, {5}, {9}, {9}, {5}};
+ struct b au;
+ if (o.c)
+ aa = ah.e;
+ if (an.d)
+ ah.e = (j & (aa * m)) ^ au.d;
+ o.c = m + aa;
+ int av = o.c || 0, aw = ai || q.c & l.c, ax = n;
+ if (q.e < ai)
+ q = an;
+ if (r)
+ break;
+ ai = aw - av;
+ an.e = 0;
+ if (ai) {
+ an.e = l.c || 0;
+ f = q.c;
+ ah.e = l.c % q.d;
+ q.c = au.e;
+ if ((q.d && q.c) || ah.e)
+ __assert_fail();
+ q.c = 0;
+ if (au.d > m || ah.e)
+ w = au.c | (n & ah.c);
+ as:
+ ae = af = ah.c;
+ int ay = au.d & q.e & au.c || o.c, az = 0 || o.c, ba = m & ah.d;
+ if (n)
+ au.c = au.e = (q.e || ah.d) ^ (o.c + (az / au.e));
+ n = au.c || au.e;
+ if (ba) {
+ printf("", ax);
+ x = q.e | m;
+ continue;
+ }
+ m = ay;
+ n = printf("", au);
+ }
+ if (ah.d)
+ o.c = l.c & o.c & q.c;
+ if (q.d)
+ __assert_fail();
+ printf("", an);
+ printf("", q);
+ printf("", au);
+ if (ah.e)
+ while (u++) {
+ struct b al[7] = {{7, 9, 8}, {7, 1, 2}, {7, 9, 8}, {7, 1, 2}, {7, 9, 8}, {7, 1, 2}, {7, 9, 0}};
+ if (an.d) {
+ int d[8] = {0, 1, 0, 1, 0, 1, 0, 1};
+ if (ad)
+ goto ak;
+ while (ag)
+ g = an.d = i = m;
+ f = j;
+ }
+ n++;
+ }
+ f = q.d;
+ }
+ if (l.c && m) {
+ int d[7] = {1, 0, 1, 0, 1, 0, 1};
+ if (x)
+ h = an.d;
+ else
+ g = 0;
+ }
+ }
+ int bb = (q.d ^ ah.c) | aa | (q.e & q.c) | (f & ah.d);
+ if (bb)
+ return x;
+ return 0;
+}
+int main() {
+ j = 1;
+ s(0);
+ return 0;
+}
@@ -3468,30 +3468,28 @@ ifcvt_can_hoist (class loop *loop, edge pe, gimple *stmt)
static void
ifcvt_hoist_invariants (class loop *loop, edge pe)
{
+ /* Only hoist from the now unconditionally executed part of the loop. */
+ basic_block bb = loop->header;
gimple_stmt_iterator hoist_gsi = {};
- unsigned int num_blocks = loop->num_nodes;
- basic_block *body = get_loop_body (loop);
- for (unsigned int i = 0; i < num_blocks; ++i)
- for (gimple_stmt_iterator gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);)
- {
- gimple *stmt = gsi_stmt (gsi);
- if (ifcvt_can_hoist (loop, pe, stmt))
- {
- /* Once we've hoisted one statement, insert other statements
- after it. */
- gsi_remove (&gsi, false);
- if (hoist_gsi.ptr)
- gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
- else
- {
- gsi_insert_on_edge_immediate (pe, stmt);
- hoist_gsi = gsi_for_stmt (stmt);
- }
- continue;
- }
- gsi_next (&gsi);
- }
- free (body);
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ if (ifcvt_can_hoist (loop, pe, stmt))
+ {
+ /* Once we've hoisted one statement, insert other statements
+ after it. */
+ gsi_remove (&gsi, false);
+ if (hoist_gsi.ptr)
+ gsi_insert_after (&hoist_gsi, stmt, GSI_NEW_STMT);
+ else
+ {
+ gsi_insert_on_edge_immediate (pe, stmt);
+ hoist_gsi = gsi_for_stmt (stmt);
+ }
+ continue;
+ }
+ gsi_next (&gsi);
+ }
}
/* Returns the DECL_FIELD_BIT_OFFSET of the bitfield accesse in stmt iff its