While test-building random linux kernel configurations, I can across an assembler error message: /tmp/mISDNisar-1df18c.s: Assembler messages: /tmp/mISDNisar-1df18c.s:8151: Error: branch must be last instruction in IT block -- `blne _test_and_set_bit' I reduced the test case to: $ cat mISDNisar.c long modeisar_ch_0_1; int modeisar_ch_0_2, modeisar_bprotocol; void fn1() { if (modeisar_ch_0_2) switch (modeisar_bprotocol) case 33: case 34: if (modeisar_bprotocol == 34) fn2(3, &modeisar_ch_0_1); else fn2(2, &modeisar_ch_0_1); _Bool branch; int *key = 0; asm goto("" ::"i"(&key[branch])::l_yes); l_yes:; } $ clang-9 --target=arm-linux-gnueabi -fsanitize-coverage=trace-pc -no-integrated-as -march=armv7-a -mthumb -c -O2 mISDNisar.c -Wno-implicit-function-declaration /tmp/mISDNisar-e138de.s: Assembler messages: /tmp/mISDNisar-e138de.s:55: Error: branch must be last instruction in IT block -- `blne fn2' clang: error: assembler command failed with exit code 1 (use -v to see invocation) $ clang-9 --version clang version 9.0.0-svn369744-1~exp1~20190823103928.28 (branches/release_90) Assembler output without -no-integrated-as is $ objdump -d mISDNisar.o 00000000 <fn1>: 0: b5d0 push {r4, r6, r7, lr} 2: af02 add r7, sp, #8 4: f7ff fffe bl 0 <__sanitizer_cov_trace_pc> 8: f240 0000 movw r0, #0 c: f2c0 0000 movt r0, #0 10: 6800 ldr r0, [r0, #0] 12: b1b8 cbz r0, 44 <fn1+0x44> 14: f240 0000 movw r0, #0 18: f2c0 0000 movt r0, #0 1c: 6804 ldr r4, [r0, #0] 1e: f1a4 0021 sub.w r0, r4, #33 ; 0x21 22: 2802 cmp r0, #2 24: d211 bcs.n 4a <fn1+0x4a> 26: f7ff fffe bl 0 <__sanitizer_cov_trace_pc> 2a: f240 0100 movw r1, #0 2e: 2c22 cmp r4, #34 ; 0x22 30: f2c0 0100 movt r1, #0 34: bf1a itte ne 36: 2002 movne r0, #2 38: f7ff fffe blne 0 <fn2> ; unpredictable branch in IT block 3c: 2003 moveq r0, #3 3e: f7ff fffe bl 0 <fn2> 42: e005 b.n e <__sanitizer_cov_trace_pc+0xe> 44: f7ff fffe bl 0 <__sanitizer_cov_trace_pc> 48: e002 b.n 8 <__sanitizer_cov_trace_pc+0x8> 4a: f7ff fffe bl 0 <__sanitizer_cov_trace_pc> 4e: e7ff b.n 2 <__sanitizer_cov_trace_pc+0x2> 50: f7ff fffe bl 0 <__sanitizer_cov_trace_pc> 54: bdd0 pop {r4, r6, r7, pc}
I briefly looked at the -print-after-all output; looks like a bug in if conversion. It's performing an illegal conversion. Not in the sense of being UNPREDICTABLE; we don't generate it blocks until later. The immediate issue in the if conversion stage is that the call clobbers cpsr. There's also arguably a bug in the it instruction generation, I guess, but I'm not sure how you would reproduce it for otherwise legal code. The testcase crashes the compiler if you specify -marm; I think we have a bug for that already, though.
Oh, actually, I remember the ARM bug now (Bug 41121); this is probably a duplicate.
I'm working on a fix.
r371111.
(In reply to Eli Friedman from comment #4) > r371111. Merged to release_90 in r371377.