Skip to content

Instantly share code, notes, and snippets.

@osy
Created May 29, 2023 04:20
Show Gist options
  • Save osy/107b6d067673713ca50031300091df80 to your computer and use it in GitHub Desktop.
Save osy/107b6d067673713ca50031300091df80 to your computer and use it in GitHub Desktop.
Compiler bug
// xcrun clang -O2 -o test test.c
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
static inline uint64_t usub64_borrow_1(uint64_t x, uint64_t y, bool *pborrow)
{
unsigned long long b = *pborrow;
x = __builtin_subcll(x, y, b, &b);
*pborrow = b & 1;
return x;
}
static inline uint64_t usub64_borrow_2(uint64_t x, uint64_t y, bool *pborrow)
{
bool b = *pborrow;
b = __builtin_sub_overflow(x, b, &x);
b |= __builtin_sub_overflow(x, y, &x);
*pborrow = b;
return x;
}
static inline void sub192_1(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t b0, uint64_t b1, uint64_t b2,
uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr)
{
bool c = 0;
*z2Ptr = usub64_borrow_1(a2, b2, &c);
*z1Ptr = usub64_borrow_1(a1, b1, &c);
*z0Ptr = usub64_borrow_1(a0, b0, &c);
}
static inline void sub192_2(uint64_t a0, uint64_t a1, uint64_t a2,
uint64_t b0, uint64_t b1, uint64_t b2,
uint64_t *z0Ptr, uint64_t *z1Ptr, uint64_t *z2Ptr)
{
bool c = 0;
*z2Ptr = usub64_borrow_2(a2, b2, &c);
*z1Ptr = usub64_borrow_2(a1, b1, &c);
*z0Ptr = usub64_borrow_2(a0, b0, &c);
}
void __attribute__((noinline)) test(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t b0, uint64_t b1, uint64_t b2, uint64_t *c0, uint64_t *c1, uint64_t *c2) {
sub192_2(a0, a1, a2, b0, b1, b2, c0, c1, c2);
printf("A0 = 0x%016llX, A1 = 0x%016llX, A2 = 0x%016llX, B0 = 0x%016llX, B1 = 0x%016llX, B2 = 0x%016llX, C0 = 0x%016llX, C1 = 0x%016llX, C2 = 0x%016llX\n", a0, a1, a2, b0, b1, b2, *c0, *c1, *c2);
sub192_1(a0, a1, a2, b0, b1, b2, c0, c1, c2);
printf("A0 = 0x%016llX, A1 = 0x%016llX, A2 = 0x%016llX, B0 = 0x%016llX, B1 = 0x%016llX, B2 = 0x%016llX, C0 = 0x%016llX, C1 = 0x%016llX, C2 = 0x%016llX\n", a0, a1, a2, b0, b1, b2, *c0, *c1, *c2);
}
int main(int argc, const char *argv[]) {
uint64_t c0, c1, c2;
test(0x8000000000000000, 0x0000000000000000, 0x0000000000000000, 0x7FFFFFFFFFFFFFFF, 0xE000000000000000, 0x0000000000000000, &c0, &c1, &c2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment