Skip to content

[MIPS] Incorrect expansion of sub-word signed atomic max #61881

@Amanieu

Description

@Amanieu

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

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions