chfast / intx

Extended precision integer C++ library
Apache License 2.0
129 stars 29 forks source link

Unit tests fail with Xcode 14.3 on Apple silicon #292

Closed yperbasis closed 1 year ago

yperbasis commented 1 year ago

Environement

Apple M1, Apple clang version 14.0.3 (clang-1403.0.22.14.1), macOS 13.4 (22F66)

Steps to reproduce

cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --parallel build/test/intx-unittests

Output

out.txt [ FAILED ] 8 tests, listed below: [ FAILED ] uint_test/uint192.comparison, where TypeParam = intx::uint<192u> [ FAILED ] uint_test/uint384.comparison, where TypeParam = intx::uint<384u> [ FAILED ] uint_test/uint512.comparison, where TypeParam = intx::uint<512u> [ FAILED ] uint256.arithmetic [ FAILED ] uint256.addmod [ FAILED ] uint256.addmod_ec1 [ FAILED ] uint256.addmod_ec2 [ FAILED ] Uint256Test.add_against_sub

aarlt commented 1 year ago

I just noticed that the unit-tests are just not working for release builds.

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
build/test/intx-unittests

If a non-release build is done (e.g. not defining -DCMAKE_BUILD_TYPE=Release) all unit-tests can be executed successfuly.

chfast commented 1 year ago

This is the repro. Can someone built it with XCode 14.3.1 with -O3 and send us the assembly (-S)?

using u64 = unsigned long long;

[[gnu::noinline]] static auto neg(const u64 y[3])
{
    u64 k = 0;
    __builtin_subcll(0, y[0], k, &k);
    __builtin_subcll(0, y[1], k, &k);
    return __builtin_subcll(0, y[2], k, &k);
}

int main()
{
    const u64 y[] = {1, 0, 0};
    if (neg(y) != ~u64(0))
        return 1;
    return 0;
}

https://godbolt.org/z/fE97oEhfP

aarlt commented 1 year ago

I just saw this. I used Apple clang version 14.0.3 (clang-1403.0.22.14.1) (this seem to be the version that was bundled with Xcode 14.3.1) I compiled it with clang bla.cpp -std=c++14 -O3 -S. Assembly output:

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 13, 0 sdk_version 13, 3
    .globl  _main                           ; -- Begin function main
    .p2align    2
_main:                                  ; @main
    .cfi_startproc
; %bb.0:
    stp x29, x30, [sp, #-16]!           ; 16-byte Folded Spill
    .cfi_def_cfa_offset 16
    mov x29, sp
    .cfi_def_cfa w29, 16
    .cfi_offset w30, -8
    .cfi_offset w29, -16
Lloh0:
    adrp    x0, l___const.main.y@PAGE
Lloh1:
    add x0, x0, l___const.main.y@PAGEOFF
    bl  __ZL3negPKy
    cmn x0, #1
    cset    w0, ne
    ldp x29, x30, [sp], #16             ; 16-byte Folded Reload
    ret
    .loh AdrpAdd    Lloh0, Lloh1
    .cfi_endproc
                                        ; -- End function
    .p2align    2                               ; -- Begin function _ZL3negPKy
__ZL3negPKy:                            ; @_ZL3negPKy
    .cfi_startproc
; %bb.0:
    ldp x8, x9, [x0]
    cmp xzr, x8
    ngcs    xzr, x9
    cset    w8, hs
    sbfx    x8, x8, #0, #1
    ldr x9, [x0, #16]
    sub x0, x8, x9
    ret
    .cfi_endproc
                                        ; -- End function
    .section    __TEXT,__const
    .p2align    3                               ; @__const.main.y
l___const.main.y:
    .quad   1                               ; 0x1
    .quad   0                               ; 0x0
    .quad   0                               ; 0x0

.subsections_via_symbols
chfast commented 1 year ago

Thanks @aarlt. To confirm, does this program return 1?

chfast commented 1 year ago

Wrong assembly:

    ldp x8, x9, [x0]
    cmp xzr, x8
    ngcs    xzr, x9
    cset    w8, hs
    sbfx    x8, x8, #0, #1
    ldr x9, [x0, #16]
    sub x0, x8, x9
    ret

Correct assembly from later XCode:

    ldp x8, x9, [x0]
    orr x8, x9, x8
    cmp x8, #0
    csetm   x8, ne
    ldr x9, [x0, #16]
    sub x0, x8, x9
    ret
aarlt commented 1 year ago

Thanks @aarlt. To confirm, does this program return 1?

yep it returns 1.

chfast commented 1 year ago

Fixed in #294. Released in https://github.com/chfast/intx/releases/tag/v0.10.1.