Building arm64 linux randconfig kernels, I came across this assembler error: /tmp/sdma_v4_0-f95fd3.s: Assembler messages: /tmp/sdma_v4_0-f95fd3.s:44: Error: selected processor does not support `bfc w0,#1,#5' I reduced the test case to int a, b, c; int __order_base_2() { return a > 1 ? __builtin_constant_p(a) ?: b : 0; } int sdma_v4_0_rb_cntl(int p1) { int d = c ?: __order_base_2(); p1 = (p1 & ~0x0000003EL) | (62 & (d << 1)); return p1; } $ clang-8 --prefix=/home/arnd/cross/x86_64/gcc-8.1.0-nolibc/aarch64-linux/bin/ -no-integrated-as -O2 sdma_v4_0.i --target=aarch64-linux -S -o- -march=armv8.1-a https://godbolt.org/z/8Gcjl9 shows the 'bfc' instruction being generated, but not the error message as it is unable to call the external assembler correctly. According to https://sourceware.org/ml/binutils/2015-11/msg00221.html, the 'bfc' instruction is only valid in armv8.2 or higher but llvm uses it for any armv8 version.
It's an alias so the underlying instruction exists in v8.0. Gating it on the architecture is weird. We might want to change how we print it when targeting < v8.2, but I'm pretty disinclined to diagnose an error in our own assembler.
> -march=armv8.1-a Orthogonal, Arnd, is there a config that sets that specific march flag? > but I'm pretty disinclined to diagnose an error in our own assembler. Would be a bug in AsmPrinter?
> Would be a bug in AsmPrinter? In LLVM terms, if the current behaviour is considered a bug, it would be fixed in what's called the "InstPrinter" in lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp. There's specific C++ code to detect and print "bfc", which could be modified to only do that when targeting v8.2a or above. How's that for a carefully hedged reply!
(In reply to Nick Desaulniers from comment #2) > > -march=armv8.1-a > > Orthogonal, Arnd, is there a config that sets that specific march flag? I don't think so, I added that to the test case for clarification. If I remember correctly, the kernel is always built for armv8-a rather than a later version, to provide the best compatibility with existing CPUs (most of what is in production today is still armv8-a, not 8.1 or 8.2). (In reply to Tim Northover from comment #1) > It's an alias so the underlying instruction exists in v8.0. Gating it on the > architecture is weird. > > We might want to change how we print it when targeting < v8.2, but I'm > pretty disinclined to diagnose an error in our own assembler. Makes sense. As I understand section A1.7.4 in the ARM ARM, an assembler is only required to understand bfc when targetting v8.2, but it is may choose to interpret it correctly anyway.
> Makes sense. As I understand section A1.7.4 in the ARM ARM, an assembler is only required to understand bfc when targetting v8.2, but it is may choose to interpret it correctly anyway. Nicely put! I wish I'd thought of that when writing my reply.
I see the bug is still present in clang-9 and clang-10, so I'm resending my workaround for the kernel.
https://reviews.llvm.org/D68356
https://reviews.llvm.org/rL373655
(In reply to Nick Desaulniers from comment #8) > https://reviews.llvm.org/rL373655 Tim, is this OK to merge to the release/9.x branch?
I think so.
(Reopening to track 9.0.1.)
Merged: 62a16ca