https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126644
--- Comment #1 from Kael Franco <kaelfandrew at gmail dot com> ---
gcc/match.pd has similar pattern:
/* For (x << c) >> c, optimize into x & ((unsigned)-1 >> c) for
unsigned x OR truncate into the precision(type) - c lowest bits
of signed x (if they have mode precision or a precision of 1). */
(simplify
(rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1)
(if (wi::ltu_p (wi::to_wide (@1), element_precision (type)))
(if (TYPE_UNSIGNED (type))
(bit_and (convert @0) (rshift { build_minus_one_cst (type); } @1))
(if (INTEGRAL_TYPE_P (type))
(with {
int width = element_precision (type) - tree_to_uhwi (@1);
tree stype = NULL_TREE;
if (width <= MAX_FIXED_MODE_SIZE)
stype = build_nonstandard_integer_type (width, 0);
}
(if (stype && (width == 1 || type_has_mode_precision_p (stype)))
(convert (convert:stype @0))))))))
Could do some gimple_match_range_of_expr.