In the tree codes and optabs, the "hi" in a vector hi/lo pair means "most significant" and the "lo" means "least significant", with sigificance following GCC's normal endian expectations. Thus on big-endian targets, the hi part handles the first half of the elements in memory order and the lo part handles the second half.
For tree codes, supportable_widening_operation first chooses hi/lo pairs based on little-endian order and then uses: if (BYTES_BIG_ENDIAN && c1 != VEC_WIDEN_MULT_EVEN_EXPR) std::swap (c1, c2); to adjust. However, the handling for internal functions was missing an equivalent fixup. This led to several execution failures in vect.exp on aarch64_be-elf. If the hi/lo code fails, the internal function handling goes on to try even/odd. But I couldn't see anything obvious that would put the even/ odd results back into the right order later, so there might be a latent bug there too. Tested on aarch64-linux-gnu & aarch64_be-elf. OK to install? Richard gcc/ PR tree-optimization/118891 * tree-vect-stmts.cc (supportable_widening_operation): Swap the hi and lo internal functions on big-endian targets. --- gcc/tree-vect-stmts.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 95406b4e3a3..5767a351fdf 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -14410,6 +14410,8 @@ supportable_widening_operation (vec_info *vinfo, internal_fn lo, hi, even, odd; lookup_hilo_internal_fn (ifn, &lo, &hi); + if (BYTES_BIG_ENDIAN) + std::swap (lo, hi); *code1 = as_combined_fn (lo); *code2 = as_combined_fn (hi); optab1 = direct_internal_fn_optab (lo, {vectype, vectype}); -- 2.43.0