Message ID | ZaEGUldmPTM5d31b@tucnak |
---|---|
State | New |
Headers | show |
Series | c: Avoid _BitInt indexes > sizetype in ARRAY_REFs [PR113315] | expand |
On Fri, 12 Jan 2024, Jakub Jelinek wrote: > Hi! > > When build_array_ref doesn't use ARRAY_REF, it casts the index to sizetype > already, performs POINTER_PLUS_EXPR and then dereferences. > While when emitting ARRAY_REF, we try to keep index expression as is in > whatever type it had, which is reasonable e.g. for signed or unsigned types > narrower than sizetype for loop optimizations etc. > But if the index is wider than sizetype, we are unnecessarily computing > bits beyond what is needed. For {,unsigned }__int128 on 64-bit arches > or {,unsigned }long long on 32-bit arches we've been doing that for decades, > so the following patch doesn't propose to change that (might be stage1 > material), but for _BitInt at least the _BitInt lowering code doesn't expect > to see large/huge _BitInt in the ARRAY_REF indexes, I was expecting one > would see just casts of those to sizetype. > > So, the following patch makes sure that large/huge _BitInt indexes don't > appear in ARRAY_REFs. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK.
--- gcc/c/c-typeck.cc.jj 2024-01-03 12:06:52.940863462 +0100 +++ gcc/c/c-typeck.cc 2024-01-11 12:55:05.457899186 +0100 @@ -2858,6 +2858,10 @@ build_array_ref (location_t loc, tree ar "array"); } + if (TREE_CODE (TREE_TYPE (index)) == BITINT_TYPE + && TYPE_PRECISION (TREE_TYPE (index)) > TYPE_PRECISION (sizetype)) + index = fold_convert (sizetype, index); + type = TREE_TYPE (TREE_TYPE (array)); rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE); /* Array ref is const/volatile if the array elements are --- gcc/testsuite/gcc.dg/bitint-65.c.jj 2024-01-11 13:03:27.843827305 +0100 +++ gcc/testsuite/gcc.dg/bitint-65.c 2024-01-11 13:03:04.807154223 +0100 @@ -0,0 +1,23 @@ +/* PR c/113315 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23" } */ + +#if __BITINT_MAXWIDTH__ >= 535 +_BitInt(535) x; +#else +_BitInt(64) x; +#endif +extern int a[]; +extern char b[][10]; + +int +foo (void) +{ + return a[x]; +} + +int +bar (void) +{ + return __builtin_strlen (b[x]); +} --- gcc/testsuite/gcc.dg/bitint-66.c.jj 2024-01-11 13:08:40.561399890 +0100 +++ gcc/testsuite/gcc.dg/bitint-66.c 2024-01-11 13:09:07.512019458 +0100 @@ -0,0 +1,12 @@ +/* PR c/113315 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=c23 -O2" } */ + +extern int a[5]; + +int +foo (void) +{ + _BitInt(535) i = 1; + return a[i]; +}