On Wed, 5 Jan 2022 at 17:55, Richard Biener <richard.guent...@gmail.com> wrote:
> On Wed, Jan 5, 2022 at 10:42 AM Jakub Jelinek <ja...@redhat.com> wrote: > > > > On Wed, Jan 05, 2022 at 10:38:53AM +0100, Richard Biener via Gcc-patches > wrote: > > > On Wed, Jan 5, 2022 at 10:18 AM Zhao Wei Liew <zhaoweil...@gmail.com> > wrote: > > > > > > > > > X >= -1 && X <= 1 is (hopefully?) going to be simplified > > > > > as (unsigned)X + 1 <= 2, it might be good to simplify it this way > > > > > here as well? > > > > > > > > Yup, GCC does simplify it that way in the end, so I didn't really > bother to simplify it here. That said, I'm open to simplifying it here as > well, but I'm not sure how to do the unsigned cast. > > > > > > You'd do sth like > > > (with > > > { tree utype = unsigned_type_for (type); } > > > (cond (le (plus (convert:utype @0) { build_one_cst (utype); }) { > > > build_int_cst (utype, 2); }) ...) > > > > > > extra tricky will be 1 bit integer types, I guess it might be easiest > > > to exclude them > > > and special case them separately - X / Y is always X for them I think, > > > > Note, we already have: > > /* X / bool_range_Y is X. */ > > (simplify > > (div @0 SSA_NAME@1) > > (if (INTEGRAL_TYPE_P (type) && ssa_name_has_boolean_range (@1)) > > @0)) > > for those. > > Ah, it might not handle the signed : 1 case though since -1 is not in the > bool range. We could generalize the above though. > > Richard. > > > > > Jakub > > > Perhaps it is possible to exclude 1-bit cases and rely on other existing simplifications to deal with them? In particular, GCC seems to already optimally simplify the signed and unsigned 1-bit cases [1]. [1]: struct S { unsigned int x: 1; int y: 1; }; unsigned int fu(S s) { return 1 / s.x; } int fi(S s) { return 1 / s.y; } fu(S): mov eax, 1 ret fi(S): mov eax, -1 ret