Hi! In GCC8/9 we used to optimize this into a bswap, but we no longer do. Handling byteswapping of pointers is easy, all we need is to allow them, for the __builtin_bswap* we already use TYPE_PRECISION to determine the precision and we cast the operand and result to the correct type if they aren't uselessly convertible to what the builtin expects.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-03-31 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/96573 * gimple-ssa-store-merging.c (init_symbolic_number): Handle also pointer types. * gcc.dg/pr96573.c: New test. --- gcc/gimple-ssa-store-merging.c.jj 2021-02-22 17:54:05.701798074 +0100 +++ gcc/gimple-ssa-store-merging.c 2021-03-31 11:30:55.519845647 +0200 @@ -333,7 +333,7 @@ init_symbolic_number (struct symbolic_nu { int size; - if (! INTEGRAL_TYPE_P (TREE_TYPE (src))) + if (!INTEGRAL_TYPE_P (TREE_TYPE (src)) && !POINTER_TYPE_P (TREE_TYPE (src))) return false; n->base_addr = n->offset = n->alias_set = n->vuse = NULL_TREE; --- gcc/testsuite/gcc.dg/pr96573.c.jj 2021-03-31 11:39:19.382122478 +0200 +++ gcc/testsuite/gcc.dg/pr96573.c 2021-03-31 11:39:54.186727148 +0200 @@ -0,0 +1,20 @@ +/* PR tree-optimization/96573 */ +/* { dg-do compile { target { lp64 || ilp32 } } } */ +/* { dg-require-effective-target bswap } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump "__builtin_bswap" "optimized" } } */ + +typedef __SIZE_TYPE__ size_t; + +void * +foo (void * const p) +{ + const size_t m = sizeof (p) - 1; + const unsigned char * const o = (unsigned char*) &p; + void *n; + unsigned char * const q = (unsigned char *) &n; + unsigned char i; + for (i = 0; i <= m; ++i) + q[m - i] = o[i]; + return n; +} Jakub