https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92712
--- Comment #14 from rguenther at suse dot de <rguenther at suse dot de> --- On November 29, 2019 4:59:35 PM GMT+01:00, "jakub at gcc dot gnu.org" <gcc-bugzi...@gcc.gnu.org> wrote: >https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92712 > >--- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> --- >(In reply to Marc Glisse from comment #11) >> (In reply to Jakub Jelinek from comment #10) >> > I know, it will be a small complication, sure, but it can be >handled. >> >> Ah, I think I understand now. But still >> >> x=-1 >> a=INT_MAX >> a*x+x gives INT_MIN without overflow. >> Now a could be (int)((unsigned)b-1) where b is INT_MIN. But we don't >want to >> generate b*x for that (INT_MIN*-1), since it overflows. So we would >need to >> do the multiplication in some unsigned type. If we go there (do >everything >> unsigned), we could do the transformation always, and restricting it >is just >> a heuristic for when the signed type information might be more useful >than >> the factorized form. > >The comments at least in fold-const.c say clearly that we do not want >to >perform unsigned multiplication. Yeah, doing so early regresses things too much. Doing it late with wrapv was my idea a while back. I've arranged it to be before the last reassoc pass but moved(?) the last VRP before that. >I was talking about the int a, b; >((int)(a-1U))*b+b >transformation into a*b. >Even for a=0, it is -1*b+b into 0, there could be UB before, but there >is none >after. a=INT_MIN used to be INT_MAX*b+b and newly INT_MIN*b, well >defined for >b=0, UB for b > 0, UB for b < -1, but it is true that INT_MAX*-1+-1 is >well >defined INT_MIN, but INT_MIN*-1 is UB. >So guess we need to use range info only then.