Last active
May 15, 2026 11:41
-
-
Save twonoise/940c979ad3d0d9fc59fdefa5edd82a08 to your computer and use it in GitHub Desktop.
8-bit math using -O3, compared to -O2, gives different results.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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