Skip to content

Instantly share code, notes, and snippets.

@twonoise
Last active May 15, 2026 11:41
Show Gist options
  • Select an option

  • Save twonoise/940c979ad3d0d9fc59fdefa5edd82a08 to your computer and use it in GitHub Desktop.

Select an option

Save twonoise/940c979ad3d0d9fc59fdefa5edd82a08 to your computer and use it in GitHub Desktop.
8-bit math using -O3, compared to -O2, gives different results.
/* 8-bit math using -O3, compared to -O2, gives different results.
* Using both `gcc` and `clang` and both -Ox, i've see three (four)
* different values. Which one is correct?
*
* NOTE code is extremely fragile: Even uncomment printf()
* below, hides the "bug", makes all results same. Same is when
* trying shrink the code even a bit.
*
* gcc -O2 ./test_uint8.c # prints ... ffffd565
* gcc -O3 ./test_uint8.c # prints ... ff80d565
* clang -O2 ./test_uint8.c # prints ... ffffd565
* clang -O3 ./test_uint8.c # prints ... ff01d765
* or ff81d765, depends if printf() is uncommented.
*
* gcc (GCC) 16.1.1 20260430, clang version 22.1.5, Archlinux x86_64
*
* By jpka, 2026. Std: C99. License: GPL 2+ */
#include <stdio.h>
#include <stdint.h>
#include "sys/param.h" /* MIN(), MAX() */
#define MSG(S,...) if (v) printf(S"\n", ##__VA_ARGS__);
int w = 0;
int v = 2;
uint16_t foo (uint8_t n, uint8_t h)
{
uint32_t result = (n * 255 + (h-1) * 12) % (12*255);
return (uint16_t) result;
}
void func(uint8_t a, uint8_t h, uint8_t s, uint8_t l)
{
if (h == 0)
s = 0;
if (w & 128)
l = 255 - l;
uint16_t A = (s * MIN(l, 255 - l) * 259) >> 8;
uint32_t r0 = ((l * (257*255) - A * MAX(MIN(MIN(foo(0, h) - 3*255, 9*255 - foo(0, h)), 255), -255)) * a / (255*255*255));
uint32_t r8 = ((l * (257*255) - A * MAX(MIN(MIN(foo(8, h) - 3*255, 9*255 - foo(8, h)), 255), -255)) * a / (255*255*255));
uint32_t r4 = ((l * (257*255) - A * MAX(MIN(MIN(foo(4, h) - 3*255, 9*255 - foo(4, h)), 255), -255)) * a / (255*255*255));
uint32_t result = (((((a << 8) + (uint8_t)r0) << 8) + (uint8_t)r8) << 8) + (uint8_t)r4;
MSG("%d, %x %x %x %x, %d %d %d %d, %x", !!(w & 128), a, h, s, l, A, r0, r8, r4, result);
/* printf("%d %d %d %d %x\n", A, r0, r8, r4, result); */
}
int main(void)
{
uint8_t a = 0xff;
uint8_t h = 0x20;
uint8_t s = 0xff;
uint8_t l = 0xb2;
func(a, h, s, l);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment