The combiner-test, gradient-crash-test, and stress-test tests fail when pixman is built with clang. Tested clang 5 and 6. Building with -O2 leads to the failure, but -O1 or less does not. -fsanitize=undefined causes the tests to pass (as does -fsanitize=alignment and -fsanitize=object-size) mattst88@p50-ethernet pixman % libtool --mode=execute gdb -q ./test/combiner-test Reading symbols from /home/mattst88/projects/pixman/test/.libs/combiner-test...done. (gdb) r Starting program: /home/mattst88/projects/pixman/test/.libs/combiner-test [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Program received signal SIGFPE, Arithmetic exception. 0x00007ffff7b519d4 in get_factor (factor=<optimized out>, sa=<optimized out>, da=<optimized out>) at pixman-combine-float.c:228 228 f = CLAMP ((1.0f - da) / sa); (gdb) l 223 224 case INV_DA_OVER_SA: 225 if (FLOAT_IS_ZERO (sa)) 226 f = 1.0f; 227 else 228 f = CLAMP ((1.0f - da) / sa); 229 break; 230 231 case ONE_MINUS_SA_OVER_DA: 232 if (FLOAT_IS_ZERO (da)) (gdb) p sa $1 = <optimized out> (gdb) display/i $pc 1: x/i $pc => 0x7ffff7b519d4 <combine_saturate_ca_float+1012>: divps %xmm11,%xmm14 (gdb) i r xmm11 xmm11 {v4_float = {0x64c90000, 0x0, 0xfed7738c, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x48, 0x26, 0x93, 0x51, 0xfc, 0x19, 0x36, 0x16, 0x3a, 0x46, 0x94, 0xcb, 0x0, 0x0, 0x0, 0x80}, v8_int16 = { 0x2648, 0x5193, 0x19fc, 0x1636, 0x463a, 0xcb94, 0x0, 0x8000}, v4_int32 = {0x51932648, 0x163619fc, 0xcb94463a, 0x80000000}, v2_int64 = {0x163619fc51932648, 0x80000000cb94463a}, uint128 = 0x80000000cb94463a163619fc51932648} (gdb) i r xmm14 xmm14 {v4_float = {0xfffffff4, 0x45a40000, 0x1, 0xc23f0800}, v2_double = {0x8000000000000000, 0x8000000000000000}, v16_int8 = {0x20, 0x36, 0x4a, 0xc1, 0x69, 0x11, 0x3d, 0x54, 0x0, 0x0, 0x80, 0x3f, 0xe0, 0x3, 0x77, 0xce}, v8_int16 = {0x3620, 0xc14a, 0x1169, 0x543d, 0x0, 0x3f80, 0x3e0, 0xce77}, v4_int32 = {0xc14a3620, 0x543d1169, 0x3f800000, 0xce7703e0}, v2_int64 = {0x543d1169c14a3620, 0xce7703e03f800000}, uint128 = 0xce7703e03f800000543d1169c14a3620} Looks like we're dividing by zero. Civil notes in a message on the pixman mailing list that: 1. It doesn't happen on -O1 level of optimization 2. It doesn't happen with "-O2 -fno-vectorize" 3. It doesn't happen with "-O0 -fvectorize" 4. It happens with "-O1 -fvectorize"
It happens in various functions and it seems that clang's optimizer just decides that 'sa' can be safely optimized out if vectorization is used. Another workaround is to wrap all variables in those functions as 'volatile'. Though I don't have a lot of experience with C, so for me it is hard to track the call-stack, so I can't create a minimal example to validate if it's clang's bug or that's actually something else that just makes clang think that it can optimize-out some variables.
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/pixman/pixman/issues/22.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.