diff options
author | JF Bastien <jfb@google.com> | 2013-05-17 23:49:01 +0000 |
---|---|---|
committer | JF Bastien <jfb@google.com> | 2013-05-17 23:49:01 +0000 |
commit | bab06ba696694e7f62f964af7ee5290a13f78340 (patch) | |
tree | 5e253bd087fd639188bf69b6b15a9cc9604c88d7 /test/CodeGen/ARM/fast-isel-align.ll | |
parent | 637cb17a3d65b46f48ae8dfd012057e6c9d00c2b (diff) | |
download | external_llvm-bab06ba696694e7f62f964af7ee5290a13f78340.zip external_llvm-bab06ba696694e7f62f964af7ee5290a13f78340.tar.gz external_llvm-bab06ba696694e7f62f964af7ee5290a13f78340.tar.bz2 |
Support unaligned load/store on more ARM targets
This patch matches GCC behavior: the code used to only allow unaligned
load/store on ARM for v6+ Darwin, it will now allow unaligned load/store
for v6+ Darwin as well as for v7+ on Linux and NaCl.
The distinction is made because v6 doesn't guarantee support (but LLVM
assumes that Apple controls hardware+kernel and therefore have
conformant v6 CPUs), whereas v7 does provide this guarantee (and
Linux/NaCl behave sanely).
The patch keeps the -arm-strict-align command line option, and adds
-arm-no-strict-align. They behave similarly to GCC's -mstrict-align and
-mnostrict-align.
I originally encountered this discrepancy in FastIsel tests which expect
unaligned load/store generation. Overall this should slightly improve
performance in most cases because of reduced I$ pressure.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182175 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ARM/fast-isel-align.ll')
-rw-r--r-- | test/CodeGen/ARM/fast-isel-align.ll | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/fast-isel-align.ll b/test/CodeGen/ARM/fast-isel-align.ll new file mode 100644 index 0000000..4e28a10 --- /dev/null +++ b/test/CodeGen/ARM/fast-isel-align.ll @@ -0,0 +1,144 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB +; RUN: llc < %s -O0 -arm-strict-align -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM-STRICT-ALIGN +; RUN: llc < %s -O0 -arm-strict-align -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB-STRICT-ALIGN + +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-linux-gnueabi | FileCheck %s --check-prefix=THUMB +; RUN: llc < %s -O0 -arm-strict-align -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=ARM-STRICT-ALIGN +; RUN: llc < %s -O0 -arm-strict-align -relocation-model=dynamic-no-pic -mtriple=thumbv7-linux-gnueabi | FileCheck %s --check-prefix=THUMB-STRICT-ALIGN + +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-unknown-nacl | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -arm-strict-align -relocation-model=dynamic-no-pic -mtriple=armv7-unknown-nacl | FileCheck %s --check-prefix=ARM-STRICT-ALIGN + +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-unknown-unknown | FileCheck %s --check-prefix=ARM-STRICT-ALIGN +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-unknown-unknown | FileCheck %s --check-prefix=THUMB-STRICT-ALIGN +; RUN: llc < %s -O0 -arm-no-strict-align -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-unknown-unknown | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -arm-no-strict-align -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-unknown-unknown | FileCheck %s --check-prefix=THUMB +; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=armv7-unknown-unknown | FileCheck %s --check-prefix=ARM-STRICT-ALIGN +; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=thumbv7-unknown-unknown | FileCheck %s --check-prefix=THUMB-STRICT-ALIGN + +; Check unaligned stores +%struct.anon = type <{ float }> + +@a = common global %struct.anon* null, align 4 + +define void @unaligned_store(float %x, float %y) nounwind { +entry: +; ARM: @unaligned_store +; ARM: vmov r1, s0 +; ARM: str r1, [r0] + +; THUMB: @unaligned_store +; THUMB: vmov r1, s0 +; THUMB: str r1, [r0] + + %add = fadd float %x, %y + %0 = load %struct.anon** @a, align 4 + %x1 = getelementptr inbounds %struct.anon* %0, i32 0, i32 0 + store float %add, float* %x1, align 1 + ret void +} + +; Doublewords require only word-alignment. +; rdar://10528060 +%struct.anon.0 = type { double } + +@foo_unpacked = common global %struct.anon.0 zeroinitializer, align 4 + +define void @word_aligned_f64_store(double %a, double %b) nounwind { +entry: +; ARM: @word_aligned_f64_store +; THUMB: @word_aligned_f64_store + %add = fadd double %a, %b + store double %add, double* getelementptr inbounds (%struct.anon.0* @foo_unpacked, i32 0, i32 0), align 4 +; ARM: vstr d16, [r0] +; THUMB: vstr d16, [r0] + ret void +} + +; Check unaligned loads of floats +%class.TAlignTest = type <{ i16, float }> + +define zeroext i1 @unaligned_f32_load(%class.TAlignTest* %this) nounwind align 2 { +entry: +; ARM: @unaligned_f32_load +; THUMB: @unaligned_f32_load + %0 = alloca %class.TAlignTest*, align 4 + store %class.TAlignTest* %this, %class.TAlignTest** %0, align 4 + %1 = load %class.TAlignTest** %0 + %2 = getelementptr inbounds %class.TAlignTest* %1, i32 0, i32 1 + %3 = load float* %2, align 1 + %4 = fcmp une float %3, 0.000000e+00 +; ARM: ldr r[[R:[0-9]+]], [r0, #2] +; ARM: vmov s0, r[[R]] +; ARM: vcmpe.f32 s0, #0 +; THUMB: ldr.w r[[R:[0-9]+]], [r0, #2] +; THUMB: vmov s0, r[[R]] +; THUMB: vcmpe.f32 s0, #0 + ret i1 %4 +} + +define void @unaligned_i16_store(i16 %x, i16* %y) nounwind { +entry: +; ARM-STRICT-ALIGN: @unaligned_i16_store +; ARM-STRICT-ALIGN: strb +; ARM-STRICT-ALIGN: strb + +; THUMB-STRICT-ALIGN: @unaligned_i16_store +; THUMB-STRICT-ALIGN: strb +; THUMB-STRICT-ALIGN: strb + + store i16 %x, i16* %y, align 1 + ret void +} + +define i16 @unaligned_i16_load(i16* %x) nounwind { +entry: +; ARM-STRICT-ALIGN: @unaligned_i16_load +; ARM-STRICT-ALIGN: ldrb +; ARM-STRICT-ALIGN: ldrb + +; THUMB-STRICT-ALIGN: @unaligned_i16_load +; THUMB-STRICT-ALIGN: ldrb +; THUMB-STRICT-ALIGN: ldrb + + %0 = load i16* %x, align 1 + ret i16 %0 +} + +define void @unaligned_i32_store(i32 %x, i32* %y) nounwind { +entry: +; ARM-STRICT-ALIGN: @unaligned_i32_store +; ARM-STRICT-ALIGN: strb +; ARM-STRICT-ALIGN: strb +; ARM-STRICT-ALIGN: strb +; ARM-STRICT-ALIGN: strb + +; THUMB-STRICT-ALIGN: @unaligned_i32_store +; THUMB-STRICT-ALIGN: strb +; THUMB-STRICT-ALIGN: strb +; THUMB-STRICT-ALIGN: strb +; THUMB-STRICT-ALIGN: strb + + store i32 %x, i32* %y, align 1 + ret void +} + +define i32 @unaligned_i32_load(i32* %x) nounwind { +entry: +; ARM-STRICT-ALIGN: @unaligned_i32_load +; ARM-STRICT-ALIGN: ldrb +; ARM-STRICT-ALIGN: ldrb +; ARM-STRICT-ALIGN: ldrb +; ARM-STRICT-ALIGN: ldrb + +; THUMB-STRICT-ALIGN: @unaligned_i32_load +; THUMB-STRICT-ALIGN: ldrb +; THUMB-STRICT-ALIGN: ldrb +; THUMB-STRICT-ALIGN: ldrb +; THUMB-STRICT-ALIGN: ldrb + + %0 = load i32* %x, align 1 + ret i32 %0 +} |