lkml.org 
[lkml]   [2020]   [Jul]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v3 11/11] x86: support i386 with Clang
    From
    GCC and Clang are architecturally different, which leads to subtle
    issues for code that's invalid but clearly dead. This can happen with
    code that emulates polymorphism with the preprocessor and sizeof.

    GCC will perform semantic analysis after early inlining and dead code
    elimination, so it will not warn on invalid code that's dead. Clang
    strictly performs optimizations after semantic analysis, so it will warn
    for dead code.

    Neither Clang nor GCC like this very much with -m32:

    long long ret;
    asm ("movb $5, %0" : "=q" (ret));

    However, GCC can tolerate this variant:

    long long ret;
    switch (sizeof(ret)) {
    case 1:
    asm ("movb $5, %0" : "=q" (ret));
    break;
    case 8:;
    }

    Clang, on the other hand, won't accept that because it validates the
    inline asm for the '1' case *before* the optimisation phase where it
    realises that it wouldn't have to emit it anyway.

    If LLVM (Clang's "back end") fails such as during instruction selection
    or register allocation, it cannot provide accurate diagnostics
    (warnings/errors) that contain line information, as the AST has been
    discarded from memory at that point.

    While there have been early discussions about having C/C++ specific
    language optimizations in Clang via the use of MLIR, which would enable
    such earlier optimizations, such work is not scoped and likely a
    multi-year endeavor.

    We also don't want to swap the use of "=q" with "=r". For 64b, it
    doesn't matter. For 32b, it's possible that a 32b register without a 8b
    lower alias (i.e. ESI, EDI, EBP) is selected which the assembler will
    then reject.

    With this, Clang can finally build an i386 defconfig.

    Link: https://bugs.llvm.org/show_bug.cgi?id=33587
    Link: https://github.com/ClangBuiltLinux/linux/issues/3
    Link: https://github.com/ClangBuiltLinux/linux/issues/194
    Link: https://github.com/ClangBuiltLinux/linux/issues/781
    Link: https://lore.kernel.org/lkml/20180209161833.4605-1-dwmw2@infradead.org/
    Link: https://lore.kernel.org/lkml/CAK8P3a1EBaWdbAEzirFDSgHVJMtWjuNt2HGG8z+vpXeNHwETFQ@mail.gmail.com/
    Reported-by: Arnd Bergmann <arnd@arndb.de>
    Reported-by: David Woodhouse <dwmw2@infradead.org>
    Reported-by: Dmitry Golovin <dima@golovin.in>
    Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
    Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Nick Desaulniers <ndesaulniers@google.com>
    ---
    arch/x86/include/asm/uaccess.h | 4 +++-
    1 file changed, 3 insertions(+), 1 deletion(-)

    diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
    index dd3261f9f4ea..9d57556ad42f 100644
    --- a/arch/x86/include/asm/uaccess.h
    +++ b/arch/x86/include/asm/uaccess.h
    @@ -314,11 +314,13 @@ do { \

    #define __get_user_size(x, ptr, size, retval) \
    do { \
    + unsigned char x_u8__; \
    retval = 0; \
    __chk_user_ptr(ptr); \
    switch (size) { \
    case 1: \
    - __get_user_asm(x, ptr, retval, "b", "=q"); \
    + __get_user_asm(x_u8__, ptr, retval, "b", "=q"); \
    + (x) = x_u8__; \
    break; \
    case 2: \
    __get_user_asm(x, ptr, retval, "w", "=r"); \
    --
    2.28.0.rc0.105.gf9edc3c819-goog
    \
     
     \ /
      Last update: 2020-07-20 22:51    [W:4.097 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site