From ed7c08c4d565bd4418cf2dce3bbfecc18fdd42a2 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Wed, 25 Dec 2019 01:20:13 +0000 Subject: [PATCH] Add simplification of shift of a bit_field. We can simplify a shift of a bit_field_ref to a shift of an and (note sometimes the shift can be removed). Change-Id: I1a9f3fc87889ecd7cf569272405b6ee7dd5f8d7b Signed-off-by: Andrew Pinski --- diff --git a/gcc/match.pd b/gcc/match.pd index cb981ec..e4f6d47 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -6071,6 +6071,34 @@ (cmp (bit_and @0 { wide_int_to_tree (type1, mask); }) { wide_int_to_tree (type1, cst); }))))) +/* lshift> -> shift(bit_and(@0, mask)) */ +(simplify + (lshift (convert (BIT_FIELD_REF@bit @0 @bitsize @bitpos)) INTEGER_CST@1) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && tree_fits_uhwi_p (@1) + && (tree_nop_conversion_p (type, TREE_TYPE (@0)) + || (TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_UNSIGNED (TREE_TYPE (@bit)) + && TYPE_UNSIGNED (type) + && TYPE_PRECISION (type) > tree_to_uhwi (@bitsize)))) + (with + { + unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (@bitpos); + unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (@bitsize); + if (BYTES_BIG_ENDIAN) + bitpos = TYPE_PRECISION (TREE_TYPE (@0)) - bitpos - bitsize; + wide_int wmask = wi::shifted_mask (bitpos, bitsize, false, TYPE_PRECISION (type)); + } + (switch + (if (tree_to_uhwi (@1) == bitpos) + (bit_and (convert @0) { wide_int_to_tree (type, wmask); })) + (if (tree_to_uhwi (@1) > bitpos) + (lshift (bit_and (convert @0) { wide_int_to_tree (type, wmask); }) + { wide_int_to_tree (integer_type_node, tree_to_uhwi (@1) - bitpos); } )) + (if (tree_to_uhwi (@1) < bitpos) + (rshift (bit_and (convert @0) { wide_int_to_tree (type, wmask); }) + { wide_int_to_tree (integer_type_node, bitpos - tree_to_uhwi (@1)); } )))))) (if (canonicalize_math_after_vectorization_p ()) (for fmas (FMA)