On Wed, 28 Feb 2024, Jakub Jelinek wrote: > Hi! > > The following patch changes the memcpy etc. folding to use bitwise vector > types rather than huge INTEGER_TYPEs for copying of > MAX_FIXED_MODE_SIZE > lengths. The problem with the huge INTEGER_TYPEs is that they aren't > supported very much, usually there are just optabs to handle moves of them, > perhaps misaligned moves and that is it, so they pose problems e.g. to > BITINT_TYPE lowering. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. I guess the int_mode_for_size (ilen * BITS_PER_UNIT, 0).exists (&imode) could then be removed in stage1? Thanks, Richard. > 2024-02-28 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/113988 > * stor-layout.h (bitwise_mode_for_size): Declare. > * stor-layout.cc (bitwise_mode_for_size): New function. > * gimple-fold.cc (gimple_fold_builtin_memory_op): Use it. > Use bitwise_type_for_mode instead of build_nonstandard_integer_type. > Use BITS_PER_UNIT instead of 8. > > * gcc.dg/bitint-91.c: New test. > > --- gcc/stor-layout.h.jj 2024-01-03 11:51:28.103778767 +0100 > +++ gcc/stor-layout.h 2024-02-27 12:32:17.716535079 +0100 > @@ -102,6 +102,8 @@ extern opt_machine_mode mode_for_size_tr > > extern tree bitwise_type_for_mode (machine_mode); > > +extern opt_machine_mode bitwise_mode_for_size (poly_uint64); > + > /* Given a VAR_DECL, PARM_DECL or RESULT_DECL, clears the results of > a previous call to layout_decl and calls it again. */ > extern void relayout_decl (tree); > --- gcc/stor-layout.cc.jj 2024-01-17 13:53:13.160176498 +0100 > +++ gcc/stor-layout.cc 2024-02-27 12:27:20.876647298 +0100 > @@ -476,6 +476,32 @@ bitwise_type_for_mode (machine_mode mode > return inner_type; > } > > +/* Find a mode that can be used for efficient bitwise operations on SIZE > + bits, if one exists. */ > + > +opt_machine_mode > +bitwise_mode_for_size (poly_uint64 size) > +{ > + if (known_le (size, (unsigned int) MAX_FIXED_MODE_SIZE)) > + return mode_for_size (size, MODE_INT, true); > + > + machine_mode mode, ret = VOIDmode; > + FOR_EACH_MODE_FROM (mode, MIN_MODE_VECTOR_INT) > + if (known_eq (GET_MODE_BITSIZE (mode), size) > + && (ret == VOIDmode || GET_MODE_INNER (mode) == QImode) > + && have_regs_of_mode[mode] > + && targetm.vector_mode_supported_p (mode)) > + { > + if (GET_MODE_INNER (mode) == QImode) > + return mode; > + else if (ret == VOIDmode) > + ret = mode; > + } > + if (ret != VOIDmode) > + return ret; > + return opt_machine_mode (); > +} > + > /* Find a mode that is suitable for representing a vector with NUNITS > elements of mode INNERMODE, if one exists. The returned mode can be > either an integer mode or a vector mode. */ > --- gcc/gimple-fold.cc.jj 2024-02-20 10:25:26.297760979 +0100 > +++ gcc/gimple-fold.cc 2024-02-27 12:42:38.338925573 +0100 > @@ -995,9 +995,12 @@ gimple_fold_builtin_memory_op (gimple_st > if (warning != OPT_Wrestrict) > return false; > > - scalar_int_mode mode; > - if (int_mode_for_size (ilen * 8, 0).exists (&mode) > - && GET_MODE_SIZE (mode) * BITS_PER_UNIT == ilen * 8 > + scalar_int_mode imode; > + machine_mode mode; > + if (int_mode_for_size (ilen * BITS_PER_UNIT, 0).exists (&imode) > + && bitwise_mode_for_size (ilen > + * BITS_PER_UNIT).exists (&mode) > + && known_eq (GET_MODE_BITSIZE (mode), ilen * BITS_PER_UNIT) > /* If the destination pointer is not aligned we must be able > to emit an unaligned store. */ > && (dest_align >= GET_MODE_ALIGNMENT (mode) > @@ -1005,7 +1008,7 @@ gimple_fold_builtin_memory_op (gimple_st > || (optab_handler (movmisalign_optab, mode) > != CODE_FOR_nothing))) > { > - tree type = build_nonstandard_integer_type (ilen * 8, 1); > + tree type = bitwise_type_for_mode (mode); > tree srctype = type; > tree desttype = type; > if (src_align < GET_MODE_ALIGNMENT (mode)) > --- gcc/testsuite/gcc.dg/bitint-91.c.jj 2024-02-27 12:08:15.230481756 > +0100 > +++ gcc/testsuite/gcc.dg/bitint-91.c 2024-02-27 12:08:15.230481756 +0100 > @@ -0,0 +1,38 @@ > +/* PR tree-optimization/113988 */ > +/* { dg-do compile { target bitint } } */ > +/* { dg-options "-O2" } */ > +/* { dg-additional-options "-mavx512f" { target i?86-*-* x86_64-*-* } } */ > + > +int i; > + > +#if __BITINT_MAXWIDTH__ >= 256 > +void > +foo (void *p, _BitInt(256) x) > +{ > + __builtin_memcpy (p, &x, sizeof x); > +} > + > +_BitInt(256) > +bar (void *p, _BitInt(256) x) > +{ > + _BitInt(246) y = x + 1; > + __builtin_memcpy (p, &y, sizeof y); > + return x; > +} > +#endif > + > +#if __BITINT_MAXWIDTH__ >= 512 > +void > +baz (void *p, _BitInt(512) x) > +{ > + __builtin_memcpy (p, &x, sizeof x); > +} > + > +_BitInt(512) > +qux (void *p, _BitInt(512) x) > +{ > + _BitInt(512) y = x + 1; > + __builtin_memcpy (p, &y, sizeof y); > + return x; > +} > +#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)