On Fri, 22 Mar 2024, Jakub Jelinek wrote: > Hi! > > The following patch fixes some bugs in the handling of stores to large/huge > _BitInt bitfields. > > In the first 2 hunks we are processing the most significant limb of the > actual type (not necessarily limb in the storage), and so we know it is > either partial or full limb, so [1, limb_prec] bits rather than > [0, limb_prec - 1] bits as the code actually assumed. So, those 2 > spots are fixed by making sure if tprec is a multiple of limb_prec we > actually use limb_prec bits rather than 0. Otherwise, it e.g. happily > could create and use 0 precision INTEGER_TYPE even when it actually > should have processed 64 bits, or for non-zero bo_bit could handle just > say 1 bit rather than 64 bits plus 1 bit in the last hunk spot. > > In the last hunk we are dealing with the extra bits in the last storage > limb, and the code was e.g. happily creating 65 bit precision INTEGER_TYPE, > even when we really should use 1 bit precision in that case. Also, it > used a wrong offset in that case. > > The large testcase covers all these cases. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. > 2024-03-22 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/114405 > * gimple-lower-bitint.cc (bitint_large_huge::lower_mergeable_stmt): > Set rprec to limb_prec rather than 0 if tprec is divisible by > limb_prec. In the last bf_cur handling, set rprec to (tprec + bo_bit) > % limb_prec rather than tprec % limb_prec and use just rprec instead > of rprec + bo_bit. For build_bit_field_ref offset, divide > (tprec + bo_bit) by limb_prec rather than just tprec. > > * gcc.dg/bitint-103.c: New test. > > --- gcc/gimple-lower-bitint.cc.jj 2024-03-20 15:03:30.868068343 +0100 > +++ gcc/gimple-lower-bitint.cc 2024-03-21 12:51:26.728296098 +0100 > @@ -2737,7 +2737,7 @@ bitint_large_huge::lower_mergeable_stmt > && tree_fits_uhwi_p (idx)) > { > unsigned int tprec = TYPE_PRECISION (type); > - unsigned int rprec = tprec % limb_prec; > + unsigned int rprec = (tprec - 1) % limb_prec + 1; > if (rprec + bo_bit < (unsigned) limb_prec) > { > tree ftype > @@ -2882,7 +2882,7 @@ bitint_large_huge::lower_mergeable_stmt > if (nlhs && i == cnt - 1) > { > unsigned int tprec = TYPE_PRECISION (type); > - unsigned int rprec = tprec % limb_prec; > + unsigned int rprec = (tprec - 1) % limb_prec + 1; > if (rprec + bo_bit < (unsigned) limb_prec) > { > tree ftype > @@ -2934,11 +2934,11 @@ bitint_large_huge::lower_mergeable_stmt > if (bf_cur != NULL_TREE) > { > unsigned int tprec = TYPE_PRECISION (type); > - unsigned int rprec = tprec % limb_prec; > - tree ftype = build_nonstandard_integer_type (rprec + bo_bit, 1); > + unsigned int rprec = (tprec + bo_bit) % limb_prec; > + tree ftype = build_nonstandard_integer_type (rprec, 1); > tree bfr = build_bit_field_ref (ftype, unshare_expr (nlhs), > - rprec + bo_bit, > - (bo_idx + tprec / limb_prec) > + rprec, > + (bo_idx + (tprec + bo_bit) / limb_prec) > * limb_prec); > rhs1 = bf_cur; > if (bf_cur != ext) > --- gcc/testsuite/gcc.dg/torture/bitint-66.c.jj 2024-03-21 > 11:53:00.790647163 +0100 > +++ gcc/testsuite/gcc.dg/torture/bitint-66.c 2024-03-21 11:52:29.296082298 > +0100 > @@ -0,0 +1,187 @@ > +/* PR tree-optimization/114405 */ > +/* { dg-do run { target bitint } } */ > +/* { dg-options "-std=c23" } */ > +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ > +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ > + > +#if __BITINT_MAXWIDTH__ >= 22658 > +struct S1 { unsigned _BitInt(22592) b : 22592; } s1; > +struct S2 { unsigned _BitInt(22656) b : 22656; } s2; > +struct S3 { unsigned _BitInt(22656) a : 1; unsigned _BitInt(22656) b : > 22592; } s3; > +struct S4 { unsigned _BitInt(22720) a : 1; unsigned _BitInt(22720) b : > 22656; } s4; > +struct S5 { unsigned _BitInt(22656) a : 63; unsigned _BitInt(22656) b : > 22592; } s5; > +struct S6 { unsigned _BitInt(22720) a : 63; unsigned _BitInt(22720) b : > 22656; } s6; > +struct S7 { unsigned _BitInt(22656) a : 63; unsigned _BitInt(22656) b : > 22593; } s7; > +struct S8 { unsigned _BitInt(22720) a : 63; unsigned _BitInt(22720) b : > 22657; } s8; > +struct S9 { unsigned _BitInt(22720) a : 63; unsigned _BitInt(22720) b : > 22594; } s9; > +struct S10 { unsigned _BitInt(22784) a : 63; unsigned _BitInt(22784) b : > 22658; } s10; > + > +void > +f1 () > +{ > + s1.b -= 1; > +} > + > +void > +f2 () > +{ > + s2.b -= 2; > +} > + > +void > +f3 () > +{ > + s3.b -= 3; > +} > + > +void > +f4 () > +{ > + s4.b -= 4; > +} > + > +void > +f5 () > +{ > + s5.b -= 5; > +} > + > +void > +f6 () > +{ > + s6.b -= 6; > +} > + > +void > +f7 () > +{ > + s7.b -= 7; > +} > + > +void > +f8 () > +{ > + s8.b -= 8; > +} > + > +void > +f9 () > +{ > + s9.b -= 9; > +} > + > +void > +f10 () > +{ > + s10.b -= 10; > +} > +#endif > + > +int > +main () > +{ > +#if __BITINT_MAXWIDTH__ >= 22658 > + unsigned _BitInt (22658) x = > 3501580033805053749865300897557477748847108711329567819459950478637111871058594476448431982181406867749052786465568547119127081237631518700636291761657692711130286544798301573970754389430181232761313430384112082690679079970794557194035367971799245661822847552854751058689774923352618076279671533857647416220848224757950147275156424428066646775909830613059147055969908435491029488219272365184159239392675718030519595002477456422002503056329294735478175929919496649872687647968807723892148311099405402751084714404228175329038682692189134908965253321284763753920366394429186473575417235289083442686263212696116398504697202530139901868456674078599632672207665940094189378896012274962391648560141536000227467537703024522843127564358988666808529295039927617882180358290797693401871123229357470298820489718939095566339078181096952355501349273568695715290536537030927540926367088533791408779004958420139510975491969746508442551722498053308778185098046700981285673069607429 7910828639377203631339464675255240105642870755676377580847320171721410474552064279926175805508159289600278139657791849436955572980238115099785715087280249620991823931002767709388014969775014532212905291917079945444559149155885537869443203998149528921864913273054936504913012987390968722761436324692074211426577825330615158003561217398156744067970380132500886173138375004010286681801118436837157169356000174611385663795085963585748604221595275406157579119331428498714316454502878707144485541046851763795055069716380454650877888082099155307604956585565750095456844726339707735735457306818630192757960862820008907032696106990880643682877297054778560972681289475676822120960274032924190097299892650196374738015462740789768656492119706888461868600641030840748136350368218121335079547275823933746794720376649284092875982043181284314358557128707984260557357154662378677928178190735268683492714017854629967153014231157377885091064447831201063510650297385915804287319939506628451435721208364052433627434988 7298662378072029694678352540100381344582406385372089002610714745433017263971246287780098138858445161168758147579517122047257558660730026818550665432969475798588251031980609543594536607704004284643671832629456597414421298864967827502032914361307828728358332109316327886922442493843907268417663046683437294533161252426630358454578409533376882850312377085740706727584706071883065032915501382320314266799396174517395898171126691776116839064587641297361142733285421882576014636790421571043264527432282199047065156175545274040484862594439887719775125510778610165240710649669702450178422560226062520615338480524359449770750116836269249278642802657582046653770615940590170998509794658765324193134862407174869068241593536055633086226251014577885194625411661775602814877995037981085884408254266073030002874099684207120496049916957909216398108674801381283064454189869127438005216713546145328338722658631127997155356877394789876797870183369709196956603906822646361505775669667647218025399986089915965965465569 6041764175806997830988661505506570268705364569312499547833245414680035989401508937878332603696114785031760589634831372662555378106192337871868765042004938316399029922046201490115097572397634399079073980935654723916987312320325707848563520372220518761329467258570671247604267759011063903006911383788841543800548434412776878092108527493561987417394898971584019389684922039236810451851403140917905252458507059606627700181991099055359750878654027452004298102254317942669228411576884730076031979860278271950271147997784187427993025681631445236633102464546578517080096798491577027430205637328858984848358627110281605835382860215484869451298488587179094216208242723800558137655675403579009115551342574105547116614383452531998695222631800922621940166465384286025568044807066440751367245844978207473901136547335822965098874847249062937074402239146662536111305441261257467813421603285655686364226541439841193527380410804499378326924926231091634327891769813861171406111239337389718538888214657118679476930091 4631780033370026907455350009100991398234230544005707225639911199001521060556494353269734418926976543883020167814965921931535096716826458262250189637748592376073865192810054352613051207327474619337934761146663426134935118503413825504082424332977262179190227449970171913254842194017309504632878985906186166214692140433429536009075713610528721894447986767468896884878765453610651622692341168938373665683970274583865449382798823150851403509730677053140708625595483245639618740574210653530198624859276131133783495033522802696413029101559426339050058584932631815922210413946199510350852865446812403106276713939581929546785460511137593419056060306250217029285811803013980616801841304694722011435758766177962049701664613512583182049260761144544863256467186213830060851829683883752577265078689385674617164146035435092588247318322733523567283845432256120837686647944780078580265417701923133121360511602219094764926277534354807040327859447719471002245844782328492039359603459083181436222097669007774554756731 2680160514879333129726161376588536503174614941960704887174049756335486859344618154678796730437380285016623857657263394473190242609307399515056939928261783433741498575457191002814344076045074699451115450324376560994244125733363690791688620030948556896005459334486992630811287741350843254329359700251606341653571454433780062206621604456479431281953525614251270994176471966683843351093490311346964638559068748656754197807419811396455872748394198642308213954694186836369359308346092913532277753127161762666534419658346979275791601776801867089703083157496506876624595993870551718087267196646736592546937426297422108750191983363747055083719030935424109952530135016014260163282148647070095343886999715396169729189257487291117924761471320991514080674156717712687585623364723331735613774248566070160762173458132002098376222932612692960491023571292592918473033107884023354730551047939250181082663655663341449579770110220809542744835130761810955721396736227972790768312192727111082560814259913758135181354426 65798185129409104195642582574005698068543758814799878628816260575002894250723437469293380754329373751478069967151946701724550270952583590048204731437620446357611597703063140065615278014456977266371201795995646459704425842307781189527028486070466105764495249910844961272734411722090576328496690678921549811732110098855139371357058264972132635004768261508328436120677484741464226299067993312922923316398805257936717699519222213192533192746600829048907097046462066206043987729487350920474035219484795840791105847762753227958460953129122508970162044661061074090561192446511631511339514682638233698374095743691902757648070625949939841339410289027899541368321851192767145693326883564251857041615916159616490433637711319076039315762942426225728417924096927156791836747462094823404471357021596544260573448601630171546391583358297381573516226814145190492133449221202013592319137021uwb; > + unsigned _BitInt (22658) y = ~x, a; > + a = x >> (22658 - 22592); > + s1.b = a; > + f1 (); > + if (s1.b != a - 1) > + __builtin_abort (); > + a = y >> (22658 - 22592); > + s1.b = a; > + f1 (); > + if (s1.b != a - 1) > + __builtin_abort (); > + a = x >> (22658 - 22656); > + s2.b = a; > + f2 (); > + if (s2.b != a - 2) > + __builtin_abort (); > + a = y >> (22658 - 22656); > + s2.b = a; > + f2 (); > + if (s2.b != a - 2) > + __builtin_abort (); > + a = x >> (22658 - 22592); > + s3.b = a; > + f3 (); > + if (s3.b != a - 3) > + __builtin_abort (); > + a = y >> (22658 - 22592); > + s3.b = a; > + f3 (); > + if (s3.b != a - 3) > + __builtin_abort (); > + a = x >> (22658 - 22656); > + s4.b = a; > + f4 (); > + if (s4.b != a - 4) > + __builtin_abort (); > + a = y >> (22658 - 22656); > + s4.b = a; > + f4 (); > + if (s4.b != a - 4) > + __builtin_abort (); > + a = x >> (22658 - 22592); > + s5.b = a; > + f5 (); > + if (s5.b != a - 5) > + __builtin_abort (); > + a = y >> (22658 - 22592); > + s5.b = a; > + f5 (); > + if (s5.b != a - 5) > + __builtin_abort (); > + a = x >> (22658 - 22656); > + s6.b = a; > + f6 (); > + if (s6.b != a - 6) > + __builtin_abort (); > + a = y >> (22658 - 22656); > + s6.b = a; > + f6 (); > + if (s6.b != a - 6) > + __builtin_abort (); > + a = x >> (22658 - 22593); > + s7.b = a; > + f7 (); > + if (s7.b != a - 7) > + __builtin_abort (); > + a = y >> (22658 - 22593); > + s7.b = a; > + f7 (); > + if (s7.b != a - 7) > + __builtin_abort (); > + a = x >> (22658 - 22657); > + s8.b = a; > + f8 (); > + if (s8.b != a - 8) > + __builtin_abort (); > + a = y >> (22658 - 22657); > + s8.b = a; > + f8 (); > + if (s8.b != a - 8) > + __builtin_abort (); > + a = x >> (22658 - 22594); > + s9.b = a; > + f9 (); > + if (s9.b != a - 9) > + __builtin_abort (); > + a = y >> (22658 - 22594); > + s9.b = a; > + f9 (); > + if (s9.b != a - 9) > + __builtin_abort (); > + a = x >> (22658 - 22658); > + s10.b = a; > + f10 (); > + if (s10.b != a - 10) > + __builtin_abort (); > + a = y >> (22658 - 22658); > + s10.b = a; > + f10 (); > + if (s10.b != a - 10) > + __builtin_abort (); > +#endif > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)