summaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorTamar Christina <tamar.christina@arm.com>2021-11-24 06:38:18 +0000
committerTamar Christina <tamar.christina@arm.com>2021-11-24 06:38:18 +0000
commit0888d6bbe97e10de0e624f4ab46acc276e5ee1d7 (patch)
tree73d71b61ff24ac2ea345b2e637fd82daa88271ae /gcc/match.pd
parentd71d019f63ed5d3fdb34579023bafa4dcf323f2c (diff)
middle-end: Convert bitclear <imm> + cmp<cc> #0 into cm<cc2> <imm2>
This optimizes the case where a mask Y which fulfills ~Y + 1 == pow2 is used to clear a some bits and then compared against 0 into one without the masking and a compare against a different bit immediate. We can do this for all unsigned compares and for signed we can do it for comparisons of EQ and NE: (x & (~255)) == 0 becomes x <= 255. Which for leaves it to the target to optimally deal with the comparison. This transformation has to be done in the mid-end because in RTL you don't have the signs of the comparison operands and if the target needs an immediate this should be floated outside of the loop. The RTL loop invariant hoisting is done before split1. i.e. void fun1(int32_t *x, int n) { for (int i = 0; i < (n & -16); i++) x[i] = (x[i]&(~255)) == 0; } now generates: .L3: ldr q0, [x0] cmhs v0.4s, v2.4s, v0.4s and v0.16b, v1.16b, v0.16b str q0, [x0], 16 cmp x0, x1 bne .L3 and floats the immediate out of the loop. instead of: .L3: ldr q0, [x0] bic v0.4s, #255 cmeq v0.4s, v0.4s, #0 and v0.16b, v1.16b, v0.16b str q0, [x0], 16 cmp x0, x1 bne .L3 In order to not break IVopts and CSE I have added a requirement for the scalar version to be single use. gcc/ChangeLog: * tree.c (bitmask_inv_cst_vector_p): New. * tree.h (bitmask_inv_cst_vector_p): New. * match.pd: Use it in new bitmask compare pattern. gcc/testsuite/ChangeLog: * gcc.dg/bic-bitmask-10.c: New test. * gcc.dg/bic-bitmask-11.c: New test. * gcc.dg/bic-bitmask-12.c: New test. * gcc.dg/bic-bitmask-13.c: New test. * gcc.dg/bic-bitmask-14.c: New test. * gcc.dg/bic-bitmask-15.c: New test. * gcc.dg/bic-bitmask-16.c: New test. * gcc.dg/bic-bitmask-17.c: New test. * gcc.dg/bic-bitmask-18.c: New test. * gcc.dg/bic-bitmask-19.c: New test. * gcc.dg/bic-bitmask-2.c: New test. * gcc.dg/bic-bitmask-20.c: New test. * gcc.dg/bic-bitmask-21.c: New test. * gcc.dg/bic-bitmask-22.c: New test. * gcc.dg/bic-bitmask-23.c: New test. * gcc.dg/bic-bitmask-3.c: New test. * gcc.dg/bic-bitmask-4.c: New test. * gcc.dg/bic-bitmask-5.c: New test. * gcc.dg/bic-bitmask-6.c: New test. * gcc.dg/bic-bitmask-7.c: New test. * gcc.dg/bic-bitmask-8.c: New test. * gcc.dg/bic-bitmask-9.c: New test. * gcc.dg/bic-bitmask.h: New test. * gcc.target/aarch64/bic-bitmask-1.c: New test.
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd21
1 files changed, 20 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 60b4ad5f706..3e54e2cf5a6 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -38,7 +38,8 @@ along with GCC; see the file COPYING3. If not see
uniform_integer_cst_p
HONOR_NANS
uniform_vector_p
- expand_vec_cmp_expr_p)
+ expand_vec_cmp_expr_p
+ bitmask_inv_cst_vector_p)
/* Operator lists. */
(define_operator_list tcc_comparison
@@ -5207,6 +5208,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(eqcmp (bit_and @1 { wide_int_to_tree (ty, mask - rhs); })
{ build_zero_cst (ty); }))))))
+/* Transform comparisons of the form (X & Y) CMP 0 to X CMP2 Z
+ where ~Y + 1 == pow2 and Z = ~Y. */
+(for cst (VECTOR_CST INTEGER_CST)
+ (for cmp (le eq ne ge gt)
+ icmp (le le gt le gt)
+ (simplify
+ (cmp (bit_and:c@2 @0 cst@1) integer_zerop)
+ (with { tree csts = bitmask_inv_cst_vector_p (@1); }
+ (switch
+ (if (csts && TYPE_UNSIGNED (TREE_TYPE (@1))
+ && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2)))
+ (icmp @0 { csts; }))
+ (if (csts && !TYPE_UNSIGNED (TREE_TYPE (@1))
+ && (cmp == EQ_EXPR || cmp == NE_EXPR)
+ && (VECTOR_TYPE_P (TREE_TYPE (@1)) || single_use (@2)))
+ (with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
+ (icmp (convert:utype @0) { csts; }))))))))
+
/* -A CMP -B -> B CMP A. */
(for cmp (tcc_comparison)
scmp (swapped_tcc_comparison)