summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/ARM')
-rw-r--r--test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll3
-rw-r--r--test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll4
-rw-r--r--test/CodeGen/ARM/Windows/hard-float.ll10
-rw-r--r--test/CodeGen/ARM/Windows/long-calls.ll2
-rw-r--r--test/CodeGen/ARM/Windows/no-arm-mode.ll9
-rw-r--r--test/CodeGen/ARM/Windows/pic.ll17
-rw-r--r--test/CodeGen/ARM/Windows/structors.ll12
-rw-r--r--test/CodeGen/ARM/Windows/trivial-gnu-object.ll10
-rw-r--r--test/CodeGen/ARM/arm-returnaddr.ll6
-rw-r--r--test/CodeGen/ARM/byval-align.ll3
-rw-r--r--test/CodeGen/ARM/cttz.ll90
-rw-r--r--test/CodeGen/ARM/cttz_vector.ll383
-rw-r--r--test/CodeGen/ARM/ctz.ll11
-rw-r--r--test/CodeGen/ARM/fast-isel-call.ll6
-rw-r--r--test/CodeGen/ARM/fast-isel-intrinsic.ll6
-rw-r--r--test/CodeGen/ARM/fast-isel-static.ll4
-rw-r--r--test/CodeGen/ARM/ldrd.ll69
-rw-r--r--test/CodeGen/ARM/memset-inline.ll3
-rw-r--r--test/CodeGen/ARM/nest-register.ll21
-rw-r--r--test/CodeGen/ARM/subtarget-features-long-calls.ll49
-rw-r--r--test/CodeGen/ARM/wrong-t2stmia-size-opt.ll16
21 files changed, 684 insertions, 50 deletions
diff --git a/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll b/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll
index c93d2a2..ac5b6f9 100644
--- a/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll
+++ b/test/CodeGen/ARM/2013-05-02-AAPCS-ByVal-Structs-C4-C5-VFP.ll
@@ -25,8 +25,7 @@ entry:
;CHECK: push {r7, lr}
;CHECK: sub sp, #4
;CHECK: add r0, sp, #12
- ;CHECK: str r2, [sp, #16]
- ;CHECK: str r1, [sp, #12]
+ ;CHECK: strd r1, r2, [sp, #12]
;CHECK: bl fooUseStruct
call void @fooUseStruct(%st_t* %p1)
ret void
diff --git a/test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll b/test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll
index 438b021a..d3aa233 100644
--- a/test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll
+++ b/test/CodeGen/ARM/2013-05-13-AAPCS-byval-padding2.ll
@@ -9,8 +9,8 @@ define void @foo(%struct4bytes* byval %p0, ; --> R0
) {
;CHECK: sub sp, sp, #16
;CHECK: push {r11, lr}
-;CHECK: add r11, sp, #8
-;CHECK: stm r11, {r0, r1, r2, r3}
+;CHECK: add r12, sp, #8
+;CHECK: stm r12, {r0, r1, r2, r3}
;CHECK: add r0, sp, #12
;CHECK: bl useInt
;CHECK: pop {r11, lr}
diff --git a/test/CodeGen/ARM/Windows/hard-float.ll b/test/CodeGen/ARM/Windows/hard-float.ll
index f7b7ec2..1ce02813 100644
--- a/test/CodeGen/ARM/Windows/hard-float.ll
+++ b/test/CodeGen/ARM/Windows/hard-float.ll
@@ -1,4 +1,8 @@
-; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-WIN
+
+; RUN: llc -mtriple=thumbv7-windows-gnu -mcpu=cortex-a9 -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-GNU
define float @function(float %f, float %g) nounwind {
entry:
@@ -6,5 +10,7 @@ entry:
ret float %h
}
-; CHECK: vadd.f32 s0, s0, s1
+; CHECK-WIN: vadd.f32 s0, s0, s1
+
+; CHECK-GNU: vadd.f32 s0, s0, s1
diff --git a/test/CodeGen/ARM/Windows/long-calls.ll b/test/CodeGen/ARM/Windows/long-calls.ll
index 21c95fa..4e5bdce 100644
--- a/test/CodeGen/ARM/Windows/long-calls.ll
+++ b/test/CodeGen/ARM/Windows/long-calls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -arm-long-calls -o - %s \
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -mattr=+long-calls -o - %s \
; RUN: | FileCheck %s
declare arm_aapcs_vfpcc void @callee()
diff --git a/test/CodeGen/ARM/Windows/no-arm-mode.ll b/test/CodeGen/ARM/Windows/no-arm-mode.ll
index 6db031f..3035364 100644
--- a/test/CodeGen/ARM/Windows/no-arm-mode.ll
+++ b/test/CodeGen/ARM/Windows/no-arm-mode.ll
@@ -1,5 +1,10 @@
; RUN: not llc -mtriple=armv7-windows-itanium -mcpu=cortex-a9 -o /dev/null %s 2>&1 \
-; RUN: | FileCheck %s
+; RUN: | FileCheck %s -check-prefix CHECK-WIN
-; CHECK: does not support ARM mode execution
+; RUN: not llc -mtriple=armv7-windows-gnu -mcpu=cortex-a9 -o /dev/null %s 2>&1 \
+; RUN: | FileCheck %s -check-prefix CHECK-GNU
+
+; CHECK-WIN: does not support ARM mode execution
+
+; CHECK-GNU: does not support ARM mode execution
diff --git a/test/CodeGen/ARM/Windows/pic.ll b/test/CodeGen/ARM/Windows/pic.ll
index 9ef7c35..df4c400 100644
--- a/test/CodeGen/ARM/Windows/pic.ll
+++ b/test/CodeGen/ARM/Windows/pic.ll
@@ -1,5 +1,8 @@
; RUN: llc -mtriple thumbv7-windows-itanium -relocation-model pic -filetype asm -o - %s \
-; RUN: | FileCheck %s
+; RUN: | FileCheck %s -check-prefix CHECK-WIN
+
+; RUN: llc -mtriple thumbv7-windows-gnu -relocation-model pic -filetype asm -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-GNU
@external = external global i8
@@ -9,8 +12,12 @@ entry:
ret i8 %0
}
-; CHECK-LABEL: return_external
-; CHECK: movw r0, :lower16:external
-; CHECK: movt r0, :upper16:external
-; CHECK: ldrb r0, [r0]
+; CHECK-WIN-LABEL: return_external
+; CHECK-WIN: movw r0, :lower16:external
+; CHECK-WIN: movt r0, :upper16:external
+; CHECK-WIN: ldrb r0, [r0]
+; CHECK-GNU-LABEL: return_external
+; CHECK-GNU: movw r0, :lower16:external
+; CHECK-GNU: movt r0, :upper16:external
+; CHECK-GNU: ldrb r0, [r0]
diff --git a/test/CodeGen/ARM/Windows/structors.ll b/test/CodeGen/ARM/Windows/structors.ll
index 874b5bf..eff1c7f 100644
--- a/test/CodeGen/ARM/Windows/structors.ll
+++ b/test/CodeGen/ARM/Windows/structors.ll
@@ -1,4 +1,8 @@
-; RUN: llc -mtriple thumbv7-windows-itanium -o - %s | FileCheck %s
+; RUN: llc -mtriple thumbv7-windows-itanium -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-WIN
+
+; RUN: llc -mtriple thumbv7-windows-gnu -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-GNU
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @function, i8* null }]
@@ -7,6 +11,8 @@ entry:
ret void
}
-; CHECK: .section .CRT$XCU,"dr"
-; CHECK: .long function
+; CHECK-WIN: .section .CRT$XCU,"dr"
+; CHECK-WIN: .long function
+; CHECK-GNU: .section .ctors,"dw"
+; CHECK-GNU: .long function
diff --git a/test/CodeGen/ARM/Windows/trivial-gnu-object.ll b/test/CodeGen/ARM/Windows/trivial-gnu-object.ll
new file mode 100644
index 0000000..a242f39
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/trivial-gnu-object.ll
@@ -0,0 +1,10 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
+; RUN: llc -mtriple=thumbv7-windows-gnu -filetype=obj -o - %s | llvm-objdump -d - | FileCheck %s
+
+define void @foo() {
+; CHECK: file format COFF-ARM
+
+; CHECK-LABEL: foo:
+; CHECK: bx lr
+ ret void
+}
diff --git a/test/CodeGen/ARM/arm-returnaddr.ll b/test/CodeGen/ARM/arm-returnaddr.ll
index 4266572..26f8c67 100644
--- a/test/CodeGen/ARM/arm-returnaddr.ll
+++ b/test/CodeGen/ARM/arm-returnaddr.ll
@@ -8,7 +8,6 @@
define i8* @rt0(i32 %x) nounwind readnone {
entry:
; CHECK-LABEL: rt0:
-; CHECK: {r7, lr}
; CHECK: mov r0, lr
%0 = tail call i8* @llvm.returnaddress(i32 0)
ret i8* %0
@@ -17,10 +16,9 @@ entry:
define i8* @rt2() nounwind readnone {
entry:
; CHECK-LABEL: rt2:
-; CHECK: {r7, lr}
; CHECK: ldr r[[R0:[0-9]+]], [r7]
-; CHECK: ldr r0, [r0]
-; CHECK: ldr r0, [r0, #4]
+; CHECK: ldr r0, [r[[R0]]]
+; CHECK: ldr r0, [r[[R0]], #4]
%0 = tail call i8* @llvm.returnaddress(i32 2)
ret i8* %0
}
diff --git a/test/CodeGen/ARM/byval-align.ll b/test/CodeGen/ARM/byval-align.ll
index a26b5a7..8a50628 100644
--- a/test/CodeGen/ARM/byval-align.ll
+++ b/test/CodeGen/ARM/byval-align.ll
@@ -28,8 +28,7 @@ define i32 @test_align8(i8*, [4 x i32]* byval align 8 %b) {
; CHECK: push {r4, r7, lr}
; CHECK: add r7, sp, #4
-; CHECK-DAG: str r2, [r7, #8]
-; CHECK-DAG: str r3, [r7, #12]
+; CHECK: strd r2, r3, [r7, #8]
; CHECK: ldr r0, [r7, #8]
diff --git a/test/CodeGen/ARM/cttz.ll b/test/CodeGen/ARM/cttz.ll
new file mode 100644
index 0000000..dacfca5
--- /dev/null
+++ b/test/CodeGen/ARM/cttz.ll
@@ -0,0 +1,90 @@
+; RUN: llc < %s -mtriple arm-eabi -mattr=+v6t2 | FileCheck %s
+; RUN: llc < %s -mtriple arm-eabi -mattr=+v6t2 -mattr=+neon | FileCheck %s
+
+; This test checks the @llvm.cttz.* intrinsics for integers.
+
+declare i8 @llvm.cttz.i8(i8, i1)
+declare i16 @llvm.cttz.i16(i16, i1)
+declare i32 @llvm.cttz.i32(i32, i1)
+declare i64 @llvm.cttz.i64(i64, i1)
+
+;------------------------------------------------------------------------------
+
+define i8 @test_i8(i8 %a) {
+; CHECK-LABEL: test_i8:
+; CHECK: orr [[REG:r[0-9]+]], [[REG]], #256
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 false)
+ ret i8 %tmp
+}
+
+define i16 @test_i16(i16 %a) {
+; CHECK-LABEL: test_i16:
+; CHECK: orr [[REG:r[0-9]+]], [[REG]], #65536
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 false)
+ ret i16 %tmp
+}
+
+define i32 @test_i32(i32 %a) {
+; CHECK-LABEL: test_i32:
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 false)
+ ret i32 %tmp
+}
+
+define i64 @test_i64(i64 %a) {
+; CHECK-LABEL: test_i64:
+; CHECK: rbit
+; CHECK: rbit
+; CHECK: cmp
+; CHECK: clz
+; CHECK: add
+; CHECK: clzne
+ %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 false)
+ ret i64 %tmp
+}
+
+;------------------------------------------------------------------------------
+
+define i8 @test_i8_zero_undef(i8 %a) {
+; CHECK-LABEL: test_i8_zero_undef:
+; CHECK-NOT: orr
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i8 @llvm.cttz.i8(i8 %a, i1 true)
+ ret i8 %tmp
+}
+
+define i16 @test_i16_zero_undef(i16 %a) {
+; CHECK-LABEL: test_i16_zero_undef:
+; CHECK-NOT: orr
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i16 @llvm.cttz.i16(i16 %a, i1 true)
+ ret i16 %tmp
+}
+
+
+define i32 @test_i32_zero_undef(i32 %a) {
+; CHECK-LABEL: test_i32_zero_undef:
+; CHECK: rbit
+; CHECK: clz
+ %tmp = call i32 @llvm.cttz.i32(i32 %a, i1 true)
+ ret i32 %tmp
+}
+
+define i64 @test_i64_zero_undef(i64 %a) {
+; CHECK-LABEL: test_i64_zero_undef:
+; CHECK: rbit
+; CHECK: rbit
+; CHECK: cmp
+; CHECK: clz
+; CHECK: add
+; CHECK: clzne
+ %tmp = call i64 @llvm.cttz.i64(i64 %a, i1 true)
+ ret i64 %tmp
+}
diff --git a/test/CodeGen/ARM/cttz_vector.ll b/test/CodeGen/ARM/cttz_vector.ll
new file mode 100644
index 0000000..9480d75
--- /dev/null
+++ b/test/CodeGen/ARM/cttz_vector.ll
@@ -0,0 +1,383 @@
+; RUN: llc < %s -mtriple armv7-linux-gnueabihf -mattr=+neon | FileCheck %s
+
+; This test checks the @llvm.cttz.* intrinsics for vectors.
+
+declare <1 x i8> @llvm.cttz.v1i8(<1 x i8>, i1)
+declare <2 x i8> @llvm.cttz.v2i8(<2 x i8>, i1)
+declare <4 x i8> @llvm.cttz.v4i8(<4 x i8>, i1)
+declare <8 x i8> @llvm.cttz.v8i8(<8 x i8>, i1)
+declare <16 x i8> @llvm.cttz.v16i8(<16 x i8>, i1)
+
+declare <1 x i16> @llvm.cttz.v1i16(<1 x i16>, i1)
+declare <2 x i16> @llvm.cttz.v2i16(<2 x i16>, i1)
+declare <4 x i16> @llvm.cttz.v4i16(<4 x i16>, i1)
+declare <8 x i16> @llvm.cttz.v8i16(<8 x i16>, i1)
+
+declare <1 x i32> @llvm.cttz.v1i32(<1 x i32>, i1)
+declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1)
+declare <4 x i32> @llvm.cttz.v4i32(<4 x i32>, i1)
+
+declare <1 x i64> @llvm.cttz.v1i64(<1 x i64>, i1)
+declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1)
+
+;------------------------------------------------------------------------------
+
+define void @test_v1i8(<1 x i8>* %p) {
+; CHECK-LABEL: test_v1i8
+ %a = load <1 x i8>, <1 x i8>* %p
+ %tmp = call <1 x i8> @llvm.cttz.v1i8(<1 x i8> %a, i1 false)
+ store <1 x i8> %tmp, <1 x i8>* %p
+ ret void
+}
+
+define void @test_v2i8(<2 x i8>* %p) {
+; CHECK-LABEL: test_v2i8:
+ %a = load <2 x i8>, <2 x i8>* %p
+ %tmp = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %a, i1 false)
+ store <2 x i8> %tmp, <2 x i8>* %p
+ ret void
+}
+
+define void @test_v4i8(<4 x i8>* %p) {
+; CHECK-LABEL: test_v4i8:
+ %a = load <4 x i8>, <4 x i8>* %p
+ %tmp = call <4 x i8> @llvm.cttz.v4i8(<4 x i8> %a, i1 false)
+ store <4 x i8> %tmp, <4 x i8>* %p
+ ret void
+}
+
+define void @test_v8i8(<8 x i8>* %p) {
+; CHECK-LABEL: test_v8i8:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i8 [[D2:d[0-9]+]], #0x1
+; CHECK: vneg.s8 [[D3:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D3]]
+; CHECK: vsub.i8 [[D1]], [[D1]], [[D2]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <8 x i8>, <8 x i8>* %p
+ %tmp = call <8 x i8> @llvm.cttz.v8i8(<8 x i8> %a, i1 false)
+ store <8 x i8> %tmp, <8 x i8>* %p
+ ret void
+}
+
+define void @test_v16i8(<16 x i8>* %p) {
+; CHECK-LABEL: test_v16i8:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i8 [[Q2:q[0-9]+]], #0x1
+; CHECK: vneg.s8 [[Q3:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vsub.i8 [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <16 x i8>, <16 x i8>* %p
+ %tmp = call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %a, i1 false)
+ store <16 x i8> %tmp, <16 x i8>* %p
+ ret void
+}
+
+define void @test_v1i16(<1 x i16>* %p) {
+; CHECK-LABEL: test_v1i16:
+ %a = load <1 x i16>, <1 x i16>* %p
+ %tmp = call <1 x i16> @llvm.cttz.v1i16(<1 x i16> %a, i1 false)
+ store <1 x i16> %tmp, <1 x i16>* %p
+ ret void
+}
+
+define void @test_v2i16(<2 x i16>* %p) {
+; CHECK-LABEL: test_v2i16:
+ %a = load <2 x i16>, <2 x i16>* %p
+ %tmp = call <2 x i16> @llvm.cttz.v2i16(<2 x i16> %a, i1 false)
+ store <2 x i16> %tmp, <2 x i16>* %p
+ ret void
+}
+
+define void @test_v4i16(<4 x i16>* %p) {
+; CHECK-LABEL: test_v4i16:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i16 [[D2:d[0-9]+]], #0x1
+; CHECK: vneg.s16 [[D3:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D3]]
+; CHECK: vsub.i16 [[D1]], [[D1]], [[D2]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vpaddl.u8 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <4 x i16>, <4 x i16>* %p
+ %tmp = call <4 x i16> @llvm.cttz.v4i16(<4 x i16> %a, i1 false)
+ store <4 x i16> %tmp, <4 x i16>* %p
+ ret void
+}
+
+define void @test_v8i16(<8 x i16>* %p) {
+; CHECK-LABEL: test_v8i16:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i16 [[Q2:q[0-9]+]], #0x1
+; CHECK: vneg.s16 [[Q3:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vsub.i16 [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u8 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <8 x i16>, <8 x i16>* %p
+ %tmp = call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %a, i1 false)
+ store <8 x i16> %tmp, <8 x i16>* %p
+ ret void
+}
+
+define void @test_v1i32(<1 x i32>* %p) {
+; CHECK-LABEL: test_v1i32:
+ %a = load <1 x i32>, <1 x i32>* %p
+ %tmp = call <1 x i32> @llvm.cttz.v1i32(<1 x i32> %a, i1 false)
+ store <1 x i32> %tmp, <1 x i32>* %p
+ ret void
+}
+
+define void @test_v2i32(<2 x i32>* %p) {
+; CHECK-LABEL: test_v2i32:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i32 [[D2:d[0-9]+]], #0x1
+; CHECK: vneg.s32 [[D3:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D3]]
+; CHECK: vsub.i32 [[D1]], [[D1]], [[D2]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vpaddl.u8 [[D1]], [[D1]]
+; CHECK: vpaddl.u16 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <2 x i32>, <2 x i32>* %p
+ %tmp = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %a, i1 false)
+ store <2 x i32> %tmp, <2 x i32>* %p
+ ret void
+}
+
+define void @test_v4i32(<4 x i32>* %p) {
+; CHECK-LABEL: test_v4i32:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i32 [[Q2:q[0-9]+]], #0x1
+; CHECK: vneg.s32 [[Q3:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vsub.i32 [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u16 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <4 x i32>, <4 x i32>* %p
+ %tmp = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %a, i1 false)
+ store <4 x i32> %tmp, <4 x i32>* %p
+ ret void
+}
+
+define void @test_v1i64(<1 x i64>* %p) {
+; CHECK-LABEL: test_v1i64:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i32 [[D2:d[0-9]+]], #0x0
+; CHECK: vmov.i64 [[D3:d[0-9]+]], #0xffffffffffffffff
+; CHECK: vsub.i64 [[D2]], [[D2]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D2]]
+; CHECK: vadd.i64 [[D1]], [[D1]], [[D3]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vpaddl.u8 [[D1]], [[D1]]
+; CHECK: vpaddl.u16 [[D1]], [[D1]]
+; CHECK: vpaddl.u32 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <1 x i64>, <1 x i64>* %p
+ %tmp = call <1 x i64> @llvm.cttz.v1i64(<1 x i64> %a, i1 false)
+ store <1 x i64> %tmp, <1 x i64>* %p
+ ret void
+}
+
+define void @test_v2i64(<2 x i64>* %p) {
+; CHECK-LABEL: test_v2i64:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i32 [[Q2:q[0-9]+]], #0x0
+; CHECK: vmov.i64 [[Q3:q[0-9]+]], #0xffffffffffffffff
+; CHECK: vsub.i64 [[Q2]], [[Q2]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vadd.i64 [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u16 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u32 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <2 x i64>, <2 x i64>* %p
+ %tmp = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 false)
+ store <2 x i64> %tmp, <2 x i64>* %p
+ ret void
+}
+
+;------------------------------------------------------------------------------
+
+define void @test_v1i8_zero_undef(<1 x i8>* %p) {
+; CHECK-LABEL: test_v1i8_zero_undef
+ %a = load <1 x i8>, <1 x i8>* %p
+ %tmp = call <1 x i8> @llvm.cttz.v1i8(<1 x i8> %a, i1 true)
+ store <1 x i8> %tmp, <1 x i8>* %p
+ ret void
+}
+
+define void @test_v2i8_zero_undef(<2 x i8>* %p) {
+; CHECK-LABEL: test_v2i8_zero_undef:
+ %a = load <2 x i8>, <2 x i8>* %p
+ %tmp = call <2 x i8> @llvm.cttz.v2i8(<2 x i8> %a, i1 true)
+ store <2 x i8> %tmp, <2 x i8>* %p
+ ret void
+}
+
+define void @test_v4i8_zero_undef(<4 x i8>* %p) {
+; CHECK-LABEL: test_v4i8_zero_undef:
+ %a = load <4 x i8>, <4 x i8>* %p
+ %tmp = call <4 x i8> @llvm.cttz.v4i8(<4 x i8> %a, i1 true)
+ store <4 x i8> %tmp, <4 x i8>* %p
+ ret void
+}
+
+define void @test_v8i8_zero_undef(<8 x i8>* %p) {
+; CHECK-LABEL: test_v8i8_zero_undef:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i8 [[D2:d[0-9]+]], #0x1
+; CHECK: vneg.s8 [[D3:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D3]]
+; CHECK: vsub.i8 [[D1]], [[D1]], [[D2]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <8 x i8>, <8 x i8>* %p
+ %tmp = call <8 x i8> @llvm.cttz.v8i8(<8 x i8> %a, i1 true)
+ store <8 x i8> %tmp, <8 x i8>* %p
+ ret void
+}
+
+define void @test_v16i8_zero_undef(<16 x i8>* %p) {
+; CHECK-LABEL: test_v16i8_zero_undef:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i8 [[Q2:q[0-9]+]], #0x1
+; CHECK: vneg.s8 [[Q3:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vsub.i8 [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <16 x i8>, <16 x i8>* %p
+ %tmp = call <16 x i8> @llvm.cttz.v16i8(<16 x i8> %a, i1 true)
+ store <16 x i8> %tmp, <16 x i8>* %p
+ ret void
+}
+
+define void @test_v1i16_zero_undef(<1 x i16>* %p) {
+; CHECK-LABEL: test_v1i16_zero_undef:
+ %a = load <1 x i16>, <1 x i16>* %p
+ %tmp = call <1 x i16> @llvm.cttz.v1i16(<1 x i16> %a, i1 true)
+ store <1 x i16> %tmp, <1 x i16>* %p
+ ret void
+}
+
+define void @test_v2i16_zero_undef(<2 x i16>* %p) {
+; CHECK-LABEL: test_v2i16_zero_undef:
+ %a = load <2 x i16>, <2 x i16>* %p
+ %tmp = call <2 x i16> @llvm.cttz.v2i16(<2 x i16> %a, i1 true)
+ store <2 x i16> %tmp, <2 x i16>* %p
+ ret void
+}
+
+define void @test_v4i16_zero_undef(<4 x i16>* %p) {
+; CHECK-LABEL: test_v4i16_zero_undef:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vneg.s16 [[D2:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D2]]
+; CHECK: vmov.i16 [[D3:d[0-9]+]], #0xf
+; CHECK: vclz.i16 [[D1]], [[D1]]
+; CHECK: vsub.i16 [[D1]], [[D3]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <4 x i16>, <4 x i16>* %p
+ %tmp = call <4 x i16> @llvm.cttz.v4i16(<4 x i16> %a, i1 true)
+ store <4 x i16> %tmp, <4 x i16>* %p
+ ret void
+}
+
+define void @test_v8i16_zero_undef(<8 x i16>* %p) {
+; CHECK-LABEL: test_v8i16_zero_undef:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vneg.s16 [[Q2:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vmov.i16 [[Q3:q[0-9]+]], #0xf
+; CHECK: vclz.i16 [[Q1]], [[Q1]]
+; CHECK: vsub.i16 [[Q1]], [[Q3]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <8 x i16>, <8 x i16>* %p
+ %tmp = call <8 x i16> @llvm.cttz.v8i16(<8 x i16> %a, i1 true)
+ store <8 x i16> %tmp, <8 x i16>* %p
+ ret void
+}
+
+define void @test_v1i32_zero_undef(<1 x i32>* %p) {
+; CHECK-LABEL: test_v1i32_zero_undef:
+ %a = load <1 x i32>, <1 x i32>* %p
+ %tmp = call <1 x i32> @llvm.cttz.v1i32(<1 x i32> %a, i1 true)
+ store <1 x i32> %tmp, <1 x i32>* %p
+ ret void
+}
+
+define void @test_v2i32_zero_undef(<2 x i32>* %p) {
+; CHECK-LABEL: test_v2i32_zero_undef:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vneg.s32 [[D2:d[0-9]+]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D2]]
+; CHECK: vmov.i32 [[D3:d[0-9]+]], #0x1f
+; CHECK: vclz.i32 [[D1]], [[D1]]
+; CHECK: vsub.i32 [[D1]], [[D3]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <2 x i32>, <2 x i32>* %p
+ %tmp = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %a, i1 true)
+ store <2 x i32> %tmp, <2 x i32>* %p
+ ret void
+}
+
+define void @test_v4i32_zero_undef(<4 x i32>* %p) {
+; CHECK-LABEL: test_v4i32_zero_undef:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vneg.s32 [[Q2:q[0-9]+]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vmov.i32 [[Q3:q[0-9]+]], #0x1f
+; CHECK: vclz.i32 [[Q1]], [[Q1]]
+; CHECK: vsub.i32 [[Q1]], [[Q3]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <4 x i32>, <4 x i32>* %p
+ %tmp = call <4 x i32> @llvm.cttz.v4i32(<4 x i32> %a, i1 true)
+ store <4 x i32> %tmp, <4 x i32>* %p
+ ret void
+}
+
+define void @test_v1i64_zero_undef(<1 x i64>* %p) {
+; CHECK-LABEL: test_v1i64_zero_undef:
+; CHECK: vldr [[D1:d[0-9]+]], [r0]
+; CHECK: vmov.i32 [[D2:d[0-9]+]], #0x0
+; CHECK: vmov.i64 [[D3:d[0-9]+]], #0xffffffffffffffff
+; CHECK: vsub.i64 [[D2]], [[D2]], [[D1]]
+; CHECK: vand [[D1]], [[D1]], [[D2]]
+; CHECK: vadd.i64 [[D1]], [[D1]], [[D3]]
+; CHECK: vcnt.8 [[D1]], [[D1]]
+; CHECK: vpaddl.u8 [[D1]], [[D1]]
+; CHECK: vpaddl.u16 [[D1]], [[D1]]
+; CHECK: vpaddl.u32 [[D1]], [[D1]]
+; CHECK: vstr [[D1]], [r0]
+ %a = load <1 x i64>, <1 x i64>* %p
+ %tmp = call <1 x i64> @llvm.cttz.v1i64(<1 x i64> %a, i1 true)
+ store <1 x i64> %tmp, <1 x i64>* %p
+ ret void
+}
+
+define void @test_v2i64_zero_undef(<2 x i64>* %p) {
+; CHECK-LABEL: test_v2i64_zero_undef:
+; CHECK: vld1.64 {[[D1:d[0-9]+]], [[D2:d[0-9]+]]}, [r0]
+; CHECK: vmov.i32 [[Q2:q[0-9]+]], #0x0
+; CHECK: vmov.i64 [[Q3:q[0-9]+]], #0xffffffffffffffff
+; CHECK: vsub.i64 [[Q2]], [[Q2]], [[Q1:q[0-9]+]]
+; CHECK: vand [[Q1]], [[Q1]], [[Q2]]
+; CHECK: vadd.i64 [[Q1]], [[Q1]], [[Q3]]
+; CHECK: vcnt.8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u8 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u16 [[Q1]], [[Q1]]
+; CHECK: vpaddl.u32 [[Q1]], [[Q1]]
+; CHECK: vst1.64 {[[D1]], [[D2]]}, [r0]
+ %a = load <2 x i64>, <2 x i64>* %p
+ %tmp = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true)
+ store <2 x i64> %tmp, <2 x i64>* %p
+ ret void
+}
diff --git a/test/CodeGen/ARM/ctz.ll b/test/CodeGen/ARM/ctz.ll
deleted file mode 100644
index 2d88b03..0000000
--- a/test/CodeGen/ARM/ctz.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; RUN: llc -mtriple=arm-eabi -mattr=+v6t2 %s -o - | FileCheck %s
-
-declare i32 @llvm.cttz.i32(i32, i1)
-
-define i32 @f1(i32 %a) {
-; CHECK-LABEL: f1:
-; CHECK: rbit
-; CHECK: clz
- %tmp = call i32 @llvm.cttz.i32( i32 %a, i1 true )
- ret i32 %tmp
-}
diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll
index bd170f3..e382e78 100644
--- a/test/CodeGen/ARM/fast-isel-call.ll
+++ b/test/CodeGen/ARM/fast-isel-call.ll
@@ -1,9 +1,9 @@
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -arm-long-calls | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=THUMB-LONG
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=THUMB-LONG
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=THUMB-NOVFP
diff --git a/test/CodeGen/ARM/fast-isel-intrinsic.ll b/test/CodeGen/ARM/fast-isel-intrinsic.ll
index 6b434b7..1c7ff68 100644
--- a/test/CodeGen/ARM/fast-isel-intrinsic.ll
+++ b/test/CodeGen/ARM/fast-isel-intrinsic.ll
@@ -1,9 +1,9 @@
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
; Note that some of these tests assume that relocations are either
; movw/movt or constant pool loads. Different platforms will select
diff --git a/test/CodeGen/ARM/fast-isel-static.ll b/test/CodeGen/ARM/fast-isel-static.ll
index c3980cb..200387c 100644
--- a/test/CodeGen/ARM/fast-isel-static.ll
+++ b/test/CodeGen/ARM/fast-isel-static.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -arm-long-calls | FileCheck -check-prefix=CHECK-LONG %s
-; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -arm-long-calls | FileCheck -check-prefix=CHECK-LONG %s
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -mattr=+long-calls | FileCheck -check-prefix=CHECK-LONG %s
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static -mattr=+long-calls | FileCheck -check-prefix=CHECK-LONG %s
; RUN: llc < %s -mtriple=thumbv7-apple-ios -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static | FileCheck -check-prefix=CHECK-NORM %s
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=static | FileCheck -check-prefix=CHECK-NORM %s
diff --git a/test/CodeGen/ARM/ldrd.ll b/test/CodeGen/ARM/ldrd.ll
index f3e1367..56cdcae 100644
--- a/test/CodeGen/ARM/ldrd.ll
+++ b/test/CodeGen/ARM/ldrd.ll
@@ -3,6 +3,7 @@
; rdar://6949835
; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=basic | FileCheck %s -check-prefix=BASIC -check-prefix=CHECK
; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=greedy | FileCheck %s -check-prefix=GREEDY -check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT -check-prefix=CHECK
; Magic ARM pair hints works best with linearscan / fast.
@@ -110,5 +111,73 @@ entry:
ret void
}
+; CHECK-LABEL: strd_spill_ldrd_reload:
+; A8: strd r1, r0, [sp, #-8]!
+; M3: strd r1, r0, [sp, #-8]!
+; BASIC: strd r1, r0, [sp, #-8]!
+; GREEDY: strd r0, r1, [sp, #-8]!
+; CHECK: @ InlineAsm Start
+; CHECK: @ InlineAsm End
+; A8: ldrd r2, r1, [sp]
+; M3: ldrd r2, r1, [sp]
+; BASIC: ldrd r2, r1, [sp]
+; GREEDY: ldrd r1, r2, [sp]
+; CHECK: bl{{x?}} _extfunc
+define void @strd_spill_ldrd_reload(i32 %v0, i32 %v1) {
+ ; force %v0 and %v1 to be spilled
+ call void asm sideeffect "", "~{r0},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr}"()
+ ; force the reloaded %v0, %v1 into different registers
+ call void @extfunc(i32 0, i32 %v0, i32 %v1, i32 7)
+ ret void
+}
+
+declare void @extfunc2(i32*, i32, i32)
+
+; CHECK-LABEL: ldrd_postupdate_dec:
+; CHECK: ldrd r1, r2, [r0], #-8
+; CHECK-NEXT: bl{{x?}} _extfunc
+define void @ldrd_postupdate_dec(i32* %p0) {
+ %p0.1 = getelementptr i32, i32* %p0, i32 1
+ %v0 = load i32, i32* %p0
+ %v1 = load i32, i32* %p0.1
+ %p1 = getelementptr i32, i32* %p0, i32 -2
+ call void @extfunc2(i32* %p1, i32 %v0, i32 %v1)
+ ret void
+}
+
+; CHECK-LABEL: ldrd_postupdate_inc:
+; CHECK: ldrd r1, r2, [r0], #8
+; CHECK-NEXT: bl{{x?}} _extfunc
+define void @ldrd_postupdate_inc(i32* %p0) {
+ %p0.1 = getelementptr i32, i32* %p0, i32 1
+ %v0 = load i32, i32* %p0
+ %v1 = load i32, i32* %p0.1
+ %p1 = getelementptr i32, i32* %p0, i32 2
+ call void @extfunc2(i32* %p1, i32 %v0, i32 %v1)
+ ret void
+}
+
+; CHECK-LABEL: strd_postupdate_dec:
+; CHECK: strd r1, r2, [r0], #-8
+; CHECK-NEXT: bx lr
+define i32* @strd_postupdate_dec(i32* %p0, i32 %v0, i32 %v1) {
+ %p0.1 = getelementptr i32, i32* %p0, i32 1
+ store i32 %v0, i32* %p0
+ store i32 %v1, i32* %p0.1
+ %p1 = getelementptr i32, i32* %p0, i32 -2
+ ret i32* %p1
+}
+
+; CHECK-LABEL: strd_postupdate_inc:
+; CHECK: strd r1, r2, [r0], #8
+; CHECK-NEXT: bx lr
+define i32* @strd_postupdate_inc(i32* %p0, i32 %v0, i32 %v1) {
+ %p0.1 = getelementptr i32, i32* %p0, i32 1
+ store i32 %v0, i32* %p0
+ store i32 %v1, i32* %p0.1
+ %p1 = getelementptr i32, i32* %p0, i32 2
+ ret i32* %p1
+}
+
declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind
declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind
diff --git a/test/CodeGen/ARM/memset-inline.ll b/test/CodeGen/ARM/memset-inline.ll
index 191db1e..f6f8d56 100644
--- a/test/CodeGen/ARM/memset-inline.ll
+++ b/test/CodeGen/ARM/memset-inline.ll
@@ -4,8 +4,7 @@ define void @t1(i8* nocapture %c) nounwind optsize {
entry:
; CHECK-LABEL: t1:
; CHECK: movs r1, #0
-; CHECK: str r1, [r0]
-; CHECK: str r1, [r0, #4]
+; CHECK: strd r1, r1, [r0]
; CHECK: str r1, [r0, #8]
call void @llvm.memset.p0i8.i64(i8* %c, i8 0, i64 12, i32 8, i1 false)
ret void
diff --git a/test/CodeGen/ARM/nest-register.ll b/test/CodeGen/ARM/nest-register.ll
new file mode 100644
index 0000000..6b8c3dc
--- /dev/null
+++ b/test/CodeGen/ARM/nest-register.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
+
+; Tests that the 'nest' parameter attribute causes the relevant parameter to be
+; passed in the right register.
+
+define i8* @nest_receiver(i8* nest %arg) nounwind {
+; CHECK-LABEL: nest_receiver:
+; CHECK: @ BB#0:
+; CHECK-NEXT: mov r0, r12
+; CHECK-NEXT: mov pc, lr
+ ret i8* %arg
+}
+
+define i8* @nest_caller(i8* %arg) nounwind {
+; CHECK-LABEL: nest_caller:
+; CHECK: mov r12, r0
+; CHECK-NEXT: bl nest_receiver
+; CHECK: mov pc, lr
+ %result = call i8* @nest_receiver(i8* nest %arg)
+ ret i8* %result
+}
diff --git a/test/CodeGen/ARM/subtarget-features-long-calls.ll b/test/CodeGen/ARM/subtarget-features-long-calls.ll
new file mode 100644
index 0000000..430ae3d
--- /dev/null
+++ b/test/CodeGen/ARM/subtarget-features-long-calls.ll
@@ -0,0 +1,49 @@
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - | FileCheck -check-prefix=NO-OPTION %s
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=+long-calls | FileCheck -check-prefix=LONGCALL %s
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - -mattr=-long-calls | FileCheck -check-prefix=NO-LONGCALL %s
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 | FileCheck -check-prefix=NO-OPTION %s
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=+long-calls | FileCheck -check-prefix=LONGCALL %s
+; RUN: llc -march thumb -mcpu=cortex-a8 -relocation-model=static %s -o - -O0 -mattr=-long-calls | FileCheck -check-prefix=NO-LONGCALL %s
+
+; NO-OPTION-LABEL: {{_?}}caller0
+; NO-OPTION: ldr [[R0:r[0-9]+]], [[L0:.*]]
+; NO-OPTION: blx [[R0]]
+; NO-OPTION: [[L0]]:
+; NO-OPTION: .long {{_?}}callee0
+
+; LONGCALL-LABEL: {{_?}}caller0
+; LONGCALL: ldr [[R0:r[0-9]+]], [[L0:.*]]
+; LONGCALL: blx [[R0]]
+; LONGCALL: [[L0]]:
+; LONGCALL: .long {{_?}}callee0
+
+; NO-LONGCALL-LABEL: {{_?}}caller0
+; NO-LONGCALL: bl {{_?}}callee0
+
+define i32 @caller0() #0 {
+entry:
+ tail call void @callee0()
+ ret i32 0
+}
+
+; NO-OPTION-LABEL: {{_?}}caller1
+; NO-OPTION: bl {{_?}}callee0
+
+; LONGCALL-LABEL: {{_?}}caller1
+; LONGCALL: ldr [[R0:r[0-9]+]], [[L0:.*]]
+; LONGCALL: blx [[R0]]
+; LONGCALL: [[L0]]:
+; LONGCALL: .long {{_?}}callee0
+
+; NO-LONGCALL-LABEL: {{_?}}caller1
+; NO-LONGCALL: bl {{_?}}callee0
+
+define i32 @caller1() {
+entry:
+ tail call void @callee0()
+ ret i32 0
+}
+
+declare void @callee0()
+
+attributes #0 = { "target-features"="+long-calls" }
diff --git a/test/CodeGen/ARM/wrong-t2stmia-size-opt.ll b/test/CodeGen/ARM/wrong-t2stmia-size-opt.ll
index 96c5fb8..fe335df 100644
--- a/test/CodeGen/ARM/wrong-t2stmia-size-opt.ll
+++ b/test/CodeGen/ARM/wrong-t2stmia-size-opt.ll
@@ -5,16 +5,20 @@ target triple = "thumbv7--linux-gnueabi"
declare i8* @llvm.returnaddress(i32)
-define i32* @wrong-t2stmia-size-reduction(i32* %addr, i32 %val0) minsize {
+define i32* @wrong-t2stmia-size-reduction(i32* %addr, i32 %val0, i32 %val1) minsize {
store i32 %val0, i32* %addr
%addr1 = getelementptr i32, i32* %addr, i32 1
+ %addr2 = getelementptr i32, i32* %addr, i32 2
%lr = call i8* @llvm.returnaddress(i32 0)
%lr32 = ptrtoint i8* %lr to i32
- store i32 %lr32, i32* %addr1
- %addr2 = getelementptr i32, i32* %addr1, i32 1
- ret i32* %addr2
+ store i32 %val1, i32* %addr1
+ store i32 %lr32, i32* %addr2
+
+ %addr3 = getelementptr i32, i32* %addr, i32 3
+ ret i32* %addr3
}
-; Check that stm writes two registers. The bug caused one of registers (LR,
+; Check that stm writes three registers. The bug caused one of registers (LR,
; which invalid for Thumb1 form of STMIA instruction) to be dropped.
-; CHECK: stm{{[^,]*}}, {{{.*,.*}}}
+; CHECK-LABEL: wrong-t2stmia-size-reduction:
+; CHECK: stm{{[^,]*}}, {{{.*,.*,.*}}}
OpenPOWER on IntegriCloud