https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122041
Bug ID: 122041 Summary: SPARC: gzip-style CRC computation runs >2× slower with GCC than Solaris Studio Product: gcc Version: 15.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: sumbera at volny dot cz Target Milestone: --- Created attachment 62440 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62440&action=edit reproducible example While comparing the performance of gzip built with GCC and Solaris Studio, I noticed a significant performance gap when GCC is used. I was able to reproduce the issue with a simplified CRC calculation, included as test.tar.gz Tested on Solaris 11.4 with GCC 15.2 and Solaris Studio 12.6. PATH=/usr/gcc/15/bin/:/usr/bin gmake test gcc -o test.o -c test.c gcc -O4 -funroll-loops -finline-functions -fstrict-aliasing -o crc-gcc.o -c crc.c gcc -o test-gcc test.o crc-gcc.o /opt/developerstudio12.6/bin/cc -m64 -xO4 -xtarget=generic -xarch=sparcvis -xchip=generic -xregs=no%appl -xmemalign=16s -o crc-studio.o -c crc.c gcc -o test-studio test.o crc-studio.o time ./test-gcc real 34.5 user 34.4 sys 0.0 time ./test-studio real 14.4 user 14.4 sys 0.0 === For reference here is disassembled crc32_update_no_xor() from both compilers. GCC 15.2: ========= crc32_update_no_xor: save %sp, -0xc0, %sp crc32_update_no_xor+4: and %i2, -0x8, %i2 crc32_update_no_xor+8: brz,pn %i2, +0x160 <crc32_update_no_xor+0x168> crc32_update_no_xor+0xc: sethi %hi(0x0), %l3 crc32_update_no_xor+0x10: mov 0xff, %i5 crc32_update_no_xor+0x14: or %l3, 0x0, %g1 crc32_update_no_xor+0x18: sllx %i5, 0x30, %l2 crc32_update_no_xor+0x1c: sllx %g1, 0xc, %g2 crc32_update_no_xor+0x20: sllx %i5, 0x28, %l1 crc32_update_no_xor+0x24: sllx %i5, 0x20, %l0 crc32_update_no_xor+0x28: clr %l4 crc32_update_no_xor+0x2c: or %g2, 0x0, %l3 crc32_update_no_xor+0x30: sethi %hi(0xff000000), %i3 crc32_update_no_xor+0x34: sethi %hi(0xff0000), %i4 crc32_update_no_xor+0x38: sllx %i5, 0x8, %i5 crc32_update_no_xor+0x3c: add %i1, %l4, %o1 crc32_update_no_xor+0x40: mov 0x8, %o2 crc32_update_no_xor+0x44: call +0x0 <crc32_update_no_xor+0x44> crc32_update_no_xor+0x48: add %fp, 0x7f7, %o0 crc32_update_no_xor+0x4c: ldx [%fp + 0x7f7], %g5 crc32_update_no_xor+0x50: srlx %g5, 0x38, %g4 crc32_update_no_xor+0x54: sllx %g5, 0x28, %g3 crc32_update_no_xor+0x58: sllx %g5, 0x18, %o1 crc32_update_no_xor+0x5c: and %g3, %l2, %o0 crc32_update_no_xor+0x60: and %o1, %l1, %o2 crc32_update_no_xor+0x64: sllx %g5, 0x8, %o3 crc32_update_no_xor+0x68: and %o3, %l0, %o4 crc32_update_no_xor+0x6c: srlx %g5, 0x8, %o5 crc32_update_no_xor+0x70: sllx %g5, 0x38, %g1 crc32_update_no_xor+0x74: and %o5, %i3, %g2 crc32_update_no_xor+0x78: or %g1, %g4, %g1 crc32_update_no_xor+0x7c: srlx %g5, 0x18, %g4 crc32_update_no_xor+0x80: or %g1, %o0, %g1 crc32_update_no_xor+0x84: and %g4, %i4, %g3 crc32_update_no_xor+0x88: or %g1, %o2, %g1 crc32_update_no_xor+0x8c: srlx %g5, 0x28, %g5 crc32_update_no_xor+0x90: or %g1, %o4, %g1 crc32_update_no_xor+0x94: and %g5, %i5, %o0 crc32_update_no_xor+0x98: or %g1, %g2, %g1 crc32_update_no_xor+0x9c: or %g1, %g3, %g1 crc32_update_no_xor+0xa0: or %g1, %o0, %g1 crc32_update_no_xor+0xa4: xor %g1, %i0, %i0 crc32_update_no_xor+0xa8: and %i0, 0xff, %o1 crc32_update_no_xor+0xac: srlx %i0, 0x30, %o4 crc32_update_no_xor+0xb0: add %o1, 0x700, %o2 crc32_update_no_xor+0xb4: sllx %o2, 0x2, %o3 crc32_update_no_xor+0xb8: and %o4, 0xff, %g2 crc32_update_no_xor+0xbc: ld [%l3 + %o3], %o5 crc32_update_no_xor+0xc0: add %g2, 0x100, %g4 crc32_update_no_xor+0xc4: srlx %i0, 0x28, %g3 crc32_update_no_xor+0xc8: sllx %g4, 0x2, %g5 crc32_update_no_xor+0xcc: and %g3, 0xff, %o0 crc32_update_no_xor+0xd0: ld [%l3 + %g5], %o1 crc32_update_no_xor+0xd4: add %o0, 0x200, %o2 crc32_update_no_xor+0xd8: srlx %i0, 0x20, %o4 crc32_update_no_xor+0xdc: sllx %o2, 0x2, %o3 crc32_update_no_xor+0xe0: and %o4, 0xff, %g2 crc32_update_no_xor+0xe4: srlx %i0, 0x18, %g3 crc32_update_no_xor+0xe8: add %g2, 0x300, %g4 crc32_update_no_xor+0xec: and %g3, 0xff, %o0 crc32_update_no_xor+0xf0: sllx %g4, 0x2, %g5 crc32_update_no_xor+0xf4: add %o0, 0x400, %o2 crc32_update_no_xor+0xf8: srlx %i0, 0x38, %g1 crc32_update_no_xor+0xfc: srlx %i0, 0x10, %o4 crc32_update_no_xor+0x100: sllx %g1, 0x2, %g1 crc32_update_no_xor+0x104: srlx %i0, 0x8, %i0 crc32_update_no_xor+0x108: ld [%l3 + %g1], %g1 crc32_update_no_xor+0x10c: xor %g1, %o5, %g1 crc32_update_no_xor+0x110: ld [%l3 + %o3], %o5 crc32_update_no_xor+0x114: xor %g1, %o1, %g1 crc32_update_no_xor+0x118: sllx %o2, 0x2, %o3 crc32_update_no_xor+0x11c: ld [%l3 + %g5], %o1 crc32_update_no_xor+0x120: xor %g1, %o5, %g1 crc32_update_no_xor+0x124: and %i0, 0xff, %g5 crc32_update_no_xor+0x128: xor %g1, %o1, %g1 crc32_update_no_xor+0x12c: ld [%l3 + %o3], %o5 crc32_update_no_xor+0x130: add %l4, 0x8, %l4 crc32_update_no_xor+0x134: and %o4, 0xff, %g2 crc32_update_no_xor+0x138: xor %g1, %o5, %g1 crc32_update_no_xor+0x13c: add %g2, 0x500, %g4 crc32_update_no_xor+0x140: add %g5, 0x600, %o1 crc32_update_no_xor+0x144: sllx %g4, 0x2, %g3 crc32_update_no_xor+0x148: sllx %o1, 0x2, %o2 crc32_update_no_xor+0x14c: ld [%l3 + %g3], %o0 crc32_update_no_xor+0x150: ld [%l3 + %o2], %o3 crc32_update_no_xor+0x154: xor %g1, %o0, %g1 crc32_update_no_xor+0x158: cmp %i2, %l4 crc32_update_no_xor+0x15c: xor %g1, %o3, %g1 crc32_update_no_xor+0x160: bgu,pt %xcc, -0x124 <crc32_update_no_xor+0x3c> crc32_update_no_xor+0x164: srl %g1, 0x0, %i0 crc32_update_no_xor+0x168: return %i7 + 0x8 crc32_update_no_xor+0x16c: nop Solaris Studio 12.6: ==================== crc32_update_no_xor: save %sp, -0xb0, %sp crc32_update_no_xor+4: and %i2, -0x8, %l3 crc32_update_no_xor+8: cmp %g0, %l3 crc32_update_no_xor+0xc: bcc,pn %xcc, +0x1d0 <crc32_update_no_xor+0x1dc> crc32_update_no_xor+0x10: sethi %hi(0x0), %i5 crc32_update_no_xor+0x14: or %i5, 0x0, %i4 crc32_update_no_xor+0x18: sethi %hi(0xfc00), %l6 crc32_update_no_xor+0x1c: sllx %i4, 0xc, %l7 crc32_update_no_xor+0x20: sethi %hi(0x3fc00), %l5 crc32_update_no_xor+0x24: add %l6, 0x300, %g4 crc32_update_no_xor+0x28: sethi %hi(0x3fc0000), %l4 crc32_update_no_xor+0x2c: sethi %hi(0x1c00), %i3 crc32_update_no_xor+0x30: add %l7, 0x0, %l7 crc32_update_no_xor+0x34: sethi %hi(0xff000000), %l1 crc32_update_no_xor+0x38: sllx %l5, 0x16, %l6 crc32_update_no_xor+0x3c: add %l3, -0x1, %g5 crc32_update_no_xor+0x40: sllx %l4, 0x16, %l5 crc32_update_no_xor+0x44: sethi %hi(0xff0000), %g1 crc32_update_no_xor+0x48: mov 0x8, %o0 crc32_update_no_xor+0x4c: add %l7, %i3, %l2 crc32_update_no_xor+0x50: sllx %l1, 0x18, %l4 crc32_update_no_xor+0x54: sllx %l1, 0x20, %l3 crc32_update_no_xor+0x58: sethi %hi(0x1400), %l0 crc32_update_no_xor+0x5c: sethi %hi(0x1800), %i5 crc32_update_no_xor+0x60: srl %i0, 0x0, %i4 crc32_update_no_xor+0x64: ldub [%i1], %i0 crc32_update_no_xor+0x68: sethi %hi(0x1000), %o1 crc32_update_no_xor+0x6c: ldub [%i1 + 0x2], %o4 crc32_update_no_xor+0x70: cmp %o0, %g5 crc32_update_no_xor+0x74: ldub [%i1 + 0x1], %o5 crc32_update_no_xor+0x78: sllx %i0, 0x8, %o7 crc32_update_no_xor+0x7c: ldub [%i1 + 0x3], %i0 crc32_update_no_xor+0x80: ldub [%i1 + 0x4], %o2 crc32_update_no_xor+0x84: sllx %o4, 0x8, %i3 crc32_update_no_xor+0x88: or %o7, %o5, %o3 crc32_update_no_xor+0x8c: ldub [%i1 + 0x5], %o7 crc32_update_no_xor+0x90: or %i3, %i0, %o4 crc32_update_no_xor+0x94: ldub [%i1 + 0x6], %i3 crc32_update_no_xor+0x98: sllx %o3, 0x10, %o5 crc32_update_no_xor+0x9c: sllx %o2, 0x8, %i2 crc32_update_no_xor+0xa0: ldub [%i1 + 0x7], %o2 crc32_update_no_xor+0xa4: or %o5, %o4, %o3 crc32_update_no_xor+0xa8: or %i2, %o7, %i2 crc32_update_no_xor+0xac: sllx %o3, 0x20, %o4 crc32_update_no_xor+0xb0: sllx %i3, 0x8, %i0 crc32_update_no_xor+0xb4: sllx %i2, 0x10, %o7 crc32_update_no_xor+0xb8: or %i0, %o2, %o5 crc32_update_no_xor+0xbc: add %i1, 0x8, %i1 crc32_update_no_xor+0xc0: or %o7, %o5, %i3 crc32_update_no_xor+0xc4: or %o4, %i3, %o2 crc32_update_no_xor+0xc8: and %o2, 0xff, %i0 crc32_update_no_xor+0xcc: and %o2, %g4, %i2 crc32_update_no_xor+0xd0: sllx %i0, 0x38, %o7 crc32_update_no_xor+0xd4: sllx %i2, 0x28, %o3 crc32_update_no_xor+0xd8: and %o2, %g1, %o5 crc32_update_no_xor+0xdc: or %o7, %o3, %i0 crc32_update_no_xor+0xe0: sllx %o5, 0x18, %o4 crc32_update_no_xor+0xe4: and %o2, %l6, %i3 crc32_update_no_xor+0xe8: or %i0, %o4, %i2 crc32_update_no_xor+0xec: srlx %i3, 0x8, %o3 crc32_update_no_xor+0xf0: and %o2, %l5, %o7 crc32_update_no_xor+0xf4: or %i2, %o3, %o4 crc32_update_no_xor+0xf8: srlx %o7, 0x18, %o5 crc32_update_no_xor+0xfc: and %o2, %l4, %i0 crc32_update_no_xor+0x100: or %o4, %o5, %o3 crc32_update_no_xor+0x104: srlx %i0, 0x28, %i3 crc32_update_no_xor+0x108: and %o2, %l3, %o7 crc32_update_no_xor+0x10c: and %o2, %l1, %o5 crc32_update_no_xor+0x110: or %o3, %i3, %i2 crc32_update_no_xor+0x114: srlx %o7, 0x38, %o2 crc32_update_no_xor+0x118: or %i2, %o2, %i0 crc32_update_no_xor+0x11c: sllx %o5, 0x8, %o4 crc32_update_no_xor+0x120: or %i0, %o4, %i3 crc32_update_no_xor+0x124: xor %i3, %i4, %i3 crc32_update_no_xor+0x128: srlx %i3, 0x30, %i4 crc32_update_no_xor+0x12c: srlx %i3, 0x28, %o3 crc32_update_no_xor+0x130: and %i4, 0xff, %o7 crc32_update_no_xor+0x134: and %o3, 0xff, %o2 crc32_update_no_xor+0x138: sllx %o7, 0x2, %o5 crc32_update_no_xor+0x13c: srlx %i3, 0x20, %i0 crc32_update_no_xor+0x140: add %l7, %o5, %o4 crc32_update_no_xor+0x144: sllx %o2, 0x2, %i2 crc32_update_no_xor+0x148: ld [%o4 + 0x400], %o2 crc32_update_no_xor+0x14c: and %i0, 0xff, %o7 crc32_update_no_xor+0x150: srlx %i3, 0x18, %o3 crc32_update_no_xor+0x154: sllx %o7, 0x2, %o4 crc32_update_no_xor+0x158: add %l7, %i2, %i4 crc32_update_no_xor+0x15c: add %l7, %o4, %i0 crc32_update_no_xor+0x160: and %o3, 0xff, %o5 crc32_update_no_xor+0x164: ld [%i4 + 0x800], %o3 crc32_update_no_xor+0x168: ld [%i0 + 0xc00], %o7 crc32_update_no_xor+0x16c: srlx %i3, 0x10, %i2 crc32_update_no_xor+0x170: srlx %i3, 0x38, %i4 crc32_update_no_xor+0x174: srlx %i3, 0x8, %o4 crc32_update_no_xor+0x178: and %i2, 0xff, %i0 crc32_update_no_xor+0x17c: sllx %i4, 0x2, %i2 crc32_update_no_xor+0x180: and %o4, 0xff, %i4 crc32_update_no_xor+0x184: ld [%i2 + %l7], %o4 crc32_update_no_xor+0x188: sllx %o5, 0x2, %o5 crc32_update_no_xor+0x18c: sllx %i0, 0x2, %i0 crc32_update_no_xor+0x190: and %i3, 0xff, %i2 crc32_update_no_xor+0x194: sllx %i4, 0x2, %i3 crc32_update_no_xor+0x198: add %l7, %o5, %i4 crc32_update_no_xor+0x19c: add %l7, %i3, %o5 crc32_update_no_xor+0x1a0: add %l7, %i0, %i0 crc32_update_no_xor+0x1a4: ld [%i4 + %o1], %i3 crc32_update_no_xor+0x1a8: sllx %i2, 0x2, %i2 crc32_update_no_xor+0x1ac: ld [%i0 + %l0], %i0 crc32_update_no_xor+0x1b0: xor %o4, %o2, %o1 crc32_update_no_xor+0x1b4: xor %o7, %o3, %o3 crc32_update_no_xor+0x1b8: ld [%l2 + %i2], %o2 crc32_update_no_xor+0x1bc: xor %o1, %o3, %o4 crc32_update_no_xor+0x1c0: ld [%o5 + %i5], %i4 crc32_update_no_xor+0x1c4: xor %i0, %i3, %o7 crc32_update_no_xor+0x1c8: xor %o4, %o7, %i2 crc32_update_no_xor+0x1cc: xor %o2, %i4, %i3 crc32_update_no_xor+0x1d0: xor %i2, %i3, %i0 crc32_update_no_xor+0x1d4: bleu,pt %xcc, -0x174 <crc32_update_no_xor+0x60> crc32_update_no_xor+0x1d8: add %o0, 0x8, %o0 crc32_update_no_xor+0x1dc: return %i7 + 0x8 crc32_update_no_xor+0x1e0: srl %o0, 0x0, %o0