On Tue, Jul 25, 2023 at 03:25:57PM -0400, Drew Ross wrote: > > With that fixed I think for non-vector integrals the above is the most > suitable > > canonical form of a sign-extension. Note it should also work for any > other > > constant shift amount - just use the appropriate intermediate precision > for > > the truncating type. > > We _might_ want > > to consider to only use the converts when the intermediate type has > > mode precision (and as a special case allow one bit as in your above case) > > so it can expand to (sign_extend:<outer> (subreg:<inner> reg)). > > Here is a pattern that that only matches to truncations that result in mode > precision (or precision of 1): > > (simplify > (rshift (nop_convert? (lshift @0 INTEGER_CST@1)) @@1) > (if (INTEGRAL_TYPE_P (type) > && !TYPE_UNSIGNED (type) > && wi::gt_p (element_precision (type), wi::to_wide (@1), TYPE_SIGN > (TREE_TYPE (@1))))
I'd use && wi::ltu_p (wi::to_wide (@1), element_precision (type)) If the shift count would be negative, you'd otherwise ICE in tree_to_uhwi on it (sure, that is UB at runtime, but compiler shouldn't ICE on it). > (with { > int width = element_precision (type) - tree_to_uhwi (@1); > tree stype = build_nonstandard_integer_type (width, 0); > } > (if (TYPE_PRECISION (stype) == 1 || type_has_mode_precision_p (stype)) > (convert (convert:stype @0)))))) Jakub