On Mon, 15 Jan 2024, Jakub Jelinek wrote: > Hi! > > The INTEGER_CST code uses the remainder bits in computations whether to use > whole constant or just part of it and extend it at runtime, and furthermore > uses it to avoid using all bits even when using the (almost) whole constant. > The problem is that the prec % (2 * limb_prec) computation it uses is > appropriate only for the normal lowering of mergeable operations (where > we process 2 limbs at a time in a loop starting with least significant > limbs and process the remaining 0-2 limbs after the loop (there with > constant indexes). For that case it is ok not to emit the upper > prec % (2 * limb_prec) bits into the constant, because those bits will be > extracted using INTEGER_CST idx and so will be used directly in the > statements as INTEGER_CSTs. > For other cases, where we either process just a single limb in a loop, > process it downwards (e.g. non-equality comparisons) or with some runtime > addends (some shifts), there is either just at most one limb lowered with > INTEGER_CST idx after the loop (e.g. for right shift) or before the loop > (e.g. non-equality comparisons), or all limbs are processed with > non-INTEGER_CST indexes (e.g. for left shift, when m_var_msb is set). > Now, the m_var_msb case is already handled through > if (m_var_msb) > type = TREE_TYPE (op); > else > /* If we have a guarantee the most significant partial limb > (if any) will be only accessed through handle_operand > with INTEGER_CST idx, we don't need to include the partial > limb in .rodata. */ > type = build_bitint_type (prec - rem, 1); > but for the right shifts or comparisons the prec - rem when rem was > prec % (2 * limb_prec) was incorrect, so the following patch fixes it > to use remainder for 2 limbs only if m_upwards_2limb and remainder for > 1 limb otherwise. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. > 2024-01-15 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/113370 > * gimple-lower-bitint.cc (bitint_large_huge::handle_operand): Only > set rem to prec % (2 * limb_prec) if m_upwards_2limb, otherwise > set it to just prec % limb_prec. > > * gcc.dg/torture/bitint-48.c: New test. > > --- gcc/gimple-lower-bitint.cc.jj 2024-01-13 11:29:08.005574338 +0100 > +++ gcc/gimple-lower-bitint.cc 2024-01-13 11:33:55.284646856 +0100 > @@ -869,7 +869,7 @@ bitint_large_huge::handle_operand (tree > && m_data[m_data_cnt + 1] == NULL_TREE)) > { > unsigned int prec = TYPE_PRECISION (TREE_TYPE (op)); > - unsigned int rem = prec % (2 * limb_prec); > + unsigned int rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec); > int ext; > unsigned min_prec = bitint_min_cst_precision (op, ext); > if (m_first) > @@ -996,7 +996,7 @@ bitint_large_huge::handle_operand (tree > if (m_data[m_data_cnt + 1] == integer_type_node) > { > unsigned int prec = TYPE_PRECISION (TREE_TYPE (op)); > - unsigned rem = prec % (2 * limb_prec); > + unsigned rem = prec % ((m_upwards_2limb ? 2 : 1) * limb_prec); > int ext = wi::neg_p (wi::to_wide (op)) ? -1 : 0; > tree c = m_data[m_data_cnt]; > unsigned min_prec = TYPE_PRECISION (TREE_TYPE (c)); > --- gcc/testsuite/gcc.dg/torture/bitint-48.c.jj 2024-01-13 > 11:46:30.707309245 +0100 > +++ gcc/testsuite/gcc.dg/torture/bitint-48.c 2024-01-13 11:46:25.493380637 > +0100 > @@ -0,0 +1,23 @@ > +/* PR tree-optimization/113370 */ > +/* { dg-do run { target bitint } } */ > +/* { dg-options "-std=c23 -pedantic-errors" } */ > +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ > +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ > + > +#if __BITINT_MAXWIDTH__ >= 255 > +_BitInt(255) > +foo (int s) > +{ > + return -(_BitInt(255)) 3 >> s; > +} > +#endif > + > +int > +main () > +{ > +#if __BITINT_MAXWIDTH__ >= 255 > + if (foo (51) != -1) > + __builtin_abort (); > +#endif > + return 0; > +} > > 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)