ClangBuiltLinux / linux

Linux kernel source tree
Other
242 stars 14 forks source link

inline assembly requires more registers than available #1589

Open nickdesaulniers opened 2 years ago

nickdesaulniers commented 2 years ago

reported by @arndb in this thread. Forking from #1483 which I've modified to track the objtool warnings.

This is reproducible via:

$ make LLVM=1 -j72 defconfig
$ ./scripts/config -d GENERIC_CPU -e MATOM -e CRYPTO_CURVE25519_X86
$ make LLVM=1 -j72 arch/x86/crypto/curve25519-x86_64.o
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
                "  movq 0(%0), %%rdx;" /* f[0] */
                ^
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
arch/x86/crypto/curve25519-x86_64.c:676:3: error: inline assembly requires more registers than available
nickdesaulniers commented 2 years ago

upstream report from @arndb

nickdesaulniers commented 2 years ago

KernelCI is also reporting this for:

$ ARCH=i386 make LLVM=1 -j72 allmodconfig net/netfilter/nf_synproxy_core.o

  CC [M]  net/netfilter/nf_synproxy_core.o
In file included from net/netfilter/nf_synproxy_core.c:7:
In file included from ./include/linux/skbuff.h:28:
In file included from ./include/net/checksum.h:22:
In file included from ./arch/x86/include/asm/checksum.h:6:
./arch/x86/include/asm/checksum_32.h:149:6: error: inline assembly requires more registers than available
        asm("addl 0(%1), %0     ;\n"
            ^
nathanchance commented 2 years ago

FWIW, I opened an issue for that specific instance in #1442, although the title could have probably been more descriptive about the error. Should I dupe that one to here?

nickdesaulniers commented 2 years ago

I'm not sure yet that it's the same cause. Let's keep them open for now, then dup once we have fixes.

nickdesaulniers commented 2 years ago

Retesting w/ clang-15 now that https://github.com/llvm/llvm-project/issues/41914 is closed out by https://github.com/llvm/llvm-project/commit/18fd09ab64b07c45d0373307e37f7c96b3984183.

My initial test case is still reproducible. :(

1442 is no longer reproducible, so indeed slightly different issues. I wonder if Atom's scheduling model has the same issue?

nickdesaulniers commented 2 years ago

I wonder if Atom's scheduling model has the same issue?

No.

https://github.com/llvm/llvm-project/blob/eb3136f022b3e5061fe790e7886f4bb592d8a1d1/llvm/lib/Target/X86/X86ScheduleAtom.td#L178

nathanchance commented 2 years ago

There was another report recently of this issue that appears to only be visible under full LTO. It is easily reproducible with i386_defconfig + CONFIG_LTO_CLANG_FULL=y + CONFIG_X86_GENERIC=y (which adds -mtune=generic)

$ make -skj"$(nproc)" ARCH=i386 LLVM=1 mrproper defconfig

$ scripts/config -d LTO_NONE -e LTO_CLANG_FULL -e X86_GENERIC

$ make -skj"$(nproc)" ARCH=i386 LLVM=1 olddefconfig all
ld.lld: error: inline assembly requires more registers than available at line 538
ld.lld: error: inline assembly requires more registers than available at line 538
...

My toolchain has https://github.com/llvm/llvm-project/commit/18fd09ab64b07c45d0373307e37f7c96b3984183 so this is likely related to this issue and not #1442.

I've not had any success reproducing this with a single translation unit yet.

nickdesaulniers commented 2 years ago

This is reproducible via:

Smaller reproducer for the curve25519-x86_64.c case:

// $ clang -mstack-alignment=8 -march=atom -O2 -w
long fsqr_out, fsqr_tmp;
void ____wrong_branch_error();
void curve25519_ever64(char out) {
  long init1[8];
  long inp = init1;
  asm(""
      : "+&r"(inp), "+&r"(fsqr_tmp)
      : "r"(fsqr_out)
      : "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r13",
        "%r14", "%r15", "memory");
  ____wrong_branch_error(out);
}