-
Couldn't load subscription status.
- Fork 288
Description
The optimize copy/equals functions are using unaligned accesses of types uint64_t, uint32_t, and uint16_t to access strings. I think it's probably breaking the C "aliasing rules", but it's also making LLVM assume that the address of a chunk is aligned according to the type used to access it.
On armeabi-v7a Android, most simple load/store instructions don't have to have aligned memory operands, but an ldrd instruction apparently must have an aligned address operand. When it isn't, the code crashes with a bus error.
e.g. To reproduce:
Download Android NDK r23b, install adb, find an arm Android device running KitKat or newer, then:
$ mkdir out
$ cd out
$ cmake -GNinja .. -DCMAKE_ANDROID_NDK=/x/android-ndk-r23b -DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=19 -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
-- Android: Targeting API '19' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
-- Android: Selected unified Clang toolchain
-- The C compiler identification is Clang 12.0.8
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /x/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Looking for dlfcn.h
-- Looking for dlfcn.h - found
-- Looking for getauxval
-- Looking for getauxval - found
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - not found
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- The CXX compiler identification is Clang 12.0.8
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /x/android-ndk-r23b/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
...
$ ninja
[0/2] Re-checking globbed directories...
[54/54] Linking CXX executable test/cpuinfo_arm_test
$ adb push test/cpuinfo_arm_test /data/local/tmp
$ adb shell
blueline:/ $ /data/local/tmp/cpuinfo_arm_test
Running main() from gmock_main.cc
[==========] Running 10 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 10 tests from CpuinfoArmTest
[ RUN ] CpuinfoArmTest.FromHardwareCap
[ OK ] CpuinfoArmTest.FromHardwareCap (0 ms)
[ RUN ] CpuinfoArmTest.ODroidFromCpuInfo
Bus error
Debugging the program with LLDB:
(lldb) c
Process 4748 resuming
Running main() from gmock_main.cc
[==========] Running 10 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 10 tests from CpuinfoArmTest
[ RUN ] CpuinfoArmTest.FromHardwareCap
[ OK ] CpuinfoArmTest.FromHardwareCap (0 ms)
[ RUN ] CpuinfoArmTest.ODroidFromCpuInfo
Process 4748 stopped
* thread #1, name = 'cpuinfo_arm_tes', stop reason = signal SIGBUS: illegal alignment
frame #0: 0x00442bce cpuinfo_arm_test`CpuFeatures_StringView_IndexOf at equals.inl:30:3
27 offset += sizeof(TYPE); \
28 }
29
-> 30 CHUNK_EQUALS(uint64_t)
31 CHUNK_EQUALS(uint32_t)
32 CHUNK_EQUALS(uint16_t)
33 CHUNK_EQUALS(uint8_t)
(lldb) disas
cpuinfo_arm_test`CpuFeatures_StringView_IndexOf:
...
0x442bc4 <+156>: ldr r2, [sp, #0x8]
0x442bc6 <+158>: add.w r3, r8, r4
0x442bca <+162>: cmp r3, #0x7
0x442bcc <+164>: bls 0x442be8 ; <+192> [inlined] equals + 42 at string_view.c:67
-> 0x442bce <+166>: ldrd r3, r6, [r2]
0x442bd2 <+170>: adds r2, #0x8
0x442bd4 <+172>: ldrd r5, r0, [r9]
0x442bd8 <+176>: add.w r9, r9, #0x8
...
(lldb) mem read $r2
0x0041513b: 66 61 73 74 6d 75 6c 74 00 43 50 55 20 72 65 76 fastmult.CPU rev
0x0041514b: 69 73 69 6f 6e 00 43 50 55 20 61 72 63 68 69 74 ision.CPU archit