From f4e92d62dccb96ade753f3a8f49be1b5f61c31f1 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 26 Mar 2024 09:11:00 +0100 Subject: [PATCH] tree-optimization/114471 - ICE with mismatching vector types The following fixes too lax verification of vector type compatibility in vectorizable_operation. When we only have a single vector size then comparing the number of elements is enough but with SLP we mix those and thus for operations like BIT_AND_EXPR we need to verify compatible element types as well. Allow sign changes for ABSU_EXPR though. PR tree-optimization/114471 * tree-vect-stmts.cc (vectorizable_operation): Verify operand types are compatible with the result type. * gcc.dg/vect/pr114471.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr114471.c | 13 +++++++++++++ gcc/tree-vect-stmts.cc | 11 ++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr114471.c diff --git a/gcc/testsuite/gcc.dg/vect/pr114471.c b/gcc/testsuite/gcc.dg/vect/pr114471.c new file mode 100644 index 000000000000..218c953e45e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr114471.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +float f1, f0, fa[2]; +short sa[2]; +void quantize(short s0) +{ + _Bool ta[2] = {(fa[0] < 0), (fa[1] < 0)}; + _Bool t = ((s0 > 0) & ta[0]); + short x1 = s0 + t; + _Bool t1 = ((x1 > 0) & ta[1]); + sa[0] = x1; + sa[1] = s0 + t1; +} diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 5a4eb136c6d9..f8d8636b139a 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -6667,7 +6667,8 @@ vectorizable_operation (vec_info *vinfo, nunits_out = TYPE_VECTOR_SUBPARTS (vectype_out); nunits_in = TYPE_VECTOR_SUBPARTS (vectype); - if (maybe_ne (nunits_out, nunits_in)) + if (maybe_ne (nunits_out, nunits_in) + || !tree_nop_conversion_p (TREE_TYPE (vectype_out), TREE_TYPE (vectype))) return false; tree vectype2 = NULL_TREE, vectype3 = NULL_TREE; @@ -6685,7 +6686,9 @@ vectorizable_operation (vec_info *vinfo, is_invariant &= (dt[1] == vect_external_def || dt[1] == vect_constant_def); if (vectype2 - && maybe_ne (nunits_out, TYPE_VECTOR_SUBPARTS (vectype2))) + && (maybe_ne (nunits_out, TYPE_VECTOR_SUBPARTS (vectype2)) + || !tree_nop_conversion_p (TREE_TYPE (vectype_out), + TREE_TYPE (vectype2)))) return false; } if (op_type == ternary_op) @@ -6701,7 +6704,9 @@ vectorizable_operation (vec_info *vinfo, is_invariant &= (dt[2] == vect_external_def || dt[2] == vect_constant_def); if (vectype3 - && maybe_ne (nunits_out, TYPE_VECTOR_SUBPARTS (vectype3))) + && (maybe_ne (nunits_out, TYPE_VECTOR_SUBPARTS (vectype3)) + || !tree_nop_conversion_p (TREE_TYPE (vectype_out), + TREE_TYPE (vectype3)))) return false; }