Linux: clang validates extended assembly constraints even when -fno-integrated-as is set

Created on 19 Mar 2018  路  15Comments  路  Source: ClangBuiltLinux/linux

upstream bug: https://bugs.llvm.org/show_bug.cgi?id=33587

TL;DR

Clang will validate extended inline assembly, even if the code gets compiled out. This conflicts with some macros that involve switching on the sizeof a type.

The validity check is done early in the front-end partly because the backend (as it stands today) cannot handle inline-asm instructions that have constraints that are not valid for the input or output operands

[ARCH] x86 [BUG] llvm known difference wontfix

Most helpful comment

All 15 comments

With patches from I was able to build a Linux v4.18-rc6 kernel.

These are the relevant patches:
locking/atomics: Instrument cmpxchg_double()
locking/atomics: Instrument xchg()
locking/atomics: Simplify cmpxchg() instrumentation
locking/atomics/x86: Reduce arch_cmpxchg64
() instrumentation

Unfortunately, the generated linux-kernel does not boot on bare due to issue #7 "__builtin_constant_p() does not work in deep inline functions". I have set CONFIG_HARDENED_USERCOPY=y.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/log/?h=locking/core

Once they land upstream, I can send them to stable (we're going to support LTS branches back to 4.4, so 4.17, 4.14, 4.9, and 4.4).

The patches are now in upstream (will be in v4.19-rc1).

Thanks for the heads up @dileks ! :cake: Let me see how much work these are to backport to stable (seems like there weren't marked for inclusion into stable).

commit 4d2b25f630c7 ("locking/atomics: Instrument cmpxchg_double()")
commit f9881cc43b11 ("locking/atomics: Instrument xchg()")
commit df79ed2c0643 ("locking/atomics: Simplify cmpxchg() instrumentation")
commit 00d5551cc4ee ("locking/atomics/x86: Reduce arch_cmpxchg64
() instrumentation")

The backport work is worth for 4.17 and 4.18 as these have:
b06ed71a624b locking/atomic, asm-generic: Add asm-generic/atomic-instrumented.h

$ git describe --contains b06ed71a624b
v4.17-rc1~180^2~9

This is an issue for _static_cpu_has, arch_static_branch, arch_static_branch_jump, static_key_false, static_key_true, and perf_sw_event (at least for x86_64). The first 3 use the i inline asm constraint with __attribute__((always_inline)) which ends up producing functions that are literally invalid until inlining occurs, meaning they can only compile with gcc -O2 and will fail with gcc -O0. Clang highlights this and refuses to compile these functions, unless I change them and their __always_inline callsites to all be macros.

I should have posted this on the upstream bug sooner, but I think disabling these diagnostics in Clang when using -fno-integrated-as is the way to go: https://bugs.llvm.org/show_bug.cgi?id=33587#c21

Happy birthday #3! What is the current situation with this issue?

NetBSD folks just filed https://bugs.llvm.org/show_bug.cgi?id=41027. I think the delayed diags wait until after DCE to emit, which is maybe a solution here.

I think this might be another solution/closely related bug: https://bugs.llvm.org/show_bug.cgi?id=41027

Still occurs on kernel 5.3.1 compiled on LLVM/clang-9.0.0 on i686

  CC      arch/x86/events/amd/core.o
BUILDSTDERR: In file included from arch/x86/events/amd/core.c:11:
BUILDSTDERR: arch/x86/events/amd/../perf_event.h:824:21: error: invalid output size for constraint '=q'
BUILDSTDERR:         u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);

Let's limit this issue's scope to only llvm side and reopen #194 to track linux patches.

GCC early inlining + DCE may not perform semantic analysis on dead code, where as Clang will.

Was this page helpful?
0 / 5 - 0 ratings