https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125628
Bug ID: 125628
Summary: mips64el: wrong code for stdatomic-op-1.c with -O
-march=mips64r2
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: xry111 at gcc dot gnu.org
Target Milestone: ---
Simplified from stdatomic-op-1.c:
#include <stdatomic.h>
extern void abort (void);
_Atomic char v = 1;
void
test_fetch_add ()
{
if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
abort ();
}
int
main ()
{
test_fetch_add ();
return 0;
}
aborts. The assembly reads:
test_fetch_add:
.frame $sp,16,$31 # vars= 0, regs= 2/0, args= 0, gp= 0
.mask 0x90000000,-8
.fmask 0x00000000,0
daddiu $sp,$sp,-16
sd $31,8($sp)
sd $28,0($sp)
lui $28,%hi(%neg(%gp_rel(test_fetch_add)))
daddu $28,$28,$25
daddiu $28,$28,%lo(%neg(%gp_rel(test_fetch_add)))
dla $2,v
li $5,-4 # 0xfffffffffffffffc
and $5,$2,$5
andi $2,$2,0x3
dsll $2,$2,3
li $4,255 # 0xff
sll $4,$4,$2
nor $7,$0,$4
li $6,1
sll $6,$6,$2
.set noreorder
.set nomacro
.set noat
sync
1:
ll $3,0($5)
and $1,$3,$7
and $8,$3,$6
xor $8,$8,$4
or $1,$1,$8
sc $1,0($5)
beq $1,$0,1b
nop
sync
.set at
.set macro
.set reorder
and $3,$3,$4
srl $3,$3,$2
andi $3,$3,0x00ff
bne $3,$0,.L5
sync
dla $2,v
lbu $2,0($2)
sync
andi $2,$2,0x00ff
li $3,1 # 0x1
bne $2,$3,.L6
ld $31,8($sp)
ld $28,0($sp)
.set noreorder
.set nomacro
j $31
daddiu $sp,$sp,16
.set macro
.set reorder
.L5:
jal abort
.L6:
jal abort
And it writes -1 into v. I cannot figure out any sense from the assembly.