https://gcc.gnu.org/g:dd38fa87afc8a9bb17af0121282dade697111f4d
commit r16-7039-gdd38fa87afc8a9bb17af0121282dade697111f4d Author: Richard Biener <[email protected]> Date: Mon Jan 26 08:57:45 2026 +0100 tree-optimization/123755 - fix LEN-masking of trapping calls There's multiple issues with properly handling len-masking of calls that might trap. Similar to get_conditional_internal_fn, get_len_internal_fn expects a COND_* argument only. When the original call is not already masked computation and code-gen fails to add mask and else arguments. This fixes gcc.target/riscv/rvv/autovec/reduc/reduc_call-5.c PR tree-optimization/123755 * tree-vect-stmts.cc (vectorizable_call): Fixup LEN masking of unconditional but possibly trapping calls. Diff: --- gcc/tree-vect-stmts.cc | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index ee98e72d1e57..15697c024bd8 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -3632,8 +3632,9 @@ vectorizable_call (vec_info *vinfo, if (could_trap && cost_vec && loop_vinfo) { /* If the operation can trap it must be conditional, otherwise fail. */ - internal_fn cond_fn = get_conditional_internal_fn (ifn); - internal_fn cond_len_fn = get_len_internal_fn (ifn); + internal_fn cond_fn = (internal_fn_mask_index (ifn) != -1 + ? ifn : get_conditional_internal_fn (ifn)); + internal_fn cond_len_fn = get_len_internal_fn (cond_fn); if (LOOP_VINFO_CAN_USE_PARTIAL_VECTORS_P (loop_vinfo)) { /* We assume that BB SLP fills all lanes, so no inactive lanes can @@ -3698,7 +3699,7 @@ vectorizable_call (vec_info *vinfo, int reduc_idx = SLP_TREE_REDUC_IDX (slp_node); internal_fn cond_fn = (internal_fn_mask_index (ifn) != -1 ? ifn : get_conditional_internal_fn (ifn)); - internal_fn cond_len_fn = get_len_internal_fn (ifn); + internal_fn cond_len_fn = get_len_internal_fn (cond_fn); int len_opno = internal_fn_len_index (cond_len_fn); vec_loop_masks *masks = (loop_vinfo ? &LOOP_VINFO_MASKS (loop_vinfo) : NULL); vec_loop_lens *lens = (loop_vinfo ? &LOOP_VINFO_LENS (loop_vinfo) : NULL); @@ -3774,6 +3775,10 @@ vectorizable_call (vec_info *vinfo, ifn = cond_len_fn; /* COND_* -> COND_LEN_* takes 2 extra arguments:LEN,BIAS. */ vect_nargs += 2; + /* But unless there's a mask argument already we need that + as well, and an else value. */ + if (mask_opno == -1) + vect_nargs += 2; } else if (reduc_idx >= 0) gcc_unreachable (); @@ -3822,13 +3827,24 @@ vectorizable_call (vec_info *vinfo, { int varg = 0; /* Add the mask if necessary. */ - if (masked_loop_p && mask_opno == -1 + if ((masked_loop_p || len_loop_p) && mask_opno == -1 && (reduc_idx >= 0 || could_trap)) { gcc_assert (internal_fn_mask_index (ifn) == varg); - unsigned int vec_num = vec_oprnds0.length (); - vargs[varg++] = vect_get_loop_mask (loop_vinfo, gsi, masks, - vec_num, vectype_out, i); + if (masked_loop_p) + { + unsigned int vec_num = vec_oprnds0.length (); + vargs[varg++] = vect_get_loop_mask (loop_vinfo, gsi, + masks, vec_num, + vectype_out, i); + } + else + { + tree mask_vectype = truth_type_for (vectype_out); + vargs[varg++] = vect_build_all_ones_mask (loop_vinfo, + stmt_info, + mask_vectype); + } } size_t k; for (k = 0; k < nargs; k++) @@ -3837,7 +3853,7 @@ vectorizable_call (vec_info *vinfo, vargs[varg++] = vec_oprndsk[i]; } /* Add the else value if necessary. */ - if (masked_loop_p && mask_opno == -1 + if ((masked_loop_p || len_loop_p) && mask_opno == -1 && (reduc_idx >= 0 || could_trap)) { gcc_assert (internal_fn_else_index (ifn) == varg); @@ -3846,7 +3862,7 @@ vectorizable_call (vec_info *vinfo, else { auto else_value = targetm.preferred_else_value - (cond_fn, vectype_out, varg - 1, &vargs[1]); + (ifn, vectype_out, varg - 1, &vargs[1]); vargs[varg++] = else_value; } }
