This patch prevents the powerpc backend from combining a 64-bit volatile load or store with a bswap insn when the resulting combined insn will be implemented as two lwbrx or stwbrx machine insns. Bootstrapped and regression tested powerpc64-linux.
PR target/58330 * config/rs6000/rs6000.md (bswapdi2_64bit): Disable for volatile mems. gcc/testsuite/ * gcc.target/powerpc/pr58330.c: New. Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 202351) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -2376,7 +2376,9 @@ (clobber (match_scratch:DI 3 "=&r,&r,&r")) (clobber (match_scratch:DI 4 "=&r,X,&r"))] "TARGET_POWERPC64 && !TARGET_LDBRX - && (REG_P (operands[0]) || REG_P (operands[1]))" + && (REG_P (operands[0]) || REG_P (operands[1])) + && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) + && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" "#" [(set_attr "length" "16,12,36")]) Index: gcc/testsuite/gcc.target/powerpc/pr58330.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr58330.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr58330.c (revision 0) @@ -0,0 +1,11 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O -mno-popcntb" } */ +/* { dg-final { scan-assembler-not "stwbrx" } } */ + +void +write_reverse (unsigned long *addr, unsigned long val) +{ + unsigned long reverse = __builtin_bswap64 (val); + __atomic_store_n (addr, reverse, __ATOMIC_RELAXED); +} -- Alan Modra Australia Development Lab, IBM