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.
2021-04-01 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/96573
* gimple-ssa-store-merging.c (init_symbolic_number): Handle
also pointer types.
* gcc.dg/pr96573.c: New test.
{
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;
--- /dev/null
+/* 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;
+}