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)

Reply via email to