[Bug middle-end/67401] New: Incorrect expand of __atomic_compare_exchange_8 using __sync_val_compare_and_swap_8
danglin at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Aug 30 15:19:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67401
Bug ID: 67401
Summary: Incorrect expand of __atomic_compare_exchange_8 using
__sync_val_compare_and_swap_8
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: danglin at gcc dot gnu.org
Target Milestone: ---
Host: hppa-unknown-linux-gnu
Target: hppa-unknown-linux-gnu
Build: hppa-unknown-linux-gnu
Created attachment 36271
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36271&action=edit
.s file
The following testcase is incorrectly compiled on hppa-unknown-linux-gnu
if I enable support for __sync_val_compare_and_swap_8 in linux-atomic.c:
extern volatile _Atomic unsigned long long mem;
void
foo (void)
{
for (int i = 0; i < 10000; i++)
mem -= 1;
}
This hunk is wrong when the testcase is compiled at -O1:
.L4:
ldw -184(%r30),%r3
ldw -180(%r30),%r4
addi -1,%r4,%r29
subb %r3,%r0,%r28
stw %r28,0(%r6)
stw %r29,4(%r6)
copy %r3,%r23
copy %r4,%r24
bl __sync_val_compare_and_swap_8,%r2
copy %r5,%r26
copy %r3,%r23
copy %r4,%r24
copy %r28,%r25
copy %r29,%r26
bl __ucmpdi2,%r2
nop
comiclr,<> 1,%r28,%r19
ldi 1,%r19
comiclr,= 0,%r19,%r0
b,n .L3
stw %r28,-184(%r30)
stw %r29,-180(%r30)
.L3:
The call to __ucmpdi2 clobbers register %r28. This is the most significant
half of the DImode value returned by __sync_val_compare_and_swap_8. As
a result, the store "stw %r28,-184(%r30)" results in the wrong value being
passed to __sync_val_compare_and_swap_8 on the next iteration.
I think the return value from __sync_val_compare_and_swap_8 should be copied
to a pseudo to prevent this from happening.
I'm not sure why __ucmpdi2is used here. Usually, DImode compare operations
are done inline without using a libcall. This pessimizes the code.
More information about the Gcc-bugs
mailing list