> +static tree > +c_check_cilk_loop_incr (location_t loc, tree decl, tree incr) > +{ > + if (EXPR_HAS_LOCATION (incr)) > + loc = EXPR_LOCATION (incr); > + > + if (!incr) > + { > + error_at (loc, "missing increment"); > + return error_mark_node; > + }
Either these tests are swapped, or the second one isn't really needed. > + switch (TREE_CODE (incr)) > + { > + case POSTINCREMENT_EXPR: > + case PREINCREMENT_EXPR: > + case POSTDECREMENT_EXPR: > + case PREDECREMENT_EXPR: > + if (TREE_OPERAND (incr, 0) != decl) > + break; > + > + // Bah... canonicalize into whatever OMP_FOR_INCR needs. > + if (POINTER_TYPE_P (TREE_TYPE (decl)) > + && TREE_OPERAND (incr, 1)) > + { > + tree t = fold_convert_loc (loc, > + sizetype, TREE_OPERAND (incr, 1)); > + > + if (TREE_CODE (incr) == POSTDECREMENT_EXPR > + || TREE_CODE (incr) == PREDECREMENT_EXPR) > + t = fold_build1_loc (loc, NEGATE_EXPR, sizetype, t); > + t = fold_build_pointer_plus (decl, t); > + incr = build2 (MODIFY_EXPR, void_type_node, decl, t); > + } > + return incr; Handling pointer types and pointer_plus_expr here (p++) ... > + case MODIFY_EXPR: > + { > + tree rhs; > + > + if (TREE_OPERAND (incr, 0) != decl) > + break; > + > + rhs = TREE_OPERAND (incr, 1); > + if (TREE_CODE (rhs) == PLUS_EXPR > + && (TREE_OPERAND (rhs, 0) == decl > + || TREE_OPERAND (rhs, 1) == decl) > + && INTEGRAL_TYPE_P (TREE_TYPE (rhs))) > + return incr; > + else if (TREE_CODE (rhs) == MINUS_EXPR > + && TREE_OPERAND (rhs, 0) == decl > + && INTEGRAL_TYPE_P (TREE_TYPE (rhs))) > + return incr; > + // Otherwise fail because only PLUS_EXPR and MINUS_EXPR are > + // allowed. > + break; ... but not here (p += 1)? > +c_validate_cilk_plus_loop (tree *tp, int *walk_subtrees, void *data) > +{ > + if (!tp || !*tp) > + return NULL_TREE; > + > + bool *valid = (bool *) data; > + > + switch (TREE_CODE (*tp)) > + { > + case CALL_EXPR: > + { > + tree fndecl = CALL_EXPR_FN (*tp); > + > + if (TREE_CODE (fndecl) == ADDR_EXPR) > + fndecl = TREE_OPERAND (fndecl, 0); > + if (TREE_CODE (fndecl) == FUNCTION_DECL) > + { > + if (setjmp_call_p (fndecl)) > + { > + error_at (EXPR_LOCATION (*tp), > + "calls to setjmp are not allowed within loops " > + "annotated with #pragma simd"); > + *valid = false; > + *walk_subtrees = 0; > + } > + } > + break; Why bother checking for setjmp? While I agree it makes little sense, there are plenty of other standard functions which also make no sense to use from within #pragma simd. What's likely to go wrong with a call to setjmp, as opposed to getcontext, pthread_create, or even printf? > + if (DECL_REGISTER (decl)) > + { > + error_at (loc, "induction variable cannot be declared register"); > + return false; > + } Why? All of the actual gimple changes look good. You could commit those now if you like to reduce the size of the next patch. r~