Hi! After merging from trunk to get #pragma omp for zero iteration handling fixes, this is a port of that for expand_omp_simd which doesn't exist on the trunk.
Committed to gomp-4_0-branch. 2013-05-20 Jakub Jelinek <ja...@redhat.com> * omp-low.c (expand_omp_simd): For collapse > 1 loops, if some loop condition might be not true initially, add runtime test and skip the whole loop. --- gcc/omp-low.c.jj 2013-05-20 13:34:42.000000000 +0200 +++ gcc/omp-low.c 2013-05-20 15:07:59.466798336 +0200 @@ -5120,7 +5120,7 @@ static void expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) { tree type, t; - basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb; + basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb; gimple_stmt_iterator gsi; gimple stmt; bool broken_loop = region->cont == NULL; @@ -5151,6 +5151,7 @@ expand_omp_simd (struct omp_region *regi l2_bb = single_succ (l1_bb); } exit_bb = region->exit; + l2_dom_bb = l1_bb; gsi = gsi_last_bb (entry_bb); @@ -5164,6 +5165,41 @@ expand_omp_simd (struct omp_region *regi { tree itype = TREE_TYPE (fd->loops[i].v); + if (SSA_VAR_P (fd->loop.n2) + && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node, + fold_convert (itype, fd->loops[i].n1), + fold_convert (itype, fd->loops[i].n2))) + == NULL_TREE || !integer_onep (t))) + { + tree n1, n2; + n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1)); + n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE, + true, GSI_SAME_STMT); + n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2)); + n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE, + true, GSI_SAME_STMT); + stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2, + NULL_TREE, NULL_TREE); + gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + if (walk_tree (gimple_cond_lhs_ptr (stmt), + expand_omp_regimplify_p, NULL, NULL) + || walk_tree (gimple_cond_rhs_ptr (stmt), + expand_omp_regimplify_p, NULL, NULL)) + { + gsi = gsi_for_stmt (stmt); + gimple_regimplify_operands (stmt, &gsi); + } + e = split_block (entry_bb, stmt); + ne = make_edge (entry_bb, l2_bb, EDGE_FALSE_VALUE); + ne->probability = REG_BR_PROB_BASE / 2000 - 1; + e->flags = EDGE_TRUE_VALUE; + e->probability = REG_BR_PROB_BASE - ne->probability; + if (l2_dom_bb == l1_bb) + l2_dom_bb = entry_bb; + entry_bb = e->dest; + e = BRANCH_EDGE (entry_bb); + gsi = gsi_last_bb (entry_bb); + } if (POINTER_TYPE_P (itype)) itype = signed_type_for (itype); t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR @@ -5324,7 +5360,7 @@ expand_omp_simd (struct omp_region *regi ne->probability = REG_BR_PROB_BASE / 8; set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb); - set_immediate_dominator (CDI_DOMINATORS, l2_bb, l1_bb); + set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb); set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb); if (!broken_loop) Jakub