Skip to main content
Fixed subtle program error
Source Link
CPlus
  • 948
  • 5
  • 26
_Static_assert(~0==-1, "Unsupported sign representation");
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1b&2) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        const int n = a < 0; // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
        i.a[1] = i.a[0] = (Short2){.a = {a-n, a-n}};
        i.i += n;
        if ((uintptr_t)b&2b&4) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
_Static_assert(~0==-1, "Unsupported sign representation");
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        const int n = a < 0; // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
        i.a[1] = i.a[0] = (Short2){.a = {a-n, a-n}};
        i.i += n;
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
_Static_assert(~0==-1, "Unsupported sign representation");
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&2) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        const int n = a < 0; // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
        i.a[1] = i.a[0] = (Short2){.a = {a-n, a-n}};
        i.i += n;
        if ((uintptr_t)b&4) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
Branchless hack; 2's Complement assertion
Source Link
CPlus
  • 948
  • 5
  • 26
_Static_assert(~0==-1, "Unsupported sign representation");
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        ifconst (int n = a < 0) {0; // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
            i.a[1] = i.a[0] = (Short2){.a = {-a-n, -a-n}};
            i.i = -i.i;
        } else
            i.a[1] = i.a[0] = (Short2){.a = {a, a}}; // Concatenate 4 copies of `a`+= togethern;
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        if (a < 0) { // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
            i.a[1] = i.a[0] = (Short2){.a = {-a, -a}};
            i.i = -i.i;
        } else
            i.a[1] = i.a[0] = (Short2){.a = {a, a}}; // Concatenate 4 copies of `a` together
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
_Static_assert(~0==-1, "Unsupported sign representation");
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        const int n = a < 0; // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
        i.a[1] = i.a[0] = (Short2){.a = {a-n, a-n}};
        i.i += n;
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
Bugfix
Source Link
CPlus
  • 948
  • 5
  • 26
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        if (a < 0) { // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
            i.a[1] = i.a[0] = (Short2){.a = {-a, -a}};
            i.i = -i.i;
        } else
            i.a[1] = i.a[0] = (Short2){.a = {a, a}}; // Concatenate 4 copies of `a` together
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        i.a[1] = i.a[0] = (Short2){.a = {a, a}}; // Concatenate 4 copies of `a` together
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
#include <stdint.h>
#include <stddef.h>
typedef union Short2 {
    int16_t a[2];
    int32_t i;
} Short2;
typedef union Short4 {
    Short2 a[2];
    int64_t i;
} Short4;
void add16(int16_t *b, const int16_t a, size_t c) {
    // c == 0 causes unpredictable behavior
    if ((uintptr_t)b&1) { // Handle first element if unaligned; remaining elements will be 4 byte aligned
        *b++ += a;
        --c;
    }
    if (c >= 2) {
        Short4 i;
        if (a < 0) { // If `a` < 0, simply concatenating 4 copies together leads to unexpected results; the positive version must be copied and concatenated instead, and the resulting 64 bit word negated
            i.a[1] = i.a[0] = (Short2){.a = {-a, -a}};
            i.i = -i.i;
        } else
            i.a[1] = i.a[0] = (Short2){.a = {a, a}}; // Concatenate 4 copies of `a` together
        if ((uintptr_t)b&2) { // Handle next pair of elements if unaligned; remaining elements will be 8 byte aligned
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
            c -= 2;
        }
        while (c >= 4) { // Handle all remaining complete batches of 4 elements
            (*(Short4 *)b).i += i.i;
            b += 4;
            c -= 4;
        }
        if (c&2) { // Handle remaining pair of 2 elements if needed
            (*(Short2 *)b).i += i.a[0].i;
            b += 2;
        }
    }
    if (c&1) // Handle remaining element if needed
        *b += a;
}
Added comments
Source Link
CPlus
  • 948
  • 5
  • 26
Loading
I have already improved upon the code myself; The older version no longer needs review
Source Link
CPlus
  • 948
  • 5
  • 26
Loading
Source Link
CPlus
  • 948
  • 5
  • 26
Loading