Hi! OpenMP 5.0 is going to support loops where condition is not just </<=/>/>= comparison, but also !=, with the requirement that the increment has to be constant expression of 1 or -1 in that case (and no overflow even for unsigned iterators).
The following patch implements it, tested on x86_64-linux, committed to gomp-5_0-branch. 2017-06-29 Jakub Jelinek <ja...@redhat.com> gcc/ * omp-general.c (omp_extract_for_data): Allow NE_EXPR even in OpenMP loops, transform them into LT_EXPR or GT_EXPR loops depending on incr sign. Formatting fixes. gcc/c-family/ * c-common.h (c_finish_omp_for): Add FINAL_P argument. * c-omp.c (check_omp_for_incr_expr): Formatting fixes. (c_finish_omp_for): Add FINAL_P argument. Allow NE_EXPR even in OpenMP loops, diagnose if NE_EXPR and incr expression is not constant expression 1 or -1. Transform NE_EXPR loops with iterators pointers to VLA into LT_EXPR or GT_EXPR loops. gcc/c/ * c-parser.c (c_parser_omp_for_loop): Allow NE_EXPR even in OpenMP loops, adjust c_finish_omp_for caller. gcc/cp/ * parser.c (cp_parser_omp_for_cond): Allow NE_EXPR even in OpenMP loops. * pt.c (dependent_omp_for_p): Return true if class type iterator does not have INTEGER_CST increment. * semantics.c (handle_omp_for_class_iterator): Call cp_fully_fold on incr. (finish_omp_for): Adjust c_finish_omp_for caller. gcc/testsuite/ * c-c++-common/gomp/for-1.c: New test. * c-c++-common/gomp/for-2.c: New test. * c-c++-common/gomp/for-3.c: New test. * c-c++-common/gomp/for-4.c: New test. * c-c++-common/gomp/for-5.c: New test. * gcc.dg/gomp/pr39495-2.c (foo): Don't expect errors on !=. * g++.dg/gomp/pr39495-2.C (foo): Likewise. * g++.dg/gomp/loop-4.C: New test. libgomp/ * testsuite/libgomp.c/for-2.h: If CONDNE macro is defined, define a different N(test), don't define N(f0) to N(f14), but instead define N(f20) to N(f34) using != comparisons. * testsuite/libgomp.c/for-4.c: Use dg-additional-options. * testsuite/libgomp.c/for-7.c: New test. * testsuite/libgomp.c/for-8.c: New test. * testsuite/libgomp.c/for-9.c: New test. * testsuite/libgomp.c/for-10.c: New test. * testsuite/libgomp.c/for-11.c: New test. * testsuite/libgomp.c/for-12.c: New test. * testsuite/libgomp.c/for-13.c: New test. * testsuite/libgomp.c++/for-12.C: Remove dg-options. * testsuite/libgomp.c++/for-15.C: New test. * testsuite/libgomp.c++/for-16.C: New test. * testsuite/libgomp.c++/for-17.C: New test. * testsuite/libgomp.c++/for-18.C: New test. * testsuite/libgomp.c++/for-19.C: New test. * testsuite/libgomp.c++/for-20.C: New test. * testsuite/libgomp.c++/for-21.C: New test. * testsuite/libgomp.c++/for-22.C: New test. * testsuite/libgomp.c++/for-23.C: New test. --- gcc/omp-general.c.jj 2017-05-24 11:48:18.881013651 +0200 +++ gcc/omp-general.c 2017-06-23 15:05:12.655397129 +0200 @@ -252,14 +252,45 @@ omp_extract_for_data (gomp_for *for_stmt loop->cond_code = gimple_omp_for_cond (for_stmt, i); loop->n2 = gimple_omp_for_final (for_stmt, i); gcc_assert (loop->cond_code != NE_EXPR - || gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_CILKSIMD - || gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_CILKFOR); - omp_adjust_for_condition (loc, &loop->cond_code, &loop->n2); - + || (gimple_omp_for_kind (for_stmt) + != GF_OMP_FOR_KIND_OACC_LOOP)); t = gimple_omp_for_incr (for_stmt, i); gcc_assert (TREE_OPERAND (t, 0) == var); loop->step = omp_get_for_step_from_incr (loc, t); + if (loop->cond_code == NE_EXPR + && fd->sched_kind != OMP_CLAUSE_SCHEDULE_CILKFOR + && (!simd || (gimple_omp_for_kind (for_stmt) + != GF_OMP_FOR_KIND_CILKSIMD))) + { + gcc_assert (TREE_CODE (loop->step) == INTEGER_CST); + if (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE) + { + if (integer_onep (loop->step)) + loop->cond_code = LT_EXPR; + else + { + gcc_assert (integer_minus_onep (loop->step)); + loop->cond_code = GT_EXPR; + } + } + else + { + tree unit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (loop->v))); + gcc_assert (TREE_CODE (unit) == INTEGER_CST); + if (tree_int_cst_equal (unit, loop->step)) + loop->cond_code = LT_EXPR; + else + { + gcc_assert (wi::neg (wi::to_widest (unit)) + == wi::to_widest (loop->step)); + loop->cond_code = GT_EXPR; + } + } + } + + omp_adjust_for_condition (loc, &loop->cond_code, &loop->n2); + if (simd || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC && !fd->have_ordered)) @@ -284,9 +315,8 @@ omp_extract_for_data (gomp_for *for_stmt tree n; if (loop->cond_code == LT_EXPR) - n = fold_build2_loc (loc, - PLUS_EXPR, TREE_TYPE (loop->v), - loop->n2, loop->step); + n = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (loop->v), + loop->n2, loop->step); else n = loop->n1; if (TREE_CODE (n) != INTEGER_CST @@ -301,15 +331,13 @@ omp_extract_for_data (gomp_for *for_stmt if (loop->cond_code == LT_EXPR) { n1 = loop->n1; - n2 = fold_build2_loc (loc, - PLUS_EXPR, TREE_TYPE (loop->v), - loop->n2, loop->step); + n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (loop->v), + loop->n2, loop->step); } else { - n1 = fold_build2_loc (loc, - MINUS_EXPR, TREE_TYPE (loop->v), - loop->n2, loop->step); + n1 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (loop->v), + loop->n2, loop->step); n2 = loop->n1; } if (TREE_CODE (n1) != INTEGER_CST @@ -341,27 +369,31 @@ omp_extract_for_data (gomp_for *for_stmt if (POINTER_TYPE_P (itype)) itype = signed_type_for (itype); t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1)); - t = fold_build2_loc (loc, - PLUS_EXPR, itype, - fold_convert_loc (loc, itype, loop->step), t); + t = fold_build2_loc (loc, PLUS_EXPR, itype, + fold_convert_loc (loc, itype, loop->step), + t); t = fold_build2_loc (loc, PLUS_EXPR, itype, t, - fold_convert_loc (loc, itype, loop->n2)); + fold_convert_loc (loc, itype, loop->n2)); t = fold_build2_loc (loc, MINUS_EXPR, itype, t, - fold_convert_loc (loc, itype, loop->n1)); + fold_convert_loc (loc, itype, loop->n1)); if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR) - t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, - fold_build1_loc (loc, NEGATE_EXPR, itype, t), - fold_build1_loc (loc, NEGATE_EXPR, itype, - fold_convert_loc (loc, itype, - loop->step))); + { + tree step = fold_convert_loc (loc, itype, loop->step); + t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, + fold_build1_loc (loc, NEGATE_EXPR, + itype, t), + fold_build1_loc (loc, NEGATE_EXPR, + itype, step)); + } else t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t, - fold_convert_loc (loc, itype, loop->step)); + fold_convert_loc (loc, itype, + loop->step)); t = fold_convert_loc (loc, long_long_unsigned_type_node, t); if (count != NULL_TREE) - count = fold_build2_loc (loc, - MULT_EXPR, long_long_unsigned_type_node, - count, t); + count = fold_build2_loc (loc, MULT_EXPR, + long_long_unsigned_type_node, + count, t); else count = t; if (TREE_CODE (count) != INTEGER_CST) --- gcc/c-family/c-common.h.jj 2017-05-24 11:56:00.000000000 +0200 +++ gcc/c-family/c-common.h 2017-06-27 14:58:35.049139137 +0200 @@ -1291,7 +1291,7 @@ extern void c_finish_omp_flush (location extern void c_finish_omp_taskwait (location_t); extern void c_finish_omp_taskyield (location_t); extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree, - tree, tree, tree, tree); + tree, tree, tree, tree, bool); extern bool c_omp_check_loop_iv (tree, tree, walk_tree_lh); extern bool c_omp_check_loop_iv_exprs (location_t, tree, tree, tree, tree, walk_tree_lh); --- gcc/c-family/c-omp.c.jj 2017-05-24 11:56:00.119183052 +0200 +++ gcc/c-family/c-omp.c 2017-06-28 18:30:29.130040052 +0200 @@ -381,17 +381,17 @@ check_omp_for_incr_expr (location_t loc, t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); if (t != error_mark_node) return fold_build2_loc (loc, MINUS_EXPR, - TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); + TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); break; case PLUS_EXPR: t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl); if (t != error_mark_node) return fold_build2_loc (loc, PLUS_EXPR, - TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); + TREE_TYPE (exp), t, TREE_OPERAND (exp, 1)); t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl); if (t != error_mark_node) return fold_build2_loc (loc, PLUS_EXPR, - TREE_TYPE (exp), TREE_OPERAND (exp, 0), t); + TREE_TYPE (exp), TREE_OPERAND (exp, 0), t); break; case COMPOUND_EXPR: { @@ -457,7 +457,7 @@ c_omp_for_incr_canonicalize_ptr (locatio tree c_finish_omp_for (location_t locus, enum tree_code code, tree declv, tree orig_declv, tree initv, tree condv, tree incrv, - tree body, tree pre_body) + tree body, tree pre_body, bool final_p) { location_t elocus; bool fail = false; @@ -592,7 +592,8 @@ c_finish_omp_for (location_t locus, enum { if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))) { - if (code != CILK_SIMD && code != CILK_FOR) + if (code != CILK_SIMD && code != CILK_FOR + && (code == OACC_LOOP || TREE_CODE (cond) == EQ_EXPR)) cond_ok = false; } else if (operand_equal_p (TREE_OPERAND (cond, 1), @@ -605,7 +606,9 @@ c_finish_omp_for (location_t locus, enum 0)) TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR ? LT_EXPR : GE_EXPR); - else if (code != CILK_SIMD && code != CILK_FOR) + else if (code != CILK_SIMD && code != CILK_FOR + && (code == OACC_LOOP + || TREE_CODE (cond) == EQ_EXPR)) cond_ok = false; } } @@ -641,6 +644,23 @@ c_finish_omp_for (location_t locus, enum break; incr_ok = true; + if (!fail + && TREE_CODE (cond) == NE_EXPR + && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE + && code != CILK_SIMD + && code != CILK_FOR + && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))) + && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))) + != INTEGER_CST)) + { + /* For pointer to VLA, transform != into < or > + depending on whether incr is increment or decrement. */ + if (TREE_CODE (incr) == PREINCREMENT_EXPR + || TREE_CODE (incr) == POSTINCREMENT_EXPR) + TREE_SET_CODE (cond, LT_EXPR); + else + TREE_SET_CODE (cond, GT_EXPR); + } incr = c_omp_for_incr_canonicalize_ptr (elocus, decl, incr); break; @@ -676,6 +696,60 @@ c_finish_omp_for (location_t locus, enum incr = build2 (MODIFY_EXPR, void_type_node, decl, t); } } + if (!fail + && incr_ok + && TREE_CODE (cond) == NE_EXPR + && code != CILK_SIMD + && code != CILK_FOR) + { + tree i = TREE_OPERAND (incr, 1); + i = TREE_OPERAND (i, TREE_OPERAND (i, 0) == decl); + i = c_fully_fold (i, false, NULL); + if (!final_p + && TREE_CODE (i) != INTEGER_CST) + ; + else if (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE) + { + tree unit + = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))); + if (unit) + { + enum tree_code ccode = GT_EXPR; + unit = c_fully_fold (unit, false, NULL); + i = fold_convert (TREE_TYPE (unit), i); + if (operand_equal_p (unit, i, 0)) + ccode = LT_EXPR; + if (ccode == GT_EXPR) + { + i = fold_unary (NEGATE_EXPR, TREE_TYPE (i), i); + if (i == NULL_TREE + || !operand_equal_p (unit, i, 0)) + { + error_at (elocus, + "increment is not constant 1 or " + "-1 for != condition"); + fail = true; + } + } + if (TREE_CODE (unit) != INTEGER_CST) + /* For pointer to VLA, transform != into < or > + depending on whether the pointer is + incremented or decremented in each + iteration. */ + TREE_SET_CODE (cond, ccode); + } + } + else + { + if (!integer_onep (i) && !integer_minus_onep (i)) + { + error_at (elocus, + "increment is not constant 1 or -1 for" + " != condition"); + fail = true; + } + } + } break; default: --- gcc/c/c-parser.c.jj 2017-05-24 11:56:00.111183154 +0200 +++ gcc/c/c-parser.c 2017-06-27 15:02:58.601006059 +0200 @@ -15136,7 +15136,7 @@ c_parser_omp_for_loop (location_t loc, c case LE_EXPR: break; case NE_EXPR: - if (code == CILK_SIMD || code == CILK_FOR) + if (code != OACC_LOOP) break; /* FALLTHRU. */ default: @@ -15273,7 +15273,7 @@ c_parser_omp_for_loop (location_t loc, c if (!fail) { stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, - incrv, body, pre_body); + incrv, body, pre_body, true); /* Check for iterators appearing in lb, b or incr expressions. */ if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) --- gcc/cp/parser.c.jj 2017-05-24 11:56:00.000000000 +0200 +++ gcc/cp/parser.c 2017-06-23 11:00:52.811115577 +0200 @@ -34196,9 +34196,8 @@ cp_parser_omp_for_cond (cp_parser *parse case LE_EXPR: break; case NE_EXPR: - if (code == CILK_SIMD || code == CILK_FOR) + if (code != OACC_LOOP) break; - /* Fall through: OpenMP disallows NE_EXPR. */ gcc_fallthrough (); default: return error_mark_node; --- gcc/cp/pt.c.jj 2017-05-24 11:56:00.000000000 +0200 +++ gcc/cp/pt.c 2017-06-28 16:24:09.654377250 +0200 @@ -24468,6 +24468,20 @@ dependent_omp_for_p (tree declv, tree in if (type_dependent_expression_p (TREE_OPERAND (t, 0)) || type_dependent_expression_p (TREE_OPERAND (t, 1))) return true; + + /* If this loop has a class iterator with != comparison + with increment other than i++/++i/i--/--i, make sure the + increment is constant. */ + if (CLASS_TYPE_P (TREE_TYPE (decl)) + && TREE_CODE (cond) == NE_EXPR) + { + if (TREE_OPERAND (t, 0) == decl) + t = TREE_OPERAND (t, 1); + else + t = TREE_OPERAND (t, 0); + if (TREE_CODE (t) != INTEGER_CST) + return true; + } } } } --- gcc/cp/semantics.c.jj 2017-05-24 11:56:00.000000000 +0200 +++ gcc/cp/semantics.c 2017-06-28 15:53:59.303706277 +0200 @@ -7891,6 +7891,7 @@ handle_omp_for_class_iterator (int i, lo } incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); + incr = cp_fully_fold (incr); bool taskloop_iv_seen = false; for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE @@ -8277,7 +8278,8 @@ finish_omp_for (location_t locus, enum t block = push_stmt_list (); omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv, - incrv, body, pre_body); + incrv, body, pre_body, + !processing_template_decl); /* Check for iterators appearing in lb, b or incr expressions. */ if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees)) --- gcc/testsuite/c-c++-common/gomp/for-1.c.jj 2017-06-28 18:06:50.461763313 +0200 +++ gcc/testsuite/c-c++-common/gomp/for-1.c 2017-06-28 17:56:03.000000000 +0200 @@ -0,0 +1,60 @@ +void bar (int); + +int a[256]; + +void +foo (void) +{ + int i; + #pragma omp for + for (i = 0; i != 64; i++) + bar (i); + #pragma omp for + for (i = 128; i != 64; i--) + bar (i); + #pragma omp for + for (i = 0; i != 64; i = i + 1) + bar (i); + #pragma omp for + for (i = 128; i != 64; i = i - 1) + bar (i); + #pragma omp for + for (i = 0; i != 64; i = 1 + i) + bar (i); + #pragma omp for + for (i = 128; i != 64; i = -1 + i) + bar (i); + #pragma omp for + for (i = 0; i != 64; i += 1) + bar (i); + #pragma omp for + for (i = 128; i != 64; i -= 1) + bar (i); + #pragma omp single + { + #pragma omp simd + for (i = 0; i != 64; i++) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i--) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 0; i != 64; i = i + 1) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i = i - 1) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 0; i != 64; i = 1 + i) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i = -1 + i) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 0; i != 64; i += 1) + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i -= 1) + a[i] = a[i] + 1; + } +} --- gcc/testsuite/c-c++-common/gomp/for-2.c.jj 2017-06-28 18:06:53.597726264 +0200 +++ gcc/testsuite/c-c++-common/gomp/for-2.c 2017-06-12 11:32:36.000000000 +0200 @@ -0,0 +1,31 @@ +void bar (short *); + +void +foo (short *q, short *r, short *s) +{ + short *p; + #pragma omp for + for (p = q; p != r; p++) + bar (p); + #pragma omp for + for (p = s; p != r; p--) + bar (p); + #pragma omp for + for (p = q; p != r; p = p + 1) + bar (p); + #pragma omp for + for (p = s; p != r; p = p - 1) + bar (p); + #pragma omp for + for (p = q; p != r; p = 1 + p) + bar (p); + #pragma omp for + for (p = s; p != r; p = -1 + p) + bar (p); + #pragma omp for + for (p = q; p != r; p += 1) + bar (p); + #pragma omp for + for (p = s; p != r; p -= 1) + bar (p); +} --- gcc/testsuite/c-c++-common/gomp/for-3.c.jj 2017-06-28 18:07:24.625359692 +0200 +++ gcc/testsuite/c-c++-common/gomp/for-3.c 2017-06-28 18:14:54.211048119 +0200 @@ -0,0 +1,48 @@ +void bar (int); + +int a[256]; + +void +foo (int j) +{ + int i; + #pragma omp for + for (i = 0; i != 64; i = i + 4) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp for + for (i = 128; i != 64; i = i - 4) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp for + for (i = 0; i != 64; i = j + i) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp for + for (i = 128; i != 64; i = -16 + i) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp for + for (i = 0; i != 64; i += j) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp for + for (i = 128; i != 64; i -= 8) /* { dg-error "increment is not constant 1 or -1" } */ + bar (i); + #pragma omp single + { + #pragma omp simd + for (i = 0; i != 64; i = i + 16) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i = i - 2) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + #pragma omp simd + for (i = 0; i != 64; i = j + i) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i = -j + i) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + #pragma omp simd + for (i = 0; i != 64; i += 8) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + #pragma omp simd + for (i = 128; i != 64; i -= j) /* { dg-error "increment is not constant 1 or -1" } */ + a[i] = a[i] + 1; + } +} --- gcc/testsuite/c-c++-common/gomp/for-4.c.jj 2017-06-28 18:15:20.800733979 +0200 +++ gcc/testsuite/c-c++-common/gomp/for-4.c 2017-06-28 18:16:28.669932147 +0200 @@ -0,0 +1,25 @@ +void bar (short *); + +void +foo (short *q, short *r, short *s, long t) +{ + short *p; + #pragma omp for + for (p = q; p != r; p = p + 5) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = p - 2) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p = t + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = -t + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p += t) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p -= 7) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); +} --- gcc/testsuite/c-c++-common/gomp/for-5.c.jj 2017-06-28 19:30:19.008831921 +0200 +++ gcc/testsuite/c-c++-common/gomp/for-5.c 2017-06-28 19:34:54.093593473 +0200 @@ -0,0 +1,50 @@ +// { dg-options "-fopenmp" } + +void bar (void *); + +__attribute__((noinline, noclone)) void +foo (void *qx, void *rx, void *sx, int n) +{ + unsigned short (*q)[n], (*r)[n], (*s)[n], (*p)[n]; + q = (typeof (q)) qx; + r = (typeof (r)) rx; + s = (typeof (s)) sx; + int t = 1; + int o = -1; + #pragma omp for + for (p = q; p != r; p += t) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p += o) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p = p + t) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = p + o) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p = t + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = o + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p += 2) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p -= 2) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p = p + 3) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = p - 3) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = q; p != r; p = 4 + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); + #pragma omp for + for (p = s; p != r; p = -5 + p) /* { dg-error "increment is not constant 1 or -1" } */ + bar (p); +} --- gcc/testsuite/gcc.dg/gomp/pr39495-2.c.jj 2017-05-04 15:05:34.757845532 +0200 +++ gcc/testsuite/gcc.dg/gomp/pr39495-2.c 2017-06-28 15:11:28.703710328 +0200 @@ -13,25 +13,25 @@ foo (void) unsigned int u; #pragma omp for - for (i = INT_MIN + 6; i != INT_MIN; i--) /* { dg-error "invalid controlling predicate" } */ + for (i = INT_MIN + 6; i != INT_MIN; i--) ; #pragma omp for for (i = INT_MIN + 6; i == INT_MIN; i--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (i = INT_MAX - 6; i != INT_MAX; i++) /* { dg-error "invalid controlling predicate" } */ + for (i = INT_MAX - 6; i != INT_MAX; i++) ; #pragma omp for for (i = INT_MAX - 6; i == INT_MAX; i++) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (u = 6; u != 0; u--) /* { dg-error "invalid controlling predicate" } */ + for (u = 6; u != 0; u--) ; #pragma omp for for (u = 6; u == 0; u--) /* { dg-error "invalid controlling predicate" } */ ; #pragma omp for - for (u = UINT_MAX - 6; u != UINT_MAX; u++) /* { dg-error "invalid controlling predicate" } */ + for (u = UINT_MAX - 6; u != UINT_MAX; u++) ; #pragma omp for for (u = UINT_MAX - 6; u == UINT_MAX; u++) /* { dg-error "invalid controlling predicate" } */ --- gcc/testsuite/g++.dg/gomp/pr39495-2.C.jj 2017-05-04 15:05:46.000000000 +0200 +++ gcc/testsuite/g++.dg/gomp/pr39495-2.C 2017-06-28 15:18:01.041022936 +0200 @@ -13,25 +13,25 @@ foo (void) unsigned int u; #pragma omp for - for (i = INT_MIN + 6; i != INT_MIN; i--) // { dg-error "invalid controlling predicate" } + for (i = INT_MIN + 6; i != INT_MIN; i--) ; #pragma omp for for (i = INT_MIN + 6; i == INT_MIN; i--) // { dg-error "invalid controlling predicate" } ; #pragma omp for - for (i = INT_MAX - 6; i != INT_MAX; i++) // { dg-error "invalid controlling predicate" } + for (i = INT_MAX - 6; i != INT_MAX; i++) ; #pragma omp for for (i = INT_MAX - 6; i == INT_MAX; i++) // { dg-error "invalid controlling predicate" } ; #pragma omp for - for (u = 6; u != 0; u--) // { dg-error "invalid controlling predicate" } + for (u = 6; u != 0; u--) ; #pragma omp for for (u = 6; u == 0; u--) // { dg-error "invalid controlling predicate" } ; #pragma omp for - for (u = UINT_MAX - 6; u != UINT_MAX; u++) // { dg-error "invalid controlling predicate" } + for (u = UINT_MAX - 6; u != UINT_MAX; u++) ; #pragma omp for for (u = UINT_MAX - 6; u == UINT_MAX; u++) // { dg-error "invalid controlling predicate" } --- gcc/testsuite/g++.dg/gomp/loop-4.C.jj 2017-06-28 19:06:22.035756688 +0200 +++ gcc/testsuite/g++.dg/gomp/loop-4.C 2017-06-28 19:19:07.440742612 +0200 @@ -0,0 +1,227 @@ +typedef __PTRDIFF_TYPE__ ptrdiff_t; + +template <typename T> +class I +{ +public: + typedef ptrdiff_t difference_type; + I (); + ~I (); + I (T *); + I (const I &); + T &operator * (); + T *operator -> (); + T &operator [] (const difference_type &) const; + I &operator = (const I &); + I &operator ++ (); + I operator ++ (int); + I &operator -- (); + I operator -- (int); + I &operator += (const difference_type &); + I &operator -= (const difference_type &); + I operator + (const difference_type &) const; + I operator - (const difference_type &) const; + template <typename S> friend bool operator == (I<S> &, I<S> &); + template <typename S> friend bool operator == (const I<S> &, const I<S> &); + template <typename S> friend bool operator < (I<S> &, I<S> &); + template <typename S> friend bool operator < (const I<S> &, const I<S> &); + template <typename S> friend bool operator <= (I<S> &, I<S> &); + template <typename S> friend bool operator <= (const I<S> &, const I<S> &); + template <typename S> friend bool operator > (I<S> &, I<S> &); + template <typename S> friend bool operator > (const I<S> &, const I<S> &); + template <typename S> friend bool operator >= (I<S> &, I<S> &); + template <typename S> friend bool operator >= (const I<S> &, const I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &); + template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &); +private: + T *p; +}; + +template <typename T> bool operator == (I<T> &, I<T> &); +template <typename T> bool operator == (const I<T> &, const I<T> &); +template <typename T> bool operator != (I<T> &, I<T> &); +template <typename T> bool operator != (const I<T> &, const I<T> &); +template <typename T> bool operator < (I<T> &, I<T> &); +template <typename T> bool operator < (const I<T> &, const I<T> &); +template <typename T> bool operator <= (I<T> &, I<T> &); +template <typename T> bool operator <= (const I<T> &, const I<T> &); +template <typename T> bool operator > (I<T> &, I<T> &); +template <typename T> bool operator > (const I<T> &, const I<T> &); +template <typename T> bool operator >= (I<T> &, I<T> &); +template <typename T> bool operator >= (const I<T> &, const I<T> &); +template <typename T> typename I<T>::difference_type operator - (I<T> &, I<T> &); +template <typename T> typename I<T>::difference_type operator - (const I<T> &, const I<T> &); +template <typename T> I<T> operator + (typename I<T>::difference_type, const I<T> &); + +ptrdiff_t foo (I<int> &); +I<int> &bar (I<int> &); +I<int> &baz (I<int> *); + +void +f0 () +{ + int i; + const int j = 1; + const int k = -1; + const int m = 2; + const int n = -7; + int o = 1; + int p = -1; + #pragma omp for + for (i = 0; i != 64; i += j) + ; + #pragma omp for + for (i = 64; i != 0; i -= j) + ; + #pragma omp for + for (i = 0; i != 64; i -= k) + ; + #pragma omp for + for (i = 64; i != 0; i += k) + ; + #pragma omp for + for (i = 0; i != 64; i += m) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 64; i != 0; i -= m) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 0; i != 64; i -= n) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 64; i != 0; i += n) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 0; i != 64; i += o) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 64; i != 0; i -= o) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 0; i != 64; i -= p) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = 64; i != 0; i += p) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; +} + +void +f1 (I<int> &x, I<int> &y, I<int> &u, I<int> &v) +{ + I<int> i, j; + const int k = 1; + const int l = -1; + const int m = 2; + const int n = -7; + int o = 1; + int p = -1; + #pragma omp for + for (i = x; i != y; i++) + ; + #pragma omp for + for (i = x; y != i; ++i) + ; + #pragma omp for + for (i = x; i != y; i = i + 1) + ; + #pragma omp for + for (i = x; i != y; i = 1 + i) + ; + #pragma omp for + for (i = y; i != x; i--) + ; + #pragma omp for + for (i = y; x != i; --i) + ; + #pragma omp for + for (i = y; i != x; i = i - 1) + ; + #pragma omp for + for (i = y; i != x; i = -1 + i) + ; + #pragma omp for + for (i = x; i != y; i = i + k) + ; + #pragma omp for + for (i = x; i != y; i = k + i) + ; + #pragma omp for + for (i = y; i != x; i = i - k) + ; + #pragma omp for + for (i = y; i != x; i = -k + i) + ; + #pragma omp for + for (i = x; i != y; i = i - l) + ; + #pragma omp for + for (i = x; i != y; i = -l + i) + ; + #pragma omp for + for (i = y; i != x; i = i + l) + ; + #pragma omp for + for (i = y; i != x; i = l + i) + ; + #pragma omp for + for (i = x; i != y; i = i + 2) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = 7 + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = i - 2) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = -7 + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = i + m) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = m + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = i - m) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = -m + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = i - n) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = -n + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = i + n) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = n + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = i + o) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = o + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = i - o) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = -o + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = i - p) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = x; i != y; i = -p + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = i + p) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; + #pragma omp for + for (i = y; i != x; i = p + i) // { dg-error "increment is not constant 1 or -1 for != condition" } + ; +} --- libgomp/testsuite/libgomp.c/for-2.h.jj 2017-05-04 15:04:53.000000000 +0200 +++ libgomp/testsuite/libgomp.c/for-2.h 2017-06-23 19:35:12.101928314 +0200 @@ -21,6 +21,7 @@ noreturn (void) #define OMPFROM(v) do {} while (0) #endif +#ifndef CONDNE __attribute__((noinline, noclone)) void N(f0) (void) { @@ -311,3 +312,292 @@ N(test) (void) return 1; return 0; } + +#else + +__attribute__((noinline, noclone)) void +N(f20) (void) +{ + int i; + OMPTGT +#pragma omp F S + for (i = 0; i != 1500; i++) + a[i] += 2; +} + +__attribute__((noinline, noclone)) void +N(f21) (void) +{ + OMPTGT +#pragma omp F S + for (unsigned int i = __INT_MAX__; i < 1500U + __INT_MAX__; i += 2 - 1) + a[(i - __INT_MAX__)] -= 2; +} + +__attribute__((noinline, noclone)) void +N(f22) (void) +{ + unsigned long long i; + OMPTGT +#pragma omp F S + for (i = __LONG_LONG_MAX__ + 1500ULL - 27; + i != __LONG_LONG_MAX__ - 27ULL; i -= 3 - 2) + a[i + 26LL - __LONG_LONG_MAX__] -= 4; +} + +__attribute__((noinline, noclone)) void +N(f23) (long long n1, long long n2) +{ + OMPTGT +#pragma omp F S + for (long long i = n1 + 23; i != n2 - 25; --i) + a[i + 48] += 7; +} + +__attribute__((noinline, noclone)) void +N(f24) (void) +{ + unsigned int i; + OMPTGT +#pragma omp F S + for (i = 30; i != 30; i += 1) + a[i] += 10; +} + +__attribute__((noinline, noclone)) void +N(f25) (int n11, int n12, int n21, int n22, int n31, int n32, + int s2) +{ + SC int v1, v2, v3; + OMPTGT +#pragma omp F S collapse(3) + for (v1 = n11; v1 != n12; v1 += 17 - 19 + 3) + for (v2 = n21; v2 < n22; v2 += s2) + for (v3 = n31; v3 != n32; ++v3) + b[v1][v2][v3] += 2.5; +} + +__attribute__((noinline, noclone)) void +N(f26) (int n11, int n12, int n21, int n22, long long n31, long long n32, + int s2) +{ + SC int v1, v2; + SC long long v3; + OMPTGT +#pragma omp F S collapse(3) + for (v1 = n11; v1 != n12; v1 += -1) + for (v2 = n21; v2 > n22; v2 += s2) + for (v3 = n31; v3 != n32; v3 --) + b[v1][v2 / 2][v3] -= 4.5; +} + +__attribute__((noinline, noclone)) void +N(f27) (void) +{ + SC unsigned int v1, v3; + SC unsigned long long v2; + OMPTGT +#pragma omp F S collapse(3) + for (v1 = 0; v1 < 20; v1 += 2) + for (v2 = __LONG_LONG_MAX__ + 11ULL; + v2 != __LONG_LONG_MAX__ - 4ULL; -- v2) + for (v3 = 10; v3 != 0; v3--) + b[v1 >> 1][v2 - __LONG_LONG_MAX__ + 3][v3 - 1] += 5.5; +} + +__attribute__((noinline, noclone)) void +N(f28) (void) +{ + SC long long v1, v2, v3; + OMPTGT +#pragma omp F S collapse(3) + for (v1 = 0; v1 != 20; v1 -= 17 - 18) + for (v2 = 30; v2 < 20; v2++) + for (v3 = 10; v3 < 0; v3--) + b[v1][v2][v3] += 5.5; +} + +__attribute__((noinline, noclone)) void +N(f29) (void) +{ + int i; + OMPTGT +#pragma omp F S + for (i = 20; i != 20; i++) + { + a[i] += 2; + noreturn (); + a[i] -= 4; + } +} + +__attribute__((noinline, noclone)) void +N(f30) (void) +{ + SC int i; + OMPTGT +#pragma omp F S collapse(3) + for (i = 0; i != 10; i++) + for (int j = 10; j < 8; j++) + for (long k = -10; k != 10; k++) + { + b[i][j][k] += 4; + noreturn (); + b[i][j][k] -= 8; + } +} + +__attribute__((noinline, noclone)) void +N(f31) (int n) +{ + int i; + OMPTGT +#pragma omp F S + for (i = 20; i != n; i++) + { + a[i] += 8; + noreturn (); + a[i] -= 16; + } +} + +__attribute__((noinline, noclone)) void +N(f32) (int n) +{ + SC int i; + OMPTGT +#pragma omp F S collapse(3) + for (i = 0; i != 10; i++) + for (int j = n; j != 12; j++) + for (long k = -10; k != 10; k++) + { + b[i][j][k] += 16; + noreturn (); + b[i][j][k] -= 32; + } +} + +__attribute__((noinline, noclone)) void +N(f33) (void) +{ + int *i; + OMPTGT +#pragma omp F S + for (i = a; i != &a[1500]; i++) + i[0] += 2; +} + +__attribute__((noinline, noclone)) void +N(f34) (void) +{ + SC float *i; + OMPTGT +#pragma omp F S collapse(3) + for (i = &b[0][0][0]; i != &b[0][0][10]; i++) + for (float *j = &b[0][15][0]; j > &b[0][0][0]; j -= 10) + for (float *k = &b[0][0][10]; k != &b[0][0][0]; --k) + b[i - &b[0][0][0]][(j - &b[0][0][0]) / 10 - 1][(k - &b[0][0][0]) - 1] + -= 3.5; +} + +__attribute__((noinline, noclone)) int +N(test) (void) +{ + int i, j, k; + for (i = 0; i < 1500; i++) + a[i] = i - 25; + OMPTO (a); + N(f20) (); + OMPFROM (a); + for (i = 0; i < 1500; i++) + if (a[i] != i - 23) + return 1; + N(f21) (); + OMPFROM (a); + for (i = 0; i < 1500; i++) + if (a[i] != i - 25) + return 1; + N(f22) (); + OMPFROM (a); + for (i = 0; i < 1500; i++) + if (a[i] != i - 29) + return 1; + N(f23) (1500LL - 1 - 23 - 48, -1LL + 25 - 48); + OMPFROM (a); + for (i = 0; i < 1500; i++) + if (a[i] != i - 22) + return 1; + N(f24) (); + OMPFROM (a); + for (i = 0; i < 1500; i++) + if (a[i] != i - 22) + return 1; + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + b[i][j][k] = i - 2.5 + 1.5 * j - 1.5 * k; + OMPTO (b); + N(f25) (0, 10, 0, 15, 0, 10, 1); + OMPFROM (b); + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i + 1.5 * j - 1.5 * k) + return 1; + N(f25) (0, 10, 30, 15, 0, 10, 5); + OMPFROM (b); + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i + 1.5 * j - 1.5 * k) + return 1; + N(f26) (9, -1, 29, 0, 9, -1, -2); + OMPFROM (b); + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i - 4.5 + 1.5 * j - 1.5 * k) + return 1; + N(f27) (); + OMPFROM (b); + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k) + return 1; + N(f28) (); + OMPFROM (b); + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k) + return 1; + N(f29) (); + N(f30) (); + N(f31) (20); + N(f32) (12); + OMPFROM (a); + OMPFROM (b); + for (i = 0; i < 1500; i++) + if (a[i] != i - 22) + return 1; + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i + 1.0 + 1.5 * j - 1.5 * k) + return 1; + N(f33) (); + N(f34) (); + OMPFROM (a); + OMPFROM (b); + for (i = 0; i < 1500; i++) + if (a[i] != i - 20) + return 1; + for (i = 0; i < 10; i++) + for (j = 0; j < 15; j++) + for (k = 0; k < 10; k++) + if (b[i][j][k] != i - 2.5 + 1.5 * j - 1.5 * k) + return 1; + return 0; +} +#endif --- libgomp/testsuite/libgomp.c/for-4.c.jj 2017-05-04 15:04:53.000000000 +0200 +++ libgomp/testsuite/libgomp.c/for-4.c 2017-06-23 19:40:29.718234544 +0200 @@ -1,4 +1,4 @@ -/* { dg-options "-std=gnu99 -fopenmp" } */ +/* { dg-additional-options "-std=gnu99" } */ extern void abort (void); --- libgomp/testsuite/libgomp.c/for-7.c.jj 2017-06-23 18:20:35.568048702 +0200 +++ libgomp/testsuite/libgomp.c/for-7.c 2017-06-23 18:20:29.160122759 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-1.c" --- libgomp/testsuite/libgomp.c/for-8.c.jj 2017-06-23 19:35:36.707642158 +0200 +++ libgomp/testsuite/libgomp.c/for-8.c 2017-06-23 19:35:41.010592116 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-2.c" --- libgomp/testsuite/libgomp.c/for-9.c.jj 2017-06-23 19:35:51.670468145 +0200 +++ libgomp/testsuite/libgomp.c/for-9.c 2017-06-23 19:35:59.094381807 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-3.c" --- libgomp/testsuite/libgomp.c/for-10.c.jj 2017-06-23 19:40:46.635037807 +0200 +++ libgomp/testsuite/libgomp.c/for-10.c 2017-06-23 19:40:51.662979334 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-4.c" --- libgomp/testsuite/libgomp.c/for-11.c.jj 2017-06-23 19:40:59.187891822 +0200 +++ libgomp/testsuite/libgomp.c/for-11.c 2017-06-23 19:41:04.809826441 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-5.c" --- libgomp/testsuite/libgomp.c/for-12.c.jj 2017-06-23 19:41:13.072730346 +0200 +++ libgomp/testsuite/libgomp.c/for-12.c 2017-06-23 19:41:18.414668221 +0200 @@ -0,0 +1,4 @@ +/* { dg-additional-options "-std=gnu99" } */ + +#define CONDNE +#include "for-6.c" --- libgomp/testsuite/libgomp.c/for-13.c.jj 2017-06-28 18:56:28.138745794 +0200 +++ libgomp/testsuite/libgomp.c/for-13.c 2017-06-28 19:02:32.231461074 +0200 @@ -0,0 +1,99 @@ +unsigned short a[256]; + +__attribute__((noinline, noclone)) void +bar (void *x, unsigned short z) +{ + unsigned short *y = (unsigned short *) x; + if (y < &a[5] || y > &a[222] || y == &a[124]) + __builtin_abort (); + *y += z; +} + +__attribute__((noinline, noclone)) void +foo (void *qx, void *rx, void *sx, int n) +{ + unsigned short (*q)[n], (*r)[n], (*s)[n], (*p)[n]; + q = (typeof (q)) qx; + r = (typeof (r)) rx; + s = (typeof (s)) sx; + #pragma omp for + for (p = q; p != r; p++) + bar (p, 1); + #pragma omp for + for (p = s; p != r; p--) + bar (p, 2); + #pragma omp for + for (p = q; p != r; p = p + 1) + bar (p, 4); + #pragma omp for + for (p = s; p != r; p = p - 1) + bar (p, 8); + #pragma omp for + for (p = q; p != r; p = 1 + p) + bar (p, 16); + #pragma omp for + for (p = s; p != r; p = -1 + p) + bar (p, 32); + #pragma omp for + for (p = q; p != r; p += 1) + bar (p, 64); + #pragma omp for + for (p = s; p != r; p -= 1) + bar (p, 128); +} + +__attribute__((noinline, noclone)) void +baz (void *qx, void *rx, void *sx, int n) +{ + unsigned short (*q)[n], (*r)[n], (*s)[n], (*p)[n]; + q = (typeof (q)) qx; + r = (typeof (r)) rx; + s = (typeof (s)) sx; + #pragma omp for + for (p = q; p < r; p++) + bar (p, 256); + #pragma omp for + for (p = s; p > r; p--) + bar (p, 512); + #pragma omp for + for (p = q; p < r; p = p + 1) + bar (p, 1024); + #pragma omp for + for (p = s; p > r; p = p - 1) + bar (p, 2048); + #pragma omp for + for (p = q; p < r; p = 1 + p) + bar (p, 4096); + #pragma omp for + for (p = s; p > r; p = -1 + p) + bar (p, 8192); + #pragma omp for + for (p = q; p < r; p += 1) + bar (p, 16384); + #pragma omp for + for (p = s; p > r; p -= 1) + bar (p, 32768U); +} + +int +main () +{ + int i; + volatile int j = 7; +#pragma omp parallel + { + foo (&a[5 + (j - 7)], &a[124 + (j - 7)], &a[222 + (j - 7)], j); + baz (&a[5 + (j - 7)], &a[124 + (j - 7)], &a[222 + (j - 7)], j); + } + for (i = 0; i < 256; i++) + if (i < 5 || i > 222 || i == 124 || ((i - 5) % 7) != 0) + { + if (a[i]) + __builtin_abort (); + } + else if (i < 124 && a[i] != 1 + 4 + 16 + 64 + 256 + 1024 + 4096 + 16384) + __builtin_abort (); + else if (i > 124 && a[i] != 2 + 8 + 32 + 128 + 512 + 2048 + 8192 + 32768U) + __builtin_abort (); + return 0; +} --- libgomp/testsuite/libgomp.c++/for-12.C.jj 2017-05-04 15:04:52.000000000 +0200 +++ libgomp/testsuite/libgomp.c++/for-12.C 2017-06-23 19:48:16.502805999 +0200 @@ -1,5 +1,3 @@ -/* { dg-options "-fopenmp" } */ - extern "C" void abort (void); #define M(x, y, z) O(x, y, z) --- libgomp/testsuite/libgomp.c++/for-15.C.jj 2017-06-23 19:50:00.023518987 +0200 +++ libgomp/testsuite/libgomp.c++/for-15.C 2017-06-23 19:48:49.000428062 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-9.C" --- libgomp/testsuite/libgomp.c++/for-16.C.jj 2017-06-23 19:50:00.025518959 +0200 +++ libgomp/testsuite/libgomp.c++/for-16.C 2017-06-23 19:49:18.494085061 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-10.C" --- libgomp/testsuite/libgomp.c++/for-17.C.jj 2017-06-23 19:50:00.026518944 +0200 +++ libgomp/testsuite/libgomp.c++/for-17.C 2017-06-23 19:49:22.896033868 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-11.C" --- libgomp/testsuite/libgomp.c++/for-18.C.jj 2017-06-23 19:50:00.028518916 +0200 +++ libgomp/testsuite/libgomp.c++/for-18.C 2017-06-23 19:49:27.952973698 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-12.C" --- libgomp/testsuite/libgomp.c++/for-19.C.jj 2017-06-23 19:50:00.029518902 +0200 +++ libgomp/testsuite/libgomp.c++/for-19.C 2017-06-23 19:49:31.990916447 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-13.C" --- libgomp/testsuite/libgomp.c++/for-20.C.jj 2017-06-23 19:50:00.031518873 +0200 +++ libgomp/testsuite/libgomp.c++/for-20.C 2017-06-23 19:49:36.853847498 +0200 @@ -0,0 +1,2 @@ +#define CONDNE +#include "for-14.C" --- libgomp/testsuite/libgomp.c++/for-21.C.jj 2017-06-28 14:27:29.617173520 +0200 +++ libgomp/testsuite/libgomp.c++/for-21.C 2017-06-28 14:21:53.000000000 +0200 @@ -0,0 +1,291 @@ +// { dg-do run } + +typedef __PTRDIFF_TYPE__ ptrdiff_t; +extern "C" void abort (); + +template <typename T> +class I +{ +public: + typedef ptrdiff_t difference_type; + I (); + ~I (); + I (T *); + I (const I &); + T &operator * (); + T *operator -> (); + T &operator [] (const difference_type &) const; + I &operator = (const I &); + I &operator ++ (); + I operator ++ (int); + I &operator -- (); + I operator -- (int); + I &operator += (const difference_type &); + I &operator -= (const difference_type &); + I operator + (const difference_type &) const; + I operator - (const difference_type &) const; + template <typename S> friend bool operator == (I<S> &, I<S> &); + template <typename S> friend bool operator == (const I<S> &, const I<S> &); + template <typename S> friend bool operator < (I<S> &, I<S> &); + template <typename S> friend bool operator < (const I<S> &, const I<S> &); + template <typename S> friend bool operator <= (I<S> &, I<S> &); + template <typename S> friend bool operator <= (const I<S> &, const I<S> &); + template <typename S> friend bool operator > (I<S> &, I<S> &); + template <typename S> friend bool operator > (const I<S> &, const I<S> &); + template <typename S> friend bool operator >= (I<S> &, I<S> &); + template <typename S> friend bool operator >= (const I<S> &, const I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &); + template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &); +private: + T *p; +}; +template <typename T> I<T>::I () : p (0) {} +template <typename T> I<T>::~I () {} +template <typename T> I<T>::I (T *x) : p (x) {} +template <typename T> I<T>::I (const I &x) : p (x.p) {} +template <typename T> T &I<T>::operator * () { return *p; } +template <typename T> T *I<T>::operator -> () { return p; } +template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; } +template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; } +template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; } +template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); } +template <typename T> I<T> &I<T>::operator -- () { --p; return *this; } +template <typename T> I<T> I<T>::operator -- (int) { return I (p--); } +template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; } +template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; } +template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); } +template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); } +template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; } +template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; } +template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); } +template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); } +template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; } +template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; } +template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; } +template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; } +template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; } +template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; } +template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; } +template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; } +template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; } +template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; } +template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); } + +template <typename T> +class J +{ +public: + J(const I<T> &x, const I<T> &y) : b (x), e (y) {} + const I<T> &begin (); + const I<T> &end (); +private: + I<T> b, e; +}; + +template <typename T> const I<T> &J<T>::begin () { return b; } +template <typename T> const I<T> &J<T>::end () { return e; } + +int results[2000]; + +template <typename T> +void +baz (I<T> &i) +{ + if (*i < 0 || *i >= 2000) + abort (); + results[*i]++; +} + +void +f1 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for + for (I<int> i = x; i != y; i++) + baz (i); +} + +void +f2 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for private(i) + for (i = x; i != y - 1; i = 2 - 8 + 7 + i) + baz (i); +} + +template <typename T> +void +f3 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for + for (I<int> i = x; i != y; i = i + 9 - 8) + baz (i); +} + +template <typename T> +void +f4 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for lastprivate(i) + for (i = x + 2000 - 64; i != y + 10; --i) + baz (i); +} + +void +f5 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for + for (I<int> i = x + 2000 - 64; i != y + 10; i--) + baz (i); +} + +template <int N> +void +f6 (const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for + for (I<int> i = x + 2000 - 64; i != y + 10; i = i - 12 + 11) + { + I<int> j = i + N; + baz (j); + } +} + +template <int N> +void +f7 (I<int> i, const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for + for (i = x - 10; i != y + 10; i += N) + baz (i); +} + +template <int N> +void +f8 (J<int> j) +{ + I<int> i; +#pragma omp parallel for + for (i = j.begin (); i != j.end () + N; i += 1) + baz (i); +} + +template <typename T, int N> +void +f9 (const I<T> &x, const I<T> &y) +{ +#pragma omp parallel for + for (I<T> i = x; i != y; i = i - N) + baz (i); +} + +template <typename T, int N> +void +f10 (const I<T> &x, const I<T> &y) +{ + I<T> i; +#pragma omp parallel for + for (i = x; i != y; i = i + N) + baz (i); +} + +template <typename T> +void +f11 (const T &x, const T &y) +{ +#pragma omp parallel + { +#pragma omp for nowait + for (T i = x; i != y; i++) + baz (i); +#pragma omp single + { + T j = y + 3; + baz (j); + } + } +} + +template <typename T> +void +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel for + for (i = x; i != y; --i) + baz (i); +} + +template <int N> +struct K +{ + template <typename T> + static void + f13 (const T &x, const T &y) + { +#pragma omp parallel for + for (T i = x; i != y + N; i += N) + baz (i); + } +}; + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (results[i] != 1) \ + abort (); \ + results[i] = 0; \ + } \ + else if (results[i]) \ + abort () + +int +main () +{ + int a[2000]; + long b[2000]; + for (int i = 0; i < 2000; i++) + { + a[i] = i; + b[i] = i; + } + f1 (&a[10], &a[1990]); + check (i >= 10 && i < 1990); + f2 (&a[0], &a[1999]); + check (i < 1998); + f3<char> (&a[20], &a[1837]); + check (i >= 20 && i < 1837); + f4<int> (&a[0], &a[30]); + check (i > 40 && i <= 2000 - 64); + f5 (&a[0], &a[100]); + check (i > 110 && i <= 2000 - 64); + f6<-10> (&a[10], &a[110]); + check (i > 110 && i <= 2000 - 64); + f7<1> (I<int> (), &a[12], &a[1800]); + check (i >= 2 && i < 1810); + f8<121> (J<int> (&a[14], &a[1803])); + check (i >= 14 && i < 1924); + f9<int, -1> (&a[33], &a[1967]); + check (i >= 33 && i < 1967); + f10<int, -1> (&a[1939], &a[17]); + check (i > 17 && i <= 1939); + f11<I<int> > (&a[16], &a[1981]); + check ((i >= 16 && i < 1981) || i == 1984); + f12<I<int> > (&a[1761], &a[37]); + check (i > 37 && i <= 1761); + K<1>::f13<I<int> > (&a[1], &a[1935]); + check (i >= 1 && i < 1936); + f9<long, 1 - 2> (&b[33], &b[1967]); + check (i >= 33 && i < 1967); + f10<long, -1> (&b[1939], &b[17]); + check (i > 17 && i <= 1939); + f11<I<long> > (&b[16], &b[1981]); + check ((i >= 16 && i < 1981) || i == 1984); + f12<I<long> > (&b[1761], &b[37]); + check (i > 37 && i <= 1761); + K<1>::f13<I<long> > (&b[1], &b[1935]); + check (i >= 1 && i < 1936); +} --- libgomp/testsuite/libgomp.c++/for-22.C.jj 2017-06-28 17:40:33.432216053 +0200 +++ libgomp/testsuite/libgomp.c++/for-22.C 2017-06-28 17:40:24.000000000 +0200 @@ -0,0 +1,314 @@ +// { dg-do run } + +typedef __PTRDIFF_TYPE__ ptrdiff_t; +extern "C" void abort (); + +template <typename T> +class I +{ +public: + typedef ptrdiff_t difference_type; + I (); + ~I (); + I (T *); + I (const I &); + T &operator * (); + T *operator -> (); + T &operator [] (const difference_type &) const; + I &operator = (const I &); + I &operator ++ (); + I operator ++ (int); + I &operator -- (); + I operator -- (int); + I &operator += (const difference_type &); + I &operator -= (const difference_type &); + I operator + (const difference_type &) const; + I operator - (const difference_type &) const; + template <typename S> friend bool operator == (I<S> &, I<S> &); + template <typename S> friend bool operator == (const I<S> &, const I<S> &); + template <typename S> friend bool operator < (I<S> &, I<S> &); + template <typename S> friend bool operator < (const I<S> &, const I<S> &); + template <typename S> friend bool operator <= (I<S> &, I<S> &); + template <typename S> friend bool operator <= (const I<S> &, const I<S> &); + template <typename S> friend bool operator > (I<S> &, I<S> &); + template <typename S> friend bool operator > (const I<S> &, const I<S> &); + template <typename S> friend bool operator >= (I<S> &, I<S> &); + template <typename S> friend bool operator >= (const I<S> &, const I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &); + template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &); +private: + T *p; +}; +template <typename T> I<T>::I () : p (0) {} +template <typename T> I<T>::~I () { p = (T *) 0; } +template <typename T> I<T>::I (T *x) : p (x) {} +template <typename T> I<T>::I (const I &x) : p (x.p) {} +template <typename T> T &I<T>::operator * () { return *p; } +template <typename T> T *I<T>::operator -> () { return p; } +template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; } +template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; } +template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; } +template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); } +template <typename T> I<T> &I<T>::operator -- () { --p; return *this; } +template <typename T> I<T> I<T>::operator -- (int) { return I (p--); } +template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; } +template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; } +template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); } +template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); } +template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; } +template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; } +template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); } +template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); } +template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; } +template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; } +template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; } +template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; } +template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; } +template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; } +template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; } +template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; } +template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; } +template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; } +template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); } + +template <typename T> +class J +{ +public: + J(const I<T> &x, const I<T> &y) : b (x), e (y) {} + const I<T> &begin (); + const I<T> &end (); +private: + I<T> b, e; +}; + +template <typename T> const I<T> &J<T>::begin () { return b; } +template <typename T> const I<T> &J<T>::end () { return e; } + +int results[2000]; + +template <typename T> +void +baz (I<T> &i) +{ + if (*i < 0 || *i >= 2000) + abort (); + results[*i]++; +} + +I<int> +f1 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel shared(i) + { +#pragma omp for lastprivate (i) schedule(runtime) + for (i = x; i != y; i++) + baz (i); +#pragma omp single + i += 3; + } + return I<int> (i); +} + +I<int> +f2 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for lastprivate(i) + for (i = x; i != y - 1; i = 2 - 8 + 7 + i) + baz (i); + return I<int> (i); +} + +template <typename T> +I<int> +f3 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel + #pragma omp for lastprivate (i) + for (i = x; i != y; i = i + 9 - 8) + baz (i); + return i; +} + +template <typename T> +I<int> +f4 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for lastprivate(i) + for (i = x + 2000 - 64; i != y + 10; --i) + baz (i); + return I<int> (i); +} + +template <typename T> +I<int> +f5 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for lastprivate(i) + for (i = x + 2000 - 64; i != y + T (10); i--) + baz (i); + return i; +} + +template <typename T> +I<int> +f6 (const I<int> &x, const I<int> &y) +{ + I<int> i; +#pragma omp parallel for lastprivate (i) + for (i = x + 2000 - 64; i != y + 10; i = i - T (12) + T (11)) + { + I<int> j = i + -10; + baz (j); + } + return I<int> (i); +} + +template <int N> +I<int> +f7 (I<int> i, const I<int> &x, const I<int> &y) +{ +#pragma omp parallel for lastprivate(i) + for (i = x - 10; i != y + 10; i += N) + baz (i); + return I<int> (i); +} + +template <int N> +I<int> +f8 (J<int> j) +{ + I<int> i; +#pragma omp parallel shared \ +(i) +#pragma omp for lastprivate (i) + for (i = j.begin (); i != j.end () + N; i += 1) + baz (i); + return i; +} + +I<int> i9; + +template <long N> +I<int> & +f9 (J<int> j) +{ +#pragma omp parallel for lastprivate(i9) + for (i9 = j.begin (); i9 != j.end () - N; i9 = i9 - N) + baz (i9); + return i9; +} + +template <typename T, int N> +I<T> +f10 (const I<T> &x, const I<T> &y) +{ + I<T> i; +#pragma omp parallel for lastprivate (i) + for (i = x; i != y; i = i + N) + baz (i); + return i; +} + +template <typename T, typename U> +T +f11 (T i, const T &x, const T &y) +{ +#pragma omp parallel + { +#pragma omp for lastprivate (i) + for (i = x + U (0); i != y + U (2 - 2); i = U(3) + U(-2) + i) + baz (i); +#pragma omp single + { + T j = y + 3; + baz (j); + } + } + return i; +} + +template <typename T> +T +f12 (const T &x, const T &y) +{ + T i; +#pragma omp parallel for lastprivate (i) + for (i = x; i != y; --i) + baz (i); + return i; +} + +#define check(expr) \ + for (int i = 0; i < 2000; i++) \ + if (expr) \ + { \ + if (results[i] != 1) \ + abort (); \ + results[i] = 0; \ + } \ + else if (results[i]) \ + abort () + +int +main () +{ + int a[2000]; + long b[2000]; + for (int i = 0; i < 2000; i++) + { + a[i] = i; + b[i] = i; + } + if (*f1 (&a[10], &a[1990]) != 1993) + abort (); + check (i >= 10 && i < 1990); + if (*f2 (&a[0], &a[1999]) != 1998) + abort (); + check (i < 1998); + if (*f3<char> (&a[20], &a[1837]) != 1837) + abort (); + check (i >= 20 && i < 1837); + if (*f4<int> (&a[0], &a[30]) != 40) + abort (); + check (i > 40 && i <= 2000 - 64); + if (*f5<int> (&a[0], &a[100]) != 110) + abort (); + check (i > 110 && i <= 2000 - 64); + if (*f6<int> (&a[10], &a[110]) != 120) + abort (); + check (i > 110 && i <= 2000 - 64); + if (*f7<1> (I<int> (), &a[12], &a[1800]) != 1810) + abort (); + check (i >= 2 && i < 1810); + if (*f8<121> (J<int> (&a[14], &a[1803])) != 1924) + abort (); + check (i >= 14 && i < 1924); + if (*f9<-1> (J<int> (&a[33], &a[1967])) != 1968) + abort (); + check (i >= 33 && i <= 1967); + if (*f10<int, -1> (&a[1939], &a[17]) != 17) + abort (); + check (i > 17 && i <= 1939); + if (*f11<I<int>, int> (I<int> (), &a[16], &a[1981]) != 1981) + abort (); + check ((i >= 16 && i < 1981) || i == 1984); + if (*f12<I<int> > (&a[1761], &a[37]) != 37) + abort (); + check (i > 37 && i <= 1761); + if (*f10<long, -1> (&b[1939], &b[17]) != 17) + abort (); + check (i > 17 && i <= 1939); + if (*f11<I<long>, long> (I<long> (), &b[16], &b[1981]) != 1981) + abort (); + check ((i >= 16 && i < 1981) || i == 1984); + if (*f12<I<long> > (&b[1761], &b[37]) != 37) + abort (); + check (i > 37 && i <= 1761); +} --- libgomp/testsuite/libgomp.c++/for-23.C.jj 2017-06-28 18:57:08.017276495 +0200 +++ libgomp/testsuite/libgomp.c++/for-23.C 2017-06-28 18:57:02.836337466 +0200 @@ -0,0 +1 @@ +#include "../libgomp.c/for-13.c" Jakub