https://gcc.gnu.org/g:d7e04528080c1ae202c7021677dd60cef03df436
commit r16-9272-gd7e04528080c1ae202c7021677dd60cef03df436 Author: Richard Biener <[email protected]> Date: Fri Jun 26 10:55:29 2026 +0200 middle-end/125875 - incomplete guards on VEC_PERM_EXPR folding This fixes up match.pd patterns using can_vec_perm_const_p on existing permutations to indicate whether we are before or after vector lowering. For this to be correct we have to use the new vec_perm_indices CTOR taking the actual permuted inputs so can_vec_perm_const_p can also handle the vec_shl/vec_shr expansion path. PR middle-end/125875 * match.pd: When checking for !can_vec_perm_const_p also allow variable permutes and use the vec_perm_indices CTOR with the original tree operands. * gcc.dg/torture/pr125875.c: New testcase. (cherry picked from commit f3475825fe0c609482ab30714f2d616f9c7b8fd7) Diff: --- gcc/match.pd | 52 +++++++++++++-------------------- gcc/testsuite/gcc.dg/torture/pr125875.c | 29 ++++++++++++++++++ 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index 12054c6bcc53..87a6c2377962 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -11743,19 +11743,15 @@ and, machine_mode result_mode = TYPE_MODE (type); machine_mode op_mode = TYPE_MODE (TREE_TYPE (@2)); int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); - vec_perm_builder builder0; - vec_perm_builder builder1; - vec_perm_builder builder2 (nelts, nelts, 1); + vec_perm_indices sel0, sel1; } - (if (tree_to_vec_perm_builder (&builder0, @4) - && tree_to_vec_perm_builder (&builder1, @5) + (if (tree_to_vec_perm_indices (&sel0, @2, @3, @4) + && tree_to_vec_perm_indices (&sel1, @0, @0, @5) && TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0))) == TYPE_SIZE (TREE_TYPE (TREE_TYPE (@1)))) (with { - vec_perm_indices sel0 (builder0, 2, nelts); - vec_perm_indices sel1 (builder1, 2, nelts); - + vec_perm_builder builder2 (nelts, nelts, 1); for (int i = 0; i < nelts; i++) builder2.quick_push (sel0[sel1[i].to_constant ()]); @@ -11769,9 +11765,9 @@ and, number of VEC_PERM_EXPRs that can't be handled. */ if (can_vec_perm_const_p (result_mode, op_mode, sel2, false) || (single_use (@0) - ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false) - || !can_vec_perm_const_p (result_mode, op_mode, sel1, false)) - : !can_vec_perm_const_p (result_mode, op_mode, sel1, false))) + ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true) + || !can_vec_perm_const_p (result_mode, op_mode, sel1, true)) + : !can_vec_perm_const_p (result_mode, op_mode, sel1, true))) op0 = vec_perm_indices_to_tree (TREE_TYPE (@5), sel2); } (if (op0) @@ -11793,18 +11789,15 @@ and, machine_mode result_mode = TYPE_MODE (type); machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1)); int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); - vec_perm_builder builder0; - vec_perm_builder builder1; - vec_perm_builder builder2 (nelts, nelts, 2); + vec_perm_indices sel0, sel1; } - (if (tree_to_vec_perm_builder (&builder0, @3) - && tree_to_vec_perm_builder (&builder1, @4)) + (if (tree_to_vec_perm_indices (&sel0, @1, @2, @3) + && tree_to_vec_perm_indices (&sel1, @5, @0, @4)) (with { - vec_perm_indices sel0 (builder0, 2, nelts); - vec_perm_indices sel1 (builder1, 2, nelts); bool use_1 = false, use_2 = false; + vec_perm_builder builder2 (nelts, nelts, 2); for (int i = 0; i < nelts; i++) { if (known_lt ((poly_uint64)sel1[i], sel1.nelts_per_input ())) @@ -11836,9 +11829,9 @@ and, number of VEC_PERM_EXPRs that can't be handled. */ if (can_vec_perm_const_p (result_mode, op_mode, sel2, false) || (single_use (@0) - ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false) - || !can_vec_perm_const_p (result_mode, op_mode, sel1, false)) - : !can_vec_perm_const_p (result_mode, op_mode, sel1, false))) + ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true) + || !can_vec_perm_const_p (result_mode, op_mode, sel1, true)) + : !can_vec_perm_const_p (result_mode, op_mode, sel1, true))) op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2); } (if (op0) @@ -11858,18 +11851,15 @@ and, machine_mode result_mode = TYPE_MODE (type); machine_mode op_mode = TYPE_MODE (TREE_TYPE (@1)); int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant (); - vec_perm_builder builder0; - vec_perm_builder builder1; - vec_perm_builder builder2 (nelts, nelts, 2); + vec_perm_indices sel0, sel1; } - (if (tree_to_vec_perm_builder (&builder0, @3) - && tree_to_vec_perm_builder (&builder1, @4)) + (if (tree_to_vec_perm_indices (&sel0, @1, @2, @3) + && tree_to_vec_perm_indices (&sel1, @0, @5, @4)) (with { - vec_perm_indices sel0 (builder0, 2, nelts); - vec_perm_indices sel1 (builder1, 2, nelts); bool use_1 = false, use_2 = false; + vec_perm_builder builder2 (nelts, nelts, 2); for (int i = 0; i < nelts; i++) { if (known_ge ((poly_uint64)sel1[i], sel1.nelts_per_input ())) @@ -11900,9 +11890,9 @@ and, number of VEC_PERM_EXPRs that can't be handled. */ if (can_vec_perm_const_p (result_mode, op_mode, sel2, false) || (single_use (@0) - ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, false) - || !can_vec_perm_const_p (result_mode, op_mode, sel1, false)) - : !can_vec_perm_const_p (result_mode, op_mode, sel1, false))) + ? (!can_vec_perm_const_p (result_mode, op_mode, sel0, true) + || !can_vec_perm_const_p (result_mode, op_mode, sel1, true)) + : !can_vec_perm_const_p (result_mode, op_mode, sel1, true))) op0 = vec_perm_indices_to_tree (TREE_TYPE (@4), sel2); } (if (op0) diff --git a/gcc/testsuite/gcc.dg/torture/pr125875.c b/gcc/testsuite/gcc.dg/torture/pr125875.c new file mode 100644 index 000000000000..0cccb190c734 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125875.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ + +#include <stdint.h> +typedef int16_t v4i16 __attribute__((vector_size(8))); +v4i16 g7, g19; +int64_t g16; +_Bool f16_a0_c3, f16_a0_ob6; +void f16_a0() +{ + int32_t ov10; + uint64_t __ov_tmp_g16 = __builtin_sub_overflow(0, 0, &__ov_tmp_g16); + g16 = __ov_tmp_g16; +lbl_b1: + __builtin_mul_overflow(g16, g16, &ov10); + switch (ov10) + case 33: + goto lbl_sw_def57; +lbl_sw_def15: + if (f16_a0_c3) goto lbl_b1; + g7 = __builtin_shufflevector(g7, g7, 4, 3, 4, 5); + f16_a0_ob6 = f16_a0; + g19 = g19 <= g19; +lbl_bf43: + g19 = ~g19; + g7 = __builtin_shufflevector(g7, g19, 6, 7, 0, 1); +lbl_sw_def57: + if (f16_a0_ob6) goto lbl_sw_def15; + goto lbl_bf43; +}
