Generalize existing scalar gimple_fold rules to apply the same bitwise comparison simplifications to vector types. Previously, an expression like
(x < y) && (x > y) would fold to `false` if x and y are scalars, but equivalent vector comparisons were left untouched. This patch enables folding of patterns of the form (cmp x y) bit_and (cmp x y) (cmp x y) bit_ior (cmp x y) for vector operands as well, ensuring consistent optimization across all data types. PR tree-optimization/119196 gcc/ChangeLog: * match.pd: Allow scalar optimizations with bitwise AND/OR to apply to vectors. gcc/testsuite/ChangeLog: * gcc.target/aarch64/vector-compare-5.c: Add new test for vector compare simplification. Signed-off-by: Icen Zeyada <icen.zeya...@arm.com> --- gcc/match.pd | 19 +++++++-- .../gcc.target/aarch64/vector-compare-5.c | 41 +++++++++++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/vector-compare-5.c diff --git a/gcc/match.pd b/gcc/match.pd index ab496d923cc0..a8a2e01e5e64 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3620,7 +3620,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_and:c (code1:c@3 @0 @1) (code2:c@4 (convert?@c0 @0) @2)) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) - || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) && bitwise_equal_p (@1, @2))) (with @@ -3697,7 +3697,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_and (code1:c@3 @0 @1) (code2:c@4 @0 @2)) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) - || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) && operand_equal_p (@1, @2))) (with @@ -3747,7 +3747,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_ior:c (code1:c@3 @0 @1) (code2:c@4 (convert?@c0 @0) @2)) (if ((TREE_CODE (@1) == INTEGER_CST && TREE_CODE (@2) == INTEGER_CST) - || ((INTEGRAL_TYPE_P (TREE_TYPE (@1)) + || ((ANY_INTEGRAL_TYPE_P (TREE_TYPE (@1)) || POINTER_TYPE_P (TREE_TYPE (@1))) && bitwise_equal_p (@1, @2))) (with @@ -3880,7 +3880,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) rcmp (eq gt le eq ge lt) (simplify (eq:c (cmp1:c @0 @1) (cmp2 @0 @1)) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) + (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) + || POINTER_TYPE_P (TREE_TYPE (@0))) (rcmp @0 @1)))) /* (type)([0,1]@a != 0) -> (type)a @@ -6510,6 +6511,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { build_int_cst (integer_type_node, prec - 1);})))))) #endif +(for op1 (simple_comparison) + (for op2 (simple_comparison) + (for lop (bit_and bit_ior) + (simplify + (lop + (vec_cond (op1 @0 @1) integer_minus_onep@2 integer_zerop@3) + (vec_cond (op2 @0 @1) integer_minus_onep@2 integer_zerop@3)) + (with { tree op_type = truth_type_for (TREE_TYPE (@0)); } + (vec_cond (lop:op_type (op1 @0 @1) (op2 @0 @1)) @2 @3)))))) + (for cnd (cond vec_cond) /* (a != b) ? (a - b) : 0 -> (a - b) */ (simplify diff --git a/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c new file mode 100644 index 000000000000..c4b95a21996d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vector-compare-5.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-fdump-tree-original-all" } */ + +typedef int v4i __attribute__((vector_size(4*sizeof(int)))); + +/* Ensure we can simplify `VEC_COND_EXPR(a OP1 b) OP2 VEC_COND_EXPR(a OP3 b)` + * into `VEC_COND_EXPR(a OP4 b)` + */ + +void use (v4i const *z); + +void +g (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x > *y | *x == *y; // expect >= + *t = *x > *y | *x <= *y; // expect true +} + +void +h (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x <= *y & *x >= *y; // expect x == y + *t = *x <= *y & *x != *y; // expect x<y +} + +void +i (v4i *x, v4i const *y, v4i *z, v4i *t) +{ + *z = *x == *y | *x != *y; // expect true + *t = *x == *y & *x != *y; // expect false +} + +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*>=\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*==\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*VEC_COND_EXPR\\s*<\\s*\\*xD\\.\\d+\\s*<\\s*VIEW_CONVERT_EXPR<v4iD\\.\\d+>\\(\\*yD\\.\\d+\\)\\s*,\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*,\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*>\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*zD\\.\\d+\\s*=\\s*\\{\\s*-1(,\\s*-1){3}\\s*\\}\\s*;" "original" } } */ +/* { dg-final { scan-tree-dump ".*\\*tD\\.\\d+\\s*=\\s*\\{\\s*0(,\\s*0){3}\\s*\\}\\s*;" "original" } } */ + + -- 2.43.0