pixman: combiner-test, gradient-crash-test, and stress-test fail when compiled with clang
@mattst88
Submitted by Matt Turner Assigned to Matt Turner @mattst88
Link to original bug (#106818)
Description
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:
- It doesn't happen on -O1 level of optimization
- It doesn't happen with "-O2 -fno-vectorize"
- It doesn't happen with "-O0 -fvectorize"
- It happens with "-O1 -fvectorize"
Version: git master