Bug 106818

Summary: pixman: combiner-test, gradient-crash-test, and stress-test fail when compiled with clang
Product: pixman Reporter: Matt Turner <mattst88>
Component: pixmanAssignee: Matt Turner <mattst88>
Status: RESOLVED MOVED QA Contact:
Severity: normal    
Priority: medium CC: civil.over
Version: git master   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Matt Turner 2018-06-04 20:44:36 UTC
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"
Comment 1 Vladimir 2018-06-04 20:55:28 UTC
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.
Comment 2 GitLab Migration User 2018-06-05 15:28:12 UTC
-- 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.