diff options
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 057a874..5776417 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -819,6 +819,7 @@ _loop_vec_info::_loop_vec_info (struct loop *loop_in, vec_info_shared *shared) max_vectorization_factor (0), mask_skip_niters (NULL_TREE), mask_compare_type (NULL_TREE), + simd_if_cond (NULL_TREE), unaligned_dr (NULL), peeling_for_alignment (0), ptr_mask (0), @@ -862,6 +863,26 @@ _loop_vec_info::_loop_vec_info (struct loop *loop_in, vec_info_shared *shared) gimple *stmt = gsi_stmt (si); gimple_set_uid (stmt, 0); add_stmt (stmt); + /* If .GOMP_SIMD_LANE call for the current loop has 2 arguments, the + second argument is the #pragma omp simd if (x) condition, when 0, + loop shouldn't be vectorized, when non-zero constant, it should + be vectorized normally, otherwise versioned with vectorized loop + done if the condition is non-zero at runtime. */ + if (loop_in->simduid + && is_gimple_call (stmt) + && gimple_call_internal_p (stmt) + && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE + && gimple_call_num_args (stmt) >= 2 + && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME + && (loop_in->simduid + == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))) + { + tree arg = gimple_call_arg (stmt, 1); + if (integer_zerop (arg) || TREE_CODE (arg) == SSA_NAME) + simd_if_cond = arg; + else + gcc_assert (integer_nonzerop (arg)); + } } } } @@ -1769,6 +1790,11 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo, bool &fatal, unsigned *n_stmts) /* The first group of checks is independent of the vector size. */ fatal = true; + if (LOOP_VINFO_SIMD_IF_COND (loop_vinfo) + && integer_zerop (LOOP_VINFO_SIMD_IF_COND (loop_vinfo))) + return opt_result::failure_at (vect_location, + "not vectorized: simd if(0)\n"); + /* Find all data references in the loop (which correspond to vdefs/vuses) and analyze their evolution in the loop. */ |