On Mon, Feb 02, 2026 at 08:38:51AM +0000, Pengfei Li wrote:
> This patch computes the constant extension offsets from min_prec, using
> `CEIL (min_prec, limb_prec) * limb_prec / BITS_PER_UNIT`, which reflects
> the number of bytes of actual data represented by the constant.
This looks wrong to me.
This can only happen in the min_prec == prec case and in that case there
should be no extension at all if c is non-NULL, as the copying from c
covers the whole size already.
And the code in there really assumes what is earlier ensured, that if
min_prec < prec, then there is no padding in it, even in the abi_limb_prec >
limb_prec case:
if (min_prec > (unsigned) limb_prec
&& abi_limb_prec > limb_prec)
{
/* For targets with ABI limb precision higher than
limb precision round to ABI limb precision,
otherwise c can contain padding bits. */
min_prec
= CEIL (min_prec, abi_limb_prec) * abi_limb_prec;
if (min_prec > prec - rem - 2 * limb_prec)
min_prec = prec;
}
Normally for the min_prec == prec case we take the
if (c)
{
if (VAR_P (v1) && min_prec == prec)
{
tree v2 = build1 (VIEW_CONVERT_EXPR,
TREE_TYPE (v1), c);
g = gimple_build_assign (v1, v2);
gsi_insert_on_edge (e, g);
edge_insertions = true;
break;
}
path, except here v1 is not a VAR_DECL but PARM_DECL and so we need to
go through the VCE path even for v1.
So, I think we should do following instead.
Tested on x86_64-linux with
make -j32 -k check-gcc GCC_TEST_RUN_EXPENSIVE=1
RUNTESTFLAGS="GCC_TEST_RUN_EXPENSIVE=1 dg.exp='*bitint* pr112673.c
builtin-stdc-bit-*.c pr112566-2.c pr112511.c pr116588.c pr116003.c pr113693.c
pr113602.c flex-array-counted-by-7.c' dg-torture.exp='*bitint* pr116480-2.c
pr114312.c pr114121.c' dfp.exp=*bitint*
vect.exp='vect-early-break_99-pr113287.c' tree-ssa.exp=pr113735.c"
so far, will bootstrap/regtest on x86_64-linux, i686-linux and aarch64-linux
tonight.
2026-02-03 Jakub Jelinek <[email protected]>
PR middle-end/122689
* gimple-lower-bitint.cc (gimple_lower_bitint): For the PHI handling
if min_prec == prec, break after emitting assignment from c.
* gcc.dg/bitint-127.c: New test.
--- gcc/gimple-lower-bitint.cc.jj 2026-01-17 14:35:07.000000000 +0100
+++ gcc/gimple-lower-bitint.cc 2026-02-03 13:22:52.499695216 +0100
@@ -7804,6 +7804,11 @@ gimple_lower_bitint (void)
vtype, c));
}
gsi_insert_on_edge (e, g);
+ if (min_prec == prec)
+ {
+ edge_insertions = true;
+ break;
+ }
}
if (ext == 0)
{
--- gcc/testsuite/gcc.dg/bitint-127.c.jj 2026-02-03 13:27:42.689740451
+0100
+++ gcc/testsuite/gcc.dg/bitint-127.c 2026-02-03 13:28:05.909344012 +0100
@@ -0,0 +1,28 @@
+/* PR middle-end/122689 */
+/* { dg-do run { target { bitint } } } */
+/* { dg-options "-O" } */
+
+#if __BITINT_MAXWIDTH__ >= 12419
+const _BitInt(12419) n =
0xfe65f7aff85d0095103ee4d1c3b9ca50eed67abd838cdc5b53c776c8dd19b0be6eeb21aa421395fc16cf018858c9c2a03b6a013546f938e5af4c286c0456a2f5e09ad52921a4f98ce6cfbdc1beee7b860507f9fbed6640a9ce12aab6ca7e54afa6113fefe2e91a2822e9f32e04c038bb2993f25afd9489117ba43f6d1389a527c0823fd096848c9ae857fac18d08ec59b8dc73df77213ec9d0b0fba9cb38213ac625a864ffe0d4c994be6692af55bdef84699596becccc0b48d6b306bed100e78defd85477a5d7eb57af5b84e70de61141f0e725b23bd26ee239fa91a8816a3b37480f8782564bb91dfc23277303553d302a0b67dbc914fab7f54ca91548bfe66eb9daa9e524509d96e94c502b7df14acf44ef09e9c4f50ad436a504f33e51210f5c4693fdbeb3a486ce7ec50ce18939936ca91e05afc11145461832f007622d19959c4dd5f508d8d60dfc9c79b7b504e5becbc0e09cef83b9a28aadb50bd3b3d071a688455831a697d7ebaa9f64fc106e2f4eb9f8edad3b5937e157d6a3d11f6c3f8a83cc2b737b8bbde90960eec3c1d629a2af864b25c9db8edee90d99e42b9948b247cd04052465da8a647ff3a4cfaa9c5cca2b4ead7e60c6b31cfcd6a5f62fe14d3ea6a914adbd7015ea3240faf3f453e5e135067bf71d4fc625a4318afeb0ba625a42e0294ffadbf356f149775ea67b9652d45cba63210becd0b8bca390c68c2be31842354eeff63e1b49b989d4de4ee11a12c812077e0062229749fd2fb0b129a8fe319a049d45baadd7e72dabe4a5276440468e78dca8ec8a129f6ce2da1a212fcc6610f1dd9eab2258492794fa6209a4a6e889e7a907f951eafe983bdda8dedf1d56af16909ce4281904c3035a8b2d3f4f3b2395f6f153da639a0265154f7fc51a3b4bada7aa6255a40544288348c4049e8d8507eada1ea5526aadfe23385bd72b1e4c0214ee962132c692ee13868e1ea4e5c53a5ff428ecda98e82c60fa01e8ced36edaee0740e19490f0c2c9912198041d0c6af7d327d1df022f6a21f2ce65395f8b5eeff47b475056e6d6debcdee65a220bc705ac235d1e10f25a47642b09bbcbe4509ffc1e621c61f2df88d2a9575692bf1fa8456060347e05fd3b41e369caecaa979c6c3d9fadac24385e871e73c907bf3d0a8d452f85c963e5230791e68e2d8264b854745f9f227b43c8f18e6f1d4060f96a227030880c6f8e2bccda5911bedceb5d2c65640fab851345932e35db4795a41d72ea0d0b4abcdfe0bfe237bf0ae087d517c03bed58bd115cf93c28f3c04a04879e449950043928e439a08e3e6708f1b5a7b99441270793f85f77299edbe8fbc3e4956f6cce8d6babf19939900c68b0dfb5e607ecd59ba7747868ad3495e727fac4daff7d69d9b0f72bc7d73c769bbf5af2135a4832ca205a936f322307ef510992987b8f712c388e72122b0bb633dcb12325d1121657649b7813a0f3952b37156918b65eccce34d0c1219cef72e9326f12920e983a46edfd30b572593e1657194e0c41d1e1830c55ac5dfc3e63dc69d9006eba308f0c85e66da89ddf81a65e6027b3144ea9e000e5d4e6f6354c405e0a47c7be23fd94bb38e7dd2f89e886212d9d6d76dafc173268716d3dc9a4fcca6f623a1df279418b147ea79b08c9eca5c723a949047690d84b6ddaebd2b69100f74d9e4323d15bb410c7dc77a74e646a9949a44a9ab2b697eedcbf060655ded990fdf157cf4ec3d7d1b6cdb50ecc27a3558660df90c993a32fb16771e9ba5f9cddb51edaa1b4592172a0daca839e09f55cf9ea1bb2659eddf52ec2ba75ac27b5c9e82524410f3a0886921235b22ee74319719d0c5b61f0e8dbd7de6533ba8a2e3d7e19ac6bf4036515ffc88ef3b02b85d8abad0e413bd56b1b4f404fa59b73cdc02cab7bf572565767b80ff87bd2bc2772349d122951b84248d406c4e1351d869c12430dc350b51896a0968867396293c7d267514e3fc80dafe5d578b6fbbbe015720942e46be881dd6ece5f131269e326b3be18292846d96cf9dc782d9b5ae8e44549ac9d3ce89347338c2949225bbdddfcf8faeb5cdbb7582fb66eec0cdfb3b21ffe61794a07a066080d1af3d90121a09c62583512a75df831bfbd4b039568197f683d0043d350b688dbe947c92b5cedcd7a64803791bd1a2dc6e0df0b9fb6a294d728e026dc9wb;
+
+unsigned g;
+
+_BitInt(6)
+foo (unsigned a, unsigned b, unsigned c, unsigned _BitInt(256) z,
+ unsigned _BitInt(12419) y)
+{
+ y /= b;
+ unsigned _BitInt(12419) ay = a * y;
+ g -= (n >= ay ? n : ay) % c;
+ return z;
+}
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 12419
+ if (foo (0, 5, 5, 2, 0) != 2)
+ __builtin_abort ();
+#endif
+}
Jakub