diff options
Diffstat (limited to 'gcc/tree-vect-stmts.cc')
| -rw-r--r-- | gcc/tree-vect-stmts.cc | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index dc155dc..56ff1c8 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -9920,36 +9920,35 @@ vectorizable_load (vec_info *vinfo, bool hoist_p = (LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) && !nested_in_vect_loop); - /* It is unsafe to hoist a conditional load over the conditions that make - it valid. When early break this means that any invariant load can't be - hoisted unless it's in the loop header or if we know something else has - verified the load is valid to do. Alignment peeling would do this - since getting through the prologue means the load was done at least - once and so the vector main body is free to hoist it. However today - GCC will hoist the load above the PFA loop. As such that makes it - still invalid and so we can't allow it today. */ - auto stmt_bb - = gimple_bb (STMT_VINFO_STMT ( - vect_orig_stmt (SLP_TREE_SCALAR_STMTS (slp_node)[0]))); - if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo) - && !DR_SCALAR_KNOWN_BOUNDS (dr_info) - && stmt_bb != loop->header) - { - if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) - && dump_enabled_p ()) - dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + bool uniform_p = true; + for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node)) + { + /* It is unsafe to hoist a conditional load over the conditions that + make it valid. When early break this means that any invariant load + can't be hoisted unless it's in the loop header or if we know + something else has verified the load is valid to do. Alignment + peeling would do this since getting through the prologue means the + load was done at least once and so the vector main body is free to + hoist it. However today GCC will hoist the load above the PFA + loop. As such that makes it still invalid and so we can't allow it + today. */ + if (LOOP_VINFO_EARLY_BREAKS (loop_vinfo) + && !DR_SCALAR_KNOWN_BOUNDS (STMT_VINFO_DR_INFO (sinfo)) + && gimple_bb (STMT_VINFO_STMT (vect_orig_stmt (sinfo))) + != loop->header) + { + if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) + && dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not hoisting invariant load due to early break" "constraints\n"); - else if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, + else if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, "not hoisting invariant load due to early break" "constraints\n"); - hoist_p = false; - } + hoist_p = false; + } - bool uniform_p = true; - for (stmt_vec_info sinfo : SLP_TREE_SCALAR_STMTS (slp_node)) - { hoist_p = hoist_p && hoist_defs_of_uses (sinfo->stmt, loop, false); if (sinfo != SLP_TREE_SCALAR_STMTS (slp_node)[0]) uniform_p = false; @@ -11393,10 +11392,18 @@ vectorizable_load (vec_info *vinfo, { tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT); gcall *call; + + /* Need conversion if the vectype is punned by VnQI. */ + els_vectype = vectype; + if (vmode != new_vmode) + els_vectype + = build_vector_type_for_mode (unsigned_intQI_type_node, + new_vmode); + vec_els = vect_get_mask_load_else (maskload_elsval, + els_vectype); + if (partial_ifn == IFN_MASK_LEN_LOAD) { - vec_els = vect_get_mask_load_else (maskload_elsval, - vectype); if (type_mode_padding_p && maskload_elsval != MASK_LOAD_ELSE_ZERO) need_zeroing = true; @@ -11406,9 +11413,10 @@ vectorizable_load (vec_info *vinfo, final_len, bias); } else - call = gimple_build_call_internal (IFN_LEN_LOAD, 4, + call = gimple_build_call_internal (IFN_LEN_LOAD, 5, dataref_ptr, ptr, - final_len, bias); + vec_els, final_len, + bias); gimple_call_set_nothrow (call, true); new_stmt = call; data_ref = NULL_TREE; |
