Issue 204270
Summary [ARM] __builtin_subc() does not generate SBC instruction
Labels
Assignees
Reporter calc84maniac
    On 32-bit ARM, `__builtin_addc()` works to generate ADC, but `__builtin_subc()` appears to always perform two integer subtractions. I found an open PR that seems to address a similar optimization issue, though I'm not sure if it directly fixes this: https://github.com/llvm/llvm-project/pull/184021 

https://godbolt.org/z/MYdMY85TK

```c
unsigned long long add64(unsigned x0, unsigned x1, unsigned y0, unsigned y1)
{
    unsigned carry = 0;
    x0 = __builtin_addc(x0, y0, carry, &carry);
    x1 = __builtin_addc(x1, y1, carry, &carry);
    return (unsigned long long)x1 << 32 | x0;
}

unsigned long long sub64(unsigned x0, unsigned x1, unsigned y0, unsigned y1)
{
    unsigned carry = 0;
    x0 = __builtin_subc(x0, y0, carry, &carry);
    x1 = __builtin_subc(x1, y1, carry, &carry);
    return (unsigned long long)x1 << 32 | x0;
}
```

```gas
add64:
        adds r0, r0, r2
        adc     r1, r3, r1
        bx      lr

sub64:
 sub     r1, r1, r3
        mov     r3, #0
        subs    r0, r0, r2
 adc     r2, r3, #0
        eor     r2, r2, #1
        sub     r1, r1, r2
        bx      lr
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to