Description
IR
define void @foo(ptr %a, i32 %x) {
%val = trunc i32 %x to i8
%1 = atomicrmw max ptr %a, i8 %val seq_cst
ret void
}
Asm (-march=mipsel
)
foo: # @foo
sync
addiu $1, $zero, -4
and $1, $4, $1
andi $2, $4, 3
sll $2, $2, 3
ori $3, $zero, 255
sllv $3, $3, $2
nor $4, $zero, $3
sllv $5, $5, $2
$BB0_1: # =>This Inner Loop Header: Depth=1
ll $7, 0($1)
and $7, $7, $3 # <== WRONG, zero-extending
and $5, $5, $3 # <== WRONG, zero-extending
slt $10, $7, $5
move $8, $7
movn $8, $5, $10
and $8, $8, $3
and $9, $7, $4
or $9, $9, $8
sc $9, 0($1)
beqz $9, $BB0_1
nop
and $6, $7, $3
srlv $6, $6, $2
sll $6, $6, 16
sra $6, $6, 16
sync
jr $ra
nop
The problem
The expansion of i8
signed atomic max masks out all bits that are not involved, but fails to sign-extend the values before passing them to slt
for a proper signed comparison.
Downstream bug: rust-lang/rust#100650
Metadata
Metadata
Assignees
Type
Projects
Status
Done