Open DavidSpickett opened 1 month ago
To reproduce by cross compiling on Linux:
Download toolchain from: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads (https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz?rev=adb0c0238c934aeeaa12c09609c5e6fc&hash=68DA67DE12CBAD82A0FA4B75247E866155C93053).
Extract and add it to your PATH:
$ export PATH=$(pwd)/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/bin/:$PATH
Set up a symlink inside the toolchain so it can find ld.lld
. I've found that ld
runs out of memory most of the time. Note that this symink is in the <triple>/bin
folder, not bin/
.
arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/bin$ ln -s $(which ld.lld-11) ./ld.lld
Then configure llvm using this script:
$ cat ../configure-arm.sh
set -ex
cd /work/open_source/build-llvm-arm
HOST_TRIPLE=arm-none-linux-gnueabihf
C_COMPILER=$HOST_TRIPLE-gcc
CXX_COMPILER=$HOST_TRIPLE-g++
cmake -G Ninja \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_CROSSCOMPILING=1 \
-DCMAKE_C_COMPILER=$C_COMPILER \
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
-DLLVM_HOST_TRIPLE=$HOST_TRIPLE \
-DLLVM_TARGETS_TO_BUILD=ARM \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_ENABLE_ASSERTIONS=On \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-marm -fuse-ld=lld" \
-DCMAKE_C_FLAGS="-marm -fuse-ld=lld" \
/work/open_source/llvm-project/llvm/
ninja
then ninja check-clang-unit
. It will fail to find the tests, this is expected because they're Arm32 binaries.
Now install qemu-user-static
from apt and then use it to emulate the unit tests:
$ qemu-arm-static -L /work/open_source/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/ ./tools/clang/unittests/Interpreter/ClangReplInterpreterTests
Interestingly, these values are different from what we see on armv8 hardware, which makes sense if there is UB here.
[ RUN ] InterpreterTest.Value
/work/open_source/llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp:293: Failure
Expected equality of these values:
V1.getInt()
Which is: -12521408
42
/work/open_source/llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp:294: Failure
Expected equality of these values:
V1.convertTo<int>()
Which is: -12521408
42
/work/open_source/llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp:330: Failure
Expected equality of these values:
V4.getInt()
Which is: 124447888
42
/work/open_source/llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp:337: Failure
Expected equality of these values:
V5.getInt()
Which is: 124447888
43
[ FAILED ] InterpreterTest.Value (2937 ms)
To reproduce the other failed tests, add -fsanitize=undefined
to the C/CXX flags. You will then need to replicate the commands that lit would run, and run those using qemu.
I will continue to look for a solution on native hardware.
Hey I just wanna point out Interp
and clang Interpreter are different things, clang/lib/AST/Interp
is a new implementation for C++ constexpr evaluation, (https://clang.llvm.org/docs/ConstantInterpreter.html) and clang/lib/Interpreter
is an interactive C++ interpreter that allows for incremental compilation. (https://clang.llvm.org/docs/ClangRepl.html)
Thank you, I had confused the two.
Which means the issue caused by https://github.com/llvm/llvm-project/pull/89811 is in clang-repl and the ones I'm seeing here are in the constant interpreter.
For those who have access to hardware, I could use the rest of the cross compilation guide for running on Raspberry Pi 4, Debian 12. I have used GCC 12.2 for glibc compatibility, instead of GCC 13.2
To reproduce by cross compiling on Linux:
Download toolchain from: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads (https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz?rev=adb0c0238c934aeeaa12c09609c5e6fc&hash=68DA67DE12CBAD82A0FA4B75247E866155C93053).
GCC 12.2 available here: https://developer.arm.com/-/media/Files/downloads/gnu/12.2.rel1/binrel/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz?rev=9929cb6c0e8948f0ba1a621167fcd56d&hash=8F13B510F8B20149258CB4AA5372BF92
Doing a 32 bit Arm build with UBSAN enabled, I get many failures from the clang interpreter:
Most of them are problems with reference binding or calling of constructors on misaligned addresses. Usually the type requires 8 byte alignment but the address is 4 byte aligned.
~This has come up a lot recently, including https://github.com/llvm/llvm-project/pull/89811 which has "uncovered" this issue outside of UBSAN builds.~
I think the assumptions in the interpreter's management of its virtual stack do not hold for 32 bit Arm. I don't know that that's the cause of all the issues we have seen without UBSAN, but it seems likely.