From 055c6cc038ef6bba311eee2abdafaadb532ddd5b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 7 Oct 2025 15:38:57 +0200 Subject: [PATCH] Add boolean pattern for bitwise ops As we consider bitwise operations possible mask operations we have to consider the case of only one operand arriving as mask. The following compensates for this by creating mask from the other operand and insert possibly required mask conversions. PR tree-optimization/110223 PR tree-optimization/122128 * tree-vect-patterns.cc (vect_recog_bool_pattern): Add compensation for mixed mask/data bitwise operations. * gcc.dg/vect/vect-bool-2.c: New testcase. * gcc.dg/vect/vect-bool-cmp-3.c: Likewise. * gcc.dg/vect/vect-bool-cmp-4.c: Likewise. --- gcc/testsuite/gcc.dg/vect/vect-bool-2.c | 17 ++++++ gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c | 14 +++++ gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c | 14 +++++ gcc/tree-vect-patterns.cc | 62 +++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-2.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-2.c b/gcc/testsuite/gcc.dg/vect/vect-bool-2.c new file mode 100644 index 00000000000..88db018a4f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bool-2.c @@ -0,0 +1,17 @@ +/* PR122128 */ +/* { dg-do compile } */ + +_Bool a[1024]; +signed char b[1024]; + +void foo () +{ + for (int i = 0; i < 1024; ++i) + { + bool x = a[i]; + bool y = b[i] < 17; + a[i] = x & y; + } +} + +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c new file mode 100644 index 00000000000..4d96af65e92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-3.c @@ -0,0 +1,14 @@ +/* PR110223 */ +/* { dg-do compile } */ + +_Bool k[1024]; +_Bool res[1024]; + +int main () +{ + int i; + for (i = 0; i < 1024; i++) + res[i] = k[i] != (i == 0); +} + +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" { target vect_unpack } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c new file mode 100644 index 00000000000..162f22835da --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-bool-cmp-4.c @@ -0,0 +1,14 @@ +/* PR110223 */ +/* { dg-do compile } */ + +_Bool k[1024]; +_Bool res[1024]; + +int main () +{ + char i; + for (i = 0; i < 64; i++) + res[i] = k[i] != (i == 0); +} + +/* { dg-final { scan-tree-dump "optimized: loop vectorized" "vect" } } */ diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 8b4f9840181..5581f44a6a8 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -5754,6 +5754,68 @@ vect_recog_bool_pattern (vec_info *vinfo, *type_out = vectype; vect_pattern_detected ("vect_recog_bool_pattern", last_stmt); + return pattern_stmt; + } + else if (rhs_code == BIT_XOR_EXPR + || rhs_code == BIT_AND_EXPR + || rhs_code == BIT_IOR_EXPR) + { + tree lhs_type = integer_type_for_mask (lhs, vinfo); + if (!lhs_type) + return NULL; + vectype = get_mask_type_for_scalar_type (vinfo, lhs_type); + if (!vectype) + return NULL; + tree rhs2 = gimple_assign_rhs2 (last_stmt); + tree rhs1_type = integer_type_for_mask (var, vinfo); + tree rhs2_type = integer_type_for_mask (rhs2, vinfo); + if (rhs1_type && rhs2_type) + return NULL; + /* When one input is a mask and the other is not create a pattern + stmt sequence that creates a mask for the non-mask input and + convert it to one suitable for the output mask used. */ + if (rhs1_type && !rhs2_type) + { + tree rhs1_vectype = get_mask_type_for_scalar_type (vinfo, rhs1_type); + if (!rhs1_vectype) + return NULL; + tree rhs2_vectype = get_vectype_for_scalar_type (vinfo, + TREE_TYPE (rhs2)); + if (!rhs2_vectype) + return NULL; + tree new_vectype = truth_type_for (rhs2_vectype); + tree tem = vect_recog_temp_ssa_var (TREE_TYPE (new_vectype), NULL); + pattern_stmt = gimple_build_assign (tem, NE_EXPR, rhs2, + build_zero_cst + (TREE_TYPE (rhs2))); + append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, + new_vectype, TREE_TYPE (new_vectype)); + rhs2 = vect_convert_mask_for_vectype (tem, rhs1_vectype, + stmt_vinfo, vinfo); + } + else if (!rhs1_type && rhs2_type) + { + tree rhs2_vectype = get_mask_type_for_scalar_type (vinfo, rhs2_type); + if (!rhs2_vectype) + return NULL; + tree rhs1_vectype = get_vectype_for_scalar_type (vinfo, + TREE_TYPE (var)); + if (!rhs1_vectype) + return NULL; + tree new_vectype = truth_type_for (rhs1_vectype); + tree tem = vect_recog_temp_ssa_var (TREE_TYPE (new_vectype), NULL); + pattern_stmt = gimple_build_assign (tem, NE_EXPR, var, + build_zero_cst + (TREE_TYPE (var))); + append_pattern_def_seq (vinfo, stmt_vinfo, pattern_stmt, + new_vectype, TREE_TYPE (new_vectype)); + var = vect_convert_mask_for_vectype (tem, rhs2_vectype, + stmt_vinfo, vinfo); + } + lhs = vect_recog_temp_ssa_var (TREE_TYPE (lhs), NULL); + pattern_stmt = gimple_build_assign (lhs, rhs_code, var, rhs2); + vect_pattern_detected ("vect_recog_bool_pattern", last_stmt); + *type_out = vectype; return pattern_stmt; } else if (rhs_code == SSA_NAME -- 2.47.3