Index: targhooks.c =================================================================== --- targhooks.c (revision 151228) +++ targhooks.c (working copy) @@ -771,6 +771,22 @@ default_builtin_vector_alignment_reachab return true; } +/* By default, assume that a target supports any factor of misalignment + memory access if it supports movmisalign patten. */ +bool +default_builtin_support_vector_misalignment (enum machine_mode mode, + const_tree type + ATTRIBUTE_UNUSED, + int misalignment + ATTRIBUTE_UNUSED, + bool is_packed + ATTRIBUTE_UNUSED) +{ + if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing) + return true; + return false; +} + bool default_hard_regno_scratch_ok (unsigned int regno ATTRIBUTE_UNUSED) { Index: targhooks.h =================================================================== --- targhooks.h (revision 151228) +++ targhooks.h (working copy) @@ -77,6 +77,10 @@ extern tree default_builtin_vectorized_c extern tree default_builtin_reciprocal (unsigned int, bool, bool); extern bool default_builtin_vector_alignment_reachable (const_tree, bool); +extern bool +default_builtin_support_vector_misalignment (enum machine_mode mode, + const_tree, + int, bool); /* These are here, and not in hooks.[ch], because not all users of hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */ Index: target.h =================================================================== --- target.h (revision 151228) +++ target.h (working copy) @@ -481,6 +481,10 @@ struct gcc_target /* Target builtin that implements vector permute. */ tree (* builtin_vec_perm) (tree, tree*); + /* Return true if the target supports misaligned store/load of a + specific factor denoted in the third parameter. */ + bool (* builtin_support_vector_misalignment) (enum machine_mode, + const_tree, int, bool); } vectorize; /* The initial value of target_flags. */ Index: tree-vect-data-refs.c =================================================================== --- tree-vect-data-refs.c (revision 151228) +++ tree-vect-data-refs.c (working copy) @@ -3455,6 +3455,9 @@ vect_supportable_dr_alignment (struct da if (DR_IS_READ (dr)) { + bool is_packed = false; + tree type = (TREE_TYPE (DR_REF (dr))); + if (optab_handler (vec_realign_load_optab, mode)->insn_code != CODE_FOR_nothing && (!targetm.vectorize.builtin_mask_for_load @@ -3468,18 +3471,39 @@ vect_supportable_dr_alignment (struct da else return dr_explicit_realign_optimized; } - - if (optab_handler (movmisalign_optab, mode)->insn_code != - CODE_FOR_nothing) + if (!known_alignment_for_access_p (dr)) + { + tree ba = DR_BASE_OBJECT (dr); + + if (ba) + is_packed = contains_packed_reference (ba); + } + + if (targetm.vectorize. + builtin_support_vector_misalignment (mode, type, + DR_MISALIGNMENT (dr), is_packed)) /* Can't software pipeline the loads, but can at least do them. */ return dr_unaligned_supported; } - else - { - if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing) - return dr_unaligned_supported; - } + else + { + bool is_packed = false; + tree type = (TREE_TYPE (DR_REF (dr))); + if (!known_alignment_for_access_p (dr)) + { + tree ba = DR_BASE_OBJECT (dr); + + if (ba) + is_packed = contains_packed_reference (ba); + } + + if (targetm.vectorize. + builtin_support_vector_misalignment (mode, type, + DR_MISALIGNMENT (dr), is_packed)) + return dr_unaligned_supported; + } + /* Unsupported. */ return dr_unaligned_unsupported; } Index: target-def.h =================================================================== --- target-def.h (revision 151228) +++ target-def.h (working copy) @@ -388,6 +388,9 @@ #define TARGET_VECTOR_ALIGNMENT_REACHABLE \ default_builtin_vector_alignment_reachable #define TARGET_VECTORIZE_BUILTIN_VEC_PERM 0 +#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ + default_builtin_support_vector_misalignment + #define TARGET_VECTORIZE \ { \ @@ -398,7 +401,8 @@ TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD, \ TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST, \ TARGET_VECTOR_ALIGNMENT_REACHABLE, \ - TARGET_VECTORIZE_BUILTIN_VEC_PERM \ + TARGET_VECTORIZE_BUILTIN_VEC_PERM, \ + TARGET_SUPPORT_VECTOR_MISALIGNMENT \ } #define TARGET_DEFAULT_TARGET_FLAGS 0 Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 151228) +++ config/rs6000/rs6000.c (working copy) @@ -919,6 +919,10 @@ static tree rs6000_builtin_mul_widen_eve static tree rs6000_builtin_mul_widen_odd (tree); static tree rs6000_builtin_conversion (unsigned int, tree); static tree rs6000_builtin_vec_perm (tree, tree *); +static bool rs6000_builtin_support_vector_misalignment (enum + machine_mode, + const_tree, + int, bool); static void def_builtin (int, const char *, tree, int); static bool rs6000_vector_alignment_reachable (const_tree, bool); @@ -1299,7 +1303,9 @@ static const struct attribute_spec rs600 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm - +#undef TARGET_SUPPORT_VECTOR_MISALIGNMENT +#define TARGET_SUPPORT_VECTOR_MISALIGNMENT \ + rs6000_builtin_support_vector_misalignment #undef TARGET_VECTOR_ALIGNMENT_REACHABLE #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable @@ -2891,6 +2897,36 @@ rs6000_vector_alignment_reachable (const } } +/* Return true if the vector misalignment factor is supported by the + target. */ +bool +rs6000_builtin_support_vector_misalignment (enum machine_mode mode, + const_tree type + ATTRIBUTE_UNUSED, + int misalignment, + bool is_packed) +{ + if (TARGET_VSX) + { + /* Return if movmisalign pattern is not supported for this mode. */ + if (movmisalign_optab->handlers[mode].insn_code == CODE_FOR_nothing) + return false; + + if (misalignment == -1) + { + /* misalignment factor is unknown at compile time but we know + it's word aligned. */ + if (rs6000_vector_alignment_reachable (type, is_packed)) + return true; + return false; + } + /* VSX supports word-aligned vector. */ + if (misalignment % 4 == 0) + return true; + } + return false; +} + /* Implement targetm.vectorize.builtin_vec_perm. */ tree rs6000_builtin_vec_perm (tree type, tree *mask_element_type)