Skip to content

[ARM] Incorrect calling convention when invoking __sync builtins #61880

@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

foo:
        push    {r11, lr}
        bl      __sync_fetch_and_max_1
        pop     {r11, lr}
        mov     pc, lr

The problem

The ARM calling convention specified that integers smaller than the word size need to be sign/zero-extended to the word size. __sync_fetch_and_max_1 expects a signed i8 for its second argument, which should be in sign-extended form. However LLVM isn't performing a sign-extension for this parameter, which leads to issues such as rust-lang/rust#100650.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions