aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/ARM
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-12-02 13:10:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-12-02 13:10:19 +0000
commit522600a229b950314b5f4af84eba4f3e8a0ffea1 (patch)
tree32b4679ab4b8f28e5228daafc65e9dc436935353 /test/CodeGen/ARM
parent902a7b529820e6a0aa85f98f21afaeb1805a22f8 (diff)
Notes
Diffstat (limited to 'test/CodeGen/ARM')
-rw-r--r--test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll4
-rw-r--r--test/CodeGen/ARM/2010-12-07-PEIBug.ll2
-rw-r--r--test/CodeGen/ARM/2011-06-16-TailCallByVal.ll5
-rw-r--r--test/CodeGen/ARM/2011-10-26-memset-with-neon.ll4
-rw-r--r--test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll135
-rw-r--r--test/CodeGen/ARM/2012-05-04-vmov.ll11
-rw-r--r--test/CodeGen/ARM/2012-05-10-PreferVMOVtoVDUP32.ll14
-rw-r--r--test/CodeGen/ARM/2012-08-27-CopyPhysRegCrash.ll129
-rw-r--r--test/CodeGen/ARM/2012-08-30-select.ll18
-rw-r--r--test/CodeGen/ARM/2012-09-18-ARMv4ISelBug.ll11
-rw-r--r--test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll11
-rw-r--r--test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll11
-rw-r--r--test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll56
-rw-r--r--test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll19
-rw-r--r--test/CodeGen/ARM/2012-10-04-LDRB_POST_IMM-Crash.ll16
-rw-r--r--test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll29
-rw-r--r--test/CodeGen/ARM/a15-mla.ll12
-rw-r--r--test/CodeGen/ARM/a15.ll6
-rw-r--r--test/CodeGen/ARM/atomic-op.ll10
-rw-r--r--test/CodeGen/ARM/atomicrmw_minmax.ll21
-rw-r--r--test/CodeGen/ARM/avoid-cpsr-rmw.ll1
-rw-r--r--test/CodeGen/ARM/call-noret-minsize.ll27
-rw-r--r--test/CodeGen/ARM/call-noret.ll31
-rw-r--r--test/CodeGen/ARM/carry.ll13
-rw-r--r--test/CodeGen/ARM/coalesce-subregs.ll294
-rw-r--r--test/CodeGen/ARM/constants.ll12
-rw-r--r--test/CodeGen/ARM/crash-shufflevector.ll10
-rw-r--r--test/CodeGen/ARM/darwin-section-order.ll21
-rw-r--r--test/CodeGen/ARM/deps-fix.ll22
-rw-r--r--test/CodeGen/ARM/div.ll17
-rw-r--r--test/CodeGen/ARM/divmod.ll46
-rw-r--r--test/CodeGen/ARM/domain-conv-vmovs.ll100
-rw-r--r--test/CodeGen/ARM/fabss.ll4
-rw-r--r--test/CodeGen/ARM/fadds.ll8
-rw-r--r--test/CodeGen/ARM/fast-isel-pic.ll61
-rw-r--r--test/CodeGen/ARM/fast-isel.ll66
-rw-r--r--test/CodeGen/ARM/fdivs.ll8
-rw-r--r--test/CodeGen/ARM/fmuls.ll8
-rw-r--r--test/CodeGen/ARM/fp-fast.ll60
-rw-r--r--test/CodeGen/ARM/fp_convert.ll4
-rw-r--r--test/CodeGen/ARM/fsubs.ll6
-rw-r--r--test/CodeGen/ARM/ifcvt1.ll12
-rw-r--r--test/CodeGen/ARM/ifcvt12.ll15
-rw-r--r--test/CodeGen/ARM/ifcvt5.ll12
-rw-r--r--test/CodeGen/ARM/indirectbr-2.ll46
-rw-r--r--test/CodeGen/ARM/integer_insertelement.ll35
-rw-r--r--test/CodeGen/ARM/ldr_post.ll1
-rw-r--r--test/CodeGen/ARM/ldr_pre.ll1
-rw-r--r--test/CodeGen/ARM/longMAC.ll44
-rw-r--r--test/CodeGen/ARM/mls.ll12
-rw-r--r--test/CodeGen/ARM/neon-fma.ll22
-rw-r--r--test/CodeGen/ARM/neon_ld2.ll37
-rw-r--r--test/CodeGen/ARM/opt-shuff-tstore.ll4
-rw-r--r--test/CodeGen/ARM/reg_sequence.ll11
-rw-r--r--test/CodeGen/ARM/select.ll2
-rw-r--r--test/CodeGen/ARM/select_xform.ll65
-rw-r--r--test/CodeGen/ARM/struct_byval.ll44
-rw-r--r--test/CodeGen/ARM/sub-cmp-peephole.ll21
-rw-r--r--test/CodeGen/ARM/sub.ll2
-rw-r--r--test/CodeGen/ARM/subreg-remat.ll4
-rw-r--r--test/CodeGen/ARM/trap.ll12
-rw-r--r--test/CodeGen/ARM/twoaddrinstr.ll16
-rw-r--r--test/CodeGen/ARM/unaligned_load_store.ll18
-rw-r--r--test/CodeGen/ARM/unaligned_load_store_vector.ll487
-rw-r--r--test/CodeGen/ARM/vbsl-constant.ll20
-rw-r--r--test/CodeGen/ARM/vbsl.ll97
-rw-r--r--test/CodeGen/ARM/vdup.ll70
-rw-r--r--test/CodeGen/ARM/vector-extend-narrow.ll11
-rw-r--r--test/CodeGen/ARM/vext.ll33
-rw-r--r--test/CodeGen/ARM/vget_lane.ll2
-rw-r--r--test/CodeGen/ARM/vselect_imax.ll12
71 files changed, 2365 insertions, 146 deletions
diff --git a/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll b/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
index 99db63713d42..36d15757c314 100644
--- a/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
+++ b/test/CodeGen/ARM/2010-10-19-mc-elf-objheader.ll
@@ -13,12 +13,12 @@
; BASIC-NEXT: 0x00000000
; BASIC-NEXT: 0x00000000
; BASIC-NEXT: 0x0000003c
-; BASIC-NEXT: 0x00000020
+; BASIC-NEXT: 0x00000022
; BASIC-NEXT: 0x00000000
; BASIC-NEXT: 0x00000000
; BASIC-NEXT: 0x00000001
; BASIC-NEXT: 0x00000000
-; BASIC-NEXT: '411f0000 00616561 62690001 15000000 06020801 09011401 15011703 18011901'
+; BASIC-NEXT: '41210000 00616561 62690001 17000000 060a0741 08010902 14011501 17031801 1901'
; CORTEXA8: .ARM.attributes
; CORTEXA8-NEXT: 0x70000003
diff --git a/test/CodeGen/ARM/2010-12-07-PEIBug.ll b/test/CodeGen/ARM/2010-12-07-PEIBug.ll
index 770ad4466aff..4879f4e10bac 100644
--- a/test/CodeGen/ARM/2010-12-07-PEIBug.ll
+++ b/test/CodeGen/ARM/2010-12-07-PEIBug.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a9 | FileCheck %s
; rdar://8728956
define hidden void @foo() nounwind ssp {
diff --git a/test/CodeGen/ARM/2011-06-16-TailCallByVal.ll b/test/CodeGen/ARM/2011-06-16-TailCallByVal.ll
index 3e78c4623859..101a91396eb7 100644
--- a/test/CodeGen/ARM/2011-06-16-TailCallByVal.ll
+++ b/test/CodeGen/ARM/2011-06-16-TailCallByVal.ll
@@ -1,4 +1,9 @@
; RUN: llc < %s -arm-tail-calls=1 | FileCheck %s
+
+; tail call inside a function where byval argument is splitted between
+; registers and stack is currently unsupported.
+; XFAIL: *
+
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "thumbv7-apple-ios"
diff --git a/test/CodeGen/ARM/2011-10-26-memset-with-neon.ll b/test/CodeGen/ARM/2011-10-26-memset-with-neon.ll
index 42b14914814a..6e0ef9619657 100644
--- a/test/CodeGen/ARM/2011-10-26-memset-with-neon.ll
+++ b/test/CodeGen/ARM/2011-10-26-memset-with-neon.ll
@@ -9,8 +9,8 @@ entry:
}
; Trigger multiple NEON stores.
-; CHECK: vstmia
-; CHECK-NEXT: vstmia
+; CHECK: vst1.64
+; CHECK-NEXT: vst1.64
define void @f_0_40(i8* nocapture %c) nounwind optsize {
entry:
call void @llvm.memset.p0i8.i64(i8* %c, i8 0, i64 40, i32 16, i1 false)
diff --git a/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll b/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll
index 89c01d58c398..f9ede7401a3c 100644
--- a/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll
+++ b/test/CodeGen/ARM/2011-11-29-128bitArithmetics.ll
@@ -8,12 +8,12 @@ define void @test_sqrt(<4 x float>* %X) nounwind {
; CHECK: movw r1, :lower16:{{.*}}
; CHECK: movt r1, :upper16:{{.*}}
-; CHECK: vldmia r1
+; CHECK: vld1.64 {{.*}}, [r1, :128]
; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}}
; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}}
; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}}
; CHECK: vsqrt.f32 {{s[0-9]+}}, {{s[0-9]+}}
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64 {{.*}}
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -31,21 +31,21 @@ define void @test_cos(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}cosf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}cosf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}cosf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}cosf
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -62,21 +62,21 @@ define void @test_exp(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}expf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}expf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}expf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}expf
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -93,21 +93,21 @@ define void @test_exp2(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}exp2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}exp2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}exp2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}exp2f
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -124,21 +124,21 @@ define void @test_log10(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log10f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log10f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log10f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log10f
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -155,21 +155,21 @@ define void @test_log(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}logf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}logf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}logf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}logf
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -186,21 +186,21 @@ define void @test_log2(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log2f
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}log2f
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -218,21 +218,21 @@ define void @test_pow(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}powf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}powf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}powf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}powf
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
@@ -252,10 +252,10 @@ define void @test_powi(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia [[reg0]], {{.*}}
+; CHECK: vld1.64 {{.*}}, :128
; CHECK: vmul.f32 {{.*}}
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
@@ -275,21 +275,21 @@ define void @test_sin(<4 x float>* %X) nounwind {
; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
; CHECK: movt [[reg0]], :upper16:{{.*}}
-; CHECK: vldmia r{{[0-9][0-9]?}}, {{.*}}
+; CHECK: vld1.64
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}sinf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}sinf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}sinf
-; CHECK: {{[mov|vmov.32]}} r0,
+; CHECK: {{v?mov(.32)?}} r0,
; CHECK: bl {{.*}}sinf
-; CHECK: vstmia {{.*}}
+; CHECK: vst1.64
L.entry:
%0 = load <4 x float>* @A, align 16
@@ -300,3 +300,34 @@ L.entry:
declare <4 x float> @llvm.sin.v4f32(<4 x float>) nounwind readonly
+define void @test_floor(<4 x float>* %X) nounwind {
+
+; CHECK: test_floor:
+
+; CHECK: movw [[reg0:r[0-9]+]], :lower16:{{.*}}
+; CHECK: movt [[reg0]], :upper16:{{.*}}
+; CHECK: vld1.64
+
+; CHECK: {{v?mov(.32)?}} r0,
+; CHECK: bl {{.*}}floorf
+
+; CHECK: {{v?mov(.32)?}} r0,
+; CHECK: bl {{.*}}floorf
+
+; CHECK: {{v?mov(.32)?}} r0,
+; CHECK: bl {{.*}}floorf
+
+; CHECK: {{v?mov(.32)?}} r0,
+; CHECK: bl {{.*}}floorf
+
+; CHECK: vst1.64
+
+L.entry:
+ %0 = load <4 x float>* @A, align 16
+ %1 = call <4 x float> @llvm.floor.v4f32(<4 x float> %0)
+ store <4 x float> %1, <4 x float>* %X, align 16
+ ret void
+}
+
+declare <4 x float> @llvm.floor.v4f32(<4 x float>) nounwind readonly
+
diff --git a/test/CodeGen/ARM/2012-05-04-vmov.ll b/test/CodeGen/ARM/2012-05-04-vmov.ll
new file mode 100644
index 000000000000..d52ef2cc5a1c
--- /dev/null
+++ b/test/CodeGen/ARM/2012-05-04-vmov.ll
@@ -0,0 +1,11 @@
+; RUN: llc -O1 -march=arm -mcpu=cortex-a9 < %s | FileCheck -check-prefix=A9-CHECK %s
+; RUN: llc -O1 -march=arm -mcpu=swift < %s | FileCheck -check-prefix=SWIFT-CHECK %s
+; Check that swift doesn't use vmov.32. <rdar://problem/10453003>.
+
+define <2 x i32> @testuvec(<2 x i32> %A, <2 x i32> %B) nounwind {
+entry:
+ %div = udiv <2 x i32> %A, %B
+ ret <2 x i32> %div
+; A9-CHECK: vmov.32
+; SWIFT-CHECK-NOT: vmov.32
+}
diff --git a/test/CodeGen/ARM/2012-05-10-PreferVMOVtoVDUP32.ll b/test/CodeGen/ARM/2012-05-10-PreferVMOVtoVDUP32.ll
new file mode 100644
index 000000000000..dd678436c04e
--- /dev/null
+++ b/test/CodeGen/ARM/2012-05-10-PreferVMOVtoVDUP32.ll
@@ -0,0 +1,14 @@
+; RUN: llc -march=arm -mcpu=swift < %s | FileCheck %s
+; <rdar://problem/10451892>
+
+define void @f(i32 %x, i32* %p) nounwind ssp {
+entry:
+; CHECK-NOT: vdup.32
+ %vecinit.i = insertelement <2 x i32> undef, i32 %x, i32 0
+ %vecinit1.i = insertelement <2 x i32> %vecinit.i, i32 %x, i32 1
+ %0 = bitcast i32* %p to i8*
+ tail call void @llvm.arm.neon.vst1.v2i32(i8* %0, <2 x i32> %vecinit1.i, i32 4)
+ ret void
+}
+
+declare void @llvm.arm.neon.vst1.v2i32(i8*, <2 x i32>, i32) nounwind
diff --git a/test/CodeGen/ARM/2012-08-27-CopyPhysRegCrash.ll b/test/CodeGen/ARM/2012-08-27-CopyPhysRegCrash.ll
new file mode 100644
index 000000000000..ec7f72d7c2e8
--- /dev/null
+++ b/test/CodeGen/ARM/2012-08-27-CopyPhysRegCrash.ll
@@ -0,0 +1,129 @@
+; RUN: llc < %s -mcpu=cortex-a8 -march=thumb
+; Test that this doesn't crash.
+; <rdar://problem/12183003>
+
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
+target triple = "thumbv7-apple-ios5.1.0"
+
+declare { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld3.v16i8(i8*, i32) nounwind readonly
+
+declare void @llvm.arm.neon.vst1.v16i8(i8*, <16 x i8>, i32) nounwind
+
+define void @findEdges(i8*) nounwind ssp {
+ %2 = icmp sgt i32 undef, 0
+ br i1 %2, label %5, label %3
+
+; <label>:3 ; preds = %5, %1
+ %4 = phi i8* [ %0, %1 ], [ %19, %5 ]
+ ret void
+
+; <label>:5 ; preds = %5, %1
+ %6 = phi i8* [ %19, %5 ], [ %0, %1 ]
+ %7 = tail call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld3.v16i8(i8* null, i32 1)
+ %8 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %7, 0
+ %9 = getelementptr inbounds i8* null, i32 3
+ %10 = tail call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld3.v16i8(i8* %9, i32 1)
+ %11 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %10, 2
+ %12 = tail call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld3.v16i8(i8* %6, i32 1)
+ %13 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %12, 0
+ %14 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %12, 1
+ %15 = getelementptr inbounds i8* %6, i32 3
+ %16 = tail call { <16 x i8>, <16 x i8>, <16 x i8> } @llvm.arm.neon.vld3.v16i8(i8* %15, i32 1)
+ %17 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %16, 1
+ %18 = extractvalue { <16 x i8>, <16 x i8>, <16 x i8> } %16, 2
+ %19 = getelementptr inbounds i8* %6, i32 48
+ %20 = bitcast <16 x i8> %13 to <2 x i64>
+ %21 = bitcast <16 x i8> %8 to <2 x i64>
+ %22 = bitcast <16 x i8> %14 to <2 x i64>
+ %23 = shufflevector <2 x i64> %22, <2 x i64> undef, <1 x i32> zeroinitializer
+ %24 = bitcast <1 x i64> %23 to <8 x i8>
+ %25 = zext <8 x i8> %24 to <8 x i16>
+ %26 = sub <8 x i16> zeroinitializer, %25
+ %27 = bitcast <16 x i8> %17 to <2 x i64>
+ %28 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %26) nounwind
+ %29 = mul <8 x i16> %28, %28
+ %30 = add <8 x i16> zeroinitializer, %29
+ %31 = tail call <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16> undef, <8 x i16> %30) nounwind
+ %32 = bitcast <16 x i8> %11 to <2 x i64>
+ %33 = shufflevector <2 x i64> %32, <2 x i64> undef, <1 x i32> zeroinitializer
+ %34 = bitcast <1 x i64> %33 to <8 x i8>
+ %35 = zext <8 x i8> %34 to <8 x i16>
+ %36 = sub <8 x i16> %35, zeroinitializer
+ %37 = bitcast <16 x i8> %18 to <2 x i64>
+ %38 = shufflevector <2 x i64> %37, <2 x i64> undef, <1 x i32> zeroinitializer
+ %39 = bitcast <1 x i64> %38 to <8 x i8>
+ %40 = zext <8 x i8> %39 to <8 x i16>
+ %41 = sub <8 x i16> zeroinitializer, %40
+ %42 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %36) nounwind
+ %43 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %41) nounwind
+ %44 = mul <8 x i16> %42, %42
+ %45 = mul <8 x i16> %43, %43
+ %46 = add <8 x i16> %45, %44
+ %47 = tail call <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16> %31, <8 x i16> %46) nounwind
+ %48 = bitcast <8 x i16> %47 to <2 x i64>
+ %49 = shufflevector <2 x i64> %48, <2 x i64> undef, <1 x i32> zeroinitializer
+ %50 = bitcast <1 x i64> %49 to <4 x i16>
+ %51 = tail call <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16> %50, <4 x i16> undef) nounwind
+ %52 = tail call <4 x i16> @llvm.arm.neon.vqshiftnu.v4i16(<4 x i32> %51, <4 x i32> <i32 -6, i32 -6, i32 -6, i32 -6>)
+ %53 = bitcast <4 x i16> %52 to <1 x i64>
+ %54 = shufflevector <1 x i64> %53, <1 x i64> undef, <2 x i32> <i32 0, i32 1>
+ %55 = bitcast <2 x i64> %54 to <8 x i16>
+ %56 = tail call <8 x i8> @llvm.arm.neon.vshiftn.v8i8(<8 x i16> %55, <8 x i16> <i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8>)
+ %57 = shufflevector <2 x i64> %20, <2 x i64> undef, <1 x i32> <i32 1>
+ %58 = bitcast <1 x i64> %57 to <8 x i8>
+ %59 = zext <8 x i8> %58 to <8 x i16>
+ %60 = sub <8 x i16> zeroinitializer, %59
+ %61 = shufflevector <2 x i64> %21, <2 x i64> undef, <1 x i32> <i32 1>
+ %62 = bitcast <1 x i64> %61 to <8 x i8>
+ %63 = zext <8 x i8> %62 to <8 x i16>
+ %64 = sub <8 x i16> %63, zeroinitializer
+ %65 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %60) nounwind
+ %66 = mul <8 x i16> %65, %65
+ %67 = add <8 x i16> zeroinitializer, %66
+ %68 = shufflevector <2 x i64> %27, <2 x i64> undef, <1 x i32> <i32 1>
+ %69 = bitcast <1 x i64> %68 to <8 x i8>
+ %70 = zext <8 x i8> %69 to <8 x i16>
+ %71 = sub <8 x i16> zeroinitializer, %70
+ %72 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> undef) nounwind
+ %73 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %71) nounwind
+ %74 = mul <8 x i16> %72, %72
+ %75 = mul <8 x i16> %73, %73
+ %76 = add <8 x i16> %75, %74
+ %77 = shufflevector <2 x i64> %32, <2 x i64> undef, <1 x i32> <i32 1>
+ %78 = bitcast <1 x i64> %77 to <8 x i8>
+ %79 = zext <8 x i8> %78 to <8 x i16>
+ %80 = sub <8 x i16> %79, zeroinitializer
+ %81 = tail call <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16> %80) nounwind
+ %82 = mul <8 x i16> %81, %81
+ %83 = add <8 x i16> zeroinitializer, %82
+ %84 = tail call <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16> %76, <8 x i16> %83) nounwind
+ %85 = tail call <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16> %67, <8 x i16> %84) nounwind
+ %86 = bitcast <8 x i16> %85 to <2 x i64>
+ %87 = shufflevector <2 x i64> %86, <2 x i64> undef, <1 x i32> <i32 1>
+ %88 = bitcast <1 x i64> %87 to <4 x i16>
+ %89 = tail call <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16> %88, <4 x i16> undef) nounwind
+ %90 = tail call <4 x i16> @llvm.arm.neon.vqrshiftnu.v4i16(<4 x i32> %89, <4 x i32> <i32 -6, i32 -6, i32 -6, i32 -6>)
+ %91 = bitcast <4 x i16> %90 to <1 x i64>
+ %92 = shufflevector <1 x i64> undef, <1 x i64> %91, <2 x i32> <i32 0, i32 1>
+ %93 = bitcast <2 x i64> %92 to <8 x i16>
+ %94 = tail call <8 x i8> @llvm.arm.neon.vshiftn.v8i8(<8 x i16> %93, <8 x i16> <i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8, i16 -8>)
+ %95 = bitcast <8 x i8> %56 to <1 x i64>
+ %96 = bitcast <8 x i8> %94 to <1 x i64>
+ %97 = shufflevector <1 x i64> %95, <1 x i64> %96, <2 x i32> <i32 0, i32 1>
+ %98 = bitcast <2 x i64> %97 to <16 x i8>
+ tail call void @llvm.arm.neon.vst1.v16i8(i8* null, <16 x i8> %98, i32 1)
+ %99 = icmp slt i32 undef, undef
+ br i1 %99, label %5, label %3
+}
+
+declare <4 x i16> @llvm.arm.neon.vqshiftnu.v4i16(<4 x i32>, <4 x i32>) nounwind readnone
+
+declare <8 x i8> @llvm.arm.neon.vshiftn.v8i8(<8 x i16>, <8 x i16>) nounwind readnone
+
+declare <4 x i16> @llvm.arm.neon.vqrshiftnu.v4i16(<4 x i32>, <4 x i32>) nounwind readnone
+
+declare <4 x i32> @llvm.arm.neon.vmullu.v4i32(<4 x i16>, <4 x i16>) nounwind readnone
+
+declare <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16>, <8 x i16>) nounwind readnone
+
+declare <8 x i16> @llvm.arm.neon.vabs.v8i16(<8 x i16>) nounwind readnone
diff --git a/test/CodeGen/ARM/2012-08-30-select.ll b/test/CodeGen/ARM/2012-08-30-select.ll
new file mode 100644
index 000000000000..8471be5330b8
--- /dev/null
+++ b/test/CodeGen/ARM/2012-08-30-select.ll
@@ -0,0 +1,18 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s
+; rdar://12201387
+
+;CHECK: select_s_v_v
+;CHECK: it ne
+;CHECK-NEXT: vmovne.i32
+;CHECK: bx
+define <16 x i8> @select_s_v_v(i32 %avail, i8* %bar) {
+entry:
+ %vld1 = call <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* %bar, i32 1)
+ %and = and i32 %avail, 1
+ %tobool = icmp eq i32 %and, 0
+ %vld1. = select i1 %tobool, <16 x i8> %vld1, <16 x i8> zeroinitializer
+ ret <16 x i8> %vld1.
+}
+
+declare <16 x i8> @llvm.arm.neon.vld1.v16i8(i8* , i32 )
+
diff --git a/test/CodeGen/ARM/2012-09-18-ARMv4ISelBug.ll b/test/CodeGen/ARM/2012-09-18-ARMv4ISelBug.ll
new file mode 100644
index 000000000000..e761ffe72c13
--- /dev/null
+++ b/test/CodeGen/ARM/2012-09-18-ARMv4ISelBug.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=arm -mcpu=arm7tdmi | FileCheck %s
+
+; movw is only legal for V6T2 and later.
+; rdar://12300648
+
+define i32 @t(i32 %x) {
+; CHECK: t:
+; CHECK-NOT: movw
+ %tmp = add i32 %x, -65535
+ ret i32 %tmp
+}
diff --git a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll
new file mode 100644
index 000000000000..75766099a220
--- /dev/null
+++ b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a8 2>&1 | FileCheck %s
+
+; Check for error message:
+; CHECK: non-trivial scalar-to-vector conversion, possible invalid constraint for vector type
+
+define void @f() nounwind ssp {
+ %1 = call { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } asm "vldm $4, { ${0:q}, ${1:q}, ${2:q}, ${3:q} }", "=r,=r,=r,=r,r"(i64* undef) nounwind, !srcloc !0
+ ret void
+}
+
+!0 = metadata !{i32 318437}
diff --git a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
new file mode 100644
index 000000000000..6fa1391474bb
--- /dev/null
+++ b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a8 2>&1 | FileCheck %s
+
+; Check for error message:
+; CHECK: scalar-to-vector conversion failed, possible invalid constraint for vector type
+
+define hidden void @f(i32* %corr, i32 %order) nounwind ssp {
+ tail call void asm sideeffect "vst1.s32 { ${1:q}, ${2:q} }, [$0]", "r,{q0},{q1}"(i32* %corr, <2 x i64>* undef, <2 x i64>* undef) nounwind, !srcloc !0
+ ret void
+}
+
+!0 = metadata !{i32 257}
diff --git a/test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll b/test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll
new file mode 100644
index 000000000000..b5f6d311cb9c
--- /dev/null
+++ b/test/CodeGen/ARM/2012-10-04-AAPCS-byval-align8.ll
@@ -0,0 +1,56 @@
+; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi | FileCheck %s
+; Test that we correctly use registers and align elements when using va_arg
+
+%struct_t = type { double, double, double }
+@static_val = constant %struct_t { double 1.0, double 2.0, double 3.0 }
+
+declare void @llvm.va_start(i8*) nounwind
+declare void @llvm.va_end(i8*) nounwind
+
+; CHECK: test_byval_8_bytes_alignment:
+define void @test_byval_8_bytes_alignment(i32 %i, ...) {
+entry:
+; CHECK: stm r0, {r1, r2, r3}
+ %g = alloca i8*
+ %g1 = bitcast i8** %g to i8*
+ call void @llvm.va_start(i8* %g1)
+
+; CHECK: add [[REG:(r[0-9]+)|(lr)]], {{(r[0-9]+)|(lr)}}, #7
+; CHECK: bfc [[REG]], #0, #3
+ %0 = va_arg i8** %g, double
+ call void @llvm.va_end(i8* %g1)
+
+ ret void
+}
+
+; CHECK: main:
+; CHECK: ldm r0, {r2, r3}
+define i32 @main() {
+entry:
+ call void (i32, ...)* @test_byval_8_bytes_alignment(i32 555, %struct_t* byval @static_val)
+ ret i32 0
+}
+
+declare void @f(double);
+
+; CHECK: test_byval_8_bytes_alignment_fixed_arg:
+; CHECK-NOT: str r1
+; CHECK: str r3, [sp, #12]
+; CHECK: str r2, [sp, #8]
+; CHECK-NOT: str r1
+define void @test_byval_8_bytes_alignment_fixed_arg(i32 %n1, %struct_t* byval %val) nounwind {
+entry:
+ %a = getelementptr inbounds %struct_t* %val, i32 0, i32 0
+ %0 = load double* %a
+ call void (double)* @f(double %0)
+ ret void
+}
+
+; CHECK: main_fixed_arg:
+; CHECK: ldm r0, {r2, r3}
+define i32 @main_fixed_arg() {
+entry:
+ call void (i32, %struct_t*)* @test_byval_8_bytes_alignment_fixed_arg(i32 555, %struct_t* byval @static_val)
+ ret i32 0
+}
+
diff --git a/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll b/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll
new file mode 100644
index 000000000000..478048d09600
--- /dev/null
+++ b/test/CodeGen/ARM/2012-10-04-FixedFrame-vs-byval.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi | FileCheck %s
+
+@.str = private unnamed_addr constant [12 x i8] c"val.a = %f\0A\00"
+%struct_t = type { double, double, double }
+@static_val = constant %struct_t { double 1.0, double 2.0, double 3.0 }
+
+declare i32 @printf(i8*, ...)
+
+; CHECK: test_byval_usage_scheduling:
+; CHECK: str r3, [sp, #12]
+; CHECK: str r2, [sp, #8]
+; CHECK: vldr d16, [sp, #8]
+define void @test_byval_usage_scheduling(i32 %n1, i32 %n2, %struct_t* byval %val) nounwind {
+entry:
+ %a = getelementptr inbounds %struct_t* %val, i32 0, i32 0
+ %0 = load double* %a
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i32 0, i32 0), double %0)
+ ret void
+}
diff --git a/test/CodeGen/ARM/2012-10-04-LDRB_POST_IMM-Crash.ll b/test/CodeGen/ARM/2012-10-04-LDRB_POST_IMM-Crash.ll
new file mode 100644
index 000000000000..f2395107d426
--- /dev/null
+++ b/test/CodeGen/ARM/2012-10-04-LDRB_POST_IMM-Crash.ll
@@ -0,0 +1,16 @@
+; RUN: llc < %s -mtriple=armv7-none-linux- | FileCheck %s
+; Check that LDRB_POST_IMM instruction emitted properly.
+
+%my_struct_t = type { i8, i8, i8, i8, i8 }
+@main.val = private unnamed_addr constant %my_struct_t { i8 1, i8 2, i8 3, i8 4, i8 5 }
+
+declare void @f(i32 %n1, i32 %n2, i32 %n3, %my_struct_t* byval %val);
+
+; CHECK: main:
+define i32 @main() nounwind {
+entry:
+; CHECK: ldrb {{(r[0-9]+)}}, {{(\[r[0-9]+\])}}, #1
+ call void @f(i32 555, i32 555, i32 555, %my_struct_t* byval @main.val)
+ ret i32 0
+}
+
diff --git a/test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll b/test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll
new file mode 100644
index 000000000000..fcc6a7f7e96f
--- /dev/null
+++ b/test/CodeGen/ARM/2012-10-18-PR14099-ByvalFrameAddress.ll
@@ -0,0 +1,29 @@
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi | FileCheck %s
+
+%struct.s = type { [4 x i32] }
+@v = constant %struct.s zeroinitializer;
+
+declare void @f(%struct.s* %p);
+
+; CHECK: t:
+define void @t(i32 %a, %struct.s* byval %s) nounwind {
+entry:
+
+; Here we need to only check proper start address of restored %s argument.
+; CHECK: sub sp, sp, #16
+; CHECK: push {r11, lr}
+; CHECK: add r0, sp, #12
+; CHECK: stm r0, {r1, r2, r3}
+; CHECK: add r0, sp, #12
+; CHECK-NEXT: bl f
+ call void @f(%struct.s* %s)
+ ret void
+}
+
+; CHECK: caller:
+define void @caller() {
+
+; CHECK: ldm r0, {r1, r2, r3}
+ call void @t(i32 0, %struct.s* @v);
+ ret void
+}
diff --git a/test/CodeGen/ARM/a15-mla.ll b/test/CodeGen/ARM/a15-mla.ll
new file mode 100644
index 000000000000..25f6de4762d5
--- /dev/null
+++ b/test/CodeGen/ARM/a15-mla.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -march=arm -float-abi=hard -mcpu=cortex-a15 -mattr=+neon,+neonfp | FileCheck %s
+
+; This test checks that the VMLxForwarting feature is disabled for A15.
+; CHECK: fun_a
+define <4 x i32> @fun_a(<4 x i32> %x, <4 x i32> %y) nounwind{
+ %1 = add <4 x i32> %x, %y
+; CHECK-NOT: vmul
+; CHECK: vmla
+ %2 = mul <4 x i32> %1, %1
+ %3 = add <4 x i32> %y, %2
+ ret <4 x i32> %3
+}
diff --git a/test/CodeGen/ARM/a15.ll b/test/CodeGen/ARM/a15.ll
new file mode 100644
index 000000000000..6f816c1c2c53
--- /dev/null
+++ b/test/CodeGen/ARM/a15.ll
@@ -0,0 +1,6 @@
+; RUN: llc < %s -mcpu=cortex-a15 | FileCheck %s
+
+; CHECK: a
+define i32 @a(i32 %x) {
+ ret i32 %x;
+}
diff --git a/test/CodeGen/ARM/atomic-op.ll b/test/CodeGen/ARM/atomic-op.ll
index 8967730835a5..6e6b36377fde 100644
--- a/test/CodeGen/ARM/atomic-op.ll
+++ b/test/CodeGen/ARM/atomic-op.ll
@@ -159,3 +159,13 @@ entry:
store i8 %3, i8* %old
ret void
}
+
+; CHECK: func4
+; This function should not need to use callee-saved registers.
+; rdar://problem/12203728
+; CHECK-NOT: r4
+define i32 @func4(i32* %p) nounwind optsize ssp {
+entry:
+ %0 = atomicrmw add i32* %p, i32 1 monotonic
+ ret i32 %0
+}
diff --git a/test/CodeGen/ARM/atomicrmw_minmax.ll b/test/CodeGen/ARM/atomicrmw_minmax.ll
new file mode 100644
index 000000000000..69f1384e125c
--- /dev/null
+++ b/test/CodeGen/ARM/atomicrmw_minmax.ll
@@ -0,0 +1,21 @@
+; RUN: llc -march=arm -mcpu=cortex-a9 < %s | FileCheck %s
+
+; CHECK: max:
+define i32 @max(i8 %ctx, i32* %ptr, i32 %val)
+{
+; CHECK: ldrex
+; CHECK: cmp [[old:r[0-9]*]], [[val:r[0-9]*]]
+; CHECK: movhi {{r[0-9]*}}, [[old]]
+ %old = atomicrmw umax i32* %ptr, i32 %val monotonic
+ ret i32 %old
+}
+
+; CHECK: min:
+define i32 @min(i8 %ctx, i32* %ptr, i32 %val)
+{
+; CHECK: ldrex
+; CHECK: cmp [[old:r[0-9]*]], [[val:r[0-9]*]]
+; CHECK: movlo {{r[0-9]*}}, [[old]]
+ %old = atomicrmw umin i32* %ptr, i32 %val monotonic
+ ret i32 %old
+}
diff --git a/test/CodeGen/ARM/avoid-cpsr-rmw.ll b/test/CodeGen/ARM/avoid-cpsr-rmw.ll
index 1b385ab79c4e..96e83dd88e92 100644
--- a/test/CodeGen/ARM/avoid-cpsr-rmw.ll
+++ b/test/CodeGen/ARM/avoid-cpsr-rmw.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a9 | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=swift | FileCheck %s
; Avoid some 's' 16-bit instruction which partially update CPSR (and add false
; dependency) when it isn't dependent on last CPSR defining instruction.
; rdar://8928208
diff --git a/test/CodeGen/ARM/call-noret-minsize.ll b/test/CodeGen/ARM/call-noret-minsize.ll
new file mode 100644
index 000000000000..df3c19eca6a0
--- /dev/null
+++ b/test/CodeGen/ARM/call-noret-minsize.ll
@@ -0,0 +1,27 @@
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=cortex-a8 | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT
+; rdar://12348580
+
+define void @t1() noreturn minsize nounwind ssp {
+entry:
+; ARM: t1:
+; ARM: bl _bar
+
+; SWIFT: t1:
+; SWIFT: bl _bar
+ tail call void @bar() noreturn nounwind
+ unreachable
+}
+
+define void @t2() noreturn minsize nounwind ssp {
+entry:
+; ARM: t2:
+; ARM: bl _t1
+
+; SWIFT: t2:
+; SWIFT: bl _t1
+ tail call void @t1() noreturn nounwind
+ unreachable
+}
+
+declare void @bar() noreturn
diff --git a/test/CodeGen/ARM/call-noret.ll b/test/CodeGen/ARM/call-noret.ll
new file mode 100644
index 000000000000..27062dca38dc
--- /dev/null
+++ b/test/CodeGen/ARM/call-noret.ll
@@ -0,0 +1,31 @@
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=cortex-a8 | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT
+; rdar://8979299
+
+define void @t1() noreturn nounwind ssp {
+entry:
+; ARM: t1:
+; ARM: mov lr, pc
+; ARM: b _bar
+
+; SWIFT: t1:
+; SWIFT: mov lr, pc
+; SWIFT: b _bar
+ tail call void @bar() noreturn nounwind
+ unreachable
+}
+
+define void @t2() noreturn nounwind ssp {
+entry:
+; ARM: t2:
+; ARM: mov lr, pc
+; ARM: b _t1
+
+; SWIFT: t2:
+; SWIFT: mov lr, pc
+; SWIFT: b _t1
+ tail call void @t1() noreturn nounwind
+ unreachable
+}
+
+declare void @bar() noreturn
diff --git a/test/CodeGen/ARM/carry.ll b/test/CodeGen/ARM/carry.ll
index f84774d9b615..bf51cd627b3c 100644
--- a/test/CodeGen/ARM/carry.ll
+++ b/test/CodeGen/ARM/carry.ll
@@ -45,3 +45,16 @@ entry:
%0 = sub nsw i64 0, %x
ret i64 %0
}
+
+; rdar://12559385
+define i64 @f5(i32 %vi) {
+entry:
+; CHECK: f5:
+; CHECK: movw [[REG:r[0-9]+]], #36102
+; CHECK: sbc r{{[0-9]+}}, r{{[0-9]+}}, [[REG]]
+ %v0 = zext i32 %vi to i64
+ %v1 = xor i64 %v0, -155057456198619
+ %v4 = add i64 %v1, 155057456198619
+ %v5 = add i64 %v4, %v1
+ ret i64 %v5
+}
diff --git a/test/CodeGen/ARM/coalesce-subregs.ll b/test/CodeGen/ARM/coalesce-subregs.ll
index fb0f4c67c927..3ba947579a3a 100644
--- a/test/CodeGen/ARM/coalesce-subregs.ll
+++ b/test/CodeGen/ARM/coalesce-subregs.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mcpu=cortex-a9 | FileCheck %s
+; RUN: llc < %s -mcpu=cortex-a9 -verify-coalescing -verify-machineinstrs | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
target triple = "thumbv7-apple-ios0.0.0"
@@ -66,3 +66,295 @@ do.end: ; preds = %do.body
declare { <4 x float>, <4 x float> } @llvm.arm.neon.vld2.v4f32(i8*, i32) nounwind readonly
declare void @llvm.arm.neon.vst2.v4f32(i8*, <4 x float>, <4 x float>, i32) nounwind
+
+; CHECK: f3
+; This function has lane insertions that span basic blocks.
+; The trivial REG_SEQUENCE lowering can't handle that, but the coalescer can.
+;
+; void f3(float *p, float *q) {
+; float32x2_t x;
+; x[1] = p[3];
+; if (q)
+; x[0] = q[0] + q[1];
+; else
+; x[0] = p[2];
+; vst1_f32(p+4, x);
+; }
+;
+; CHECK-NOT: vmov
+; CHECK-NOT: vorr
+define void @f3(float* %p, float* %q) nounwind ssp {
+entry:
+ %arrayidx = getelementptr inbounds float* %p, i32 3
+ %0 = load float* %arrayidx, align 4
+ %vecins = insertelement <2 x float> undef, float %0, i32 1
+ %tobool = icmp eq float* %q, null
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ %1 = load float* %q, align 4
+ %arrayidx2 = getelementptr inbounds float* %q, i32 1
+ %2 = load float* %arrayidx2, align 4
+ %add = fadd float %1, %2
+ %vecins3 = insertelement <2 x float> %vecins, float %add, i32 0
+ br label %if.end
+
+if.else: ; preds = %entry
+ %arrayidx4 = getelementptr inbounds float* %p, i32 2
+ %3 = load float* %arrayidx4, align 4
+ %vecins5 = insertelement <2 x float> %vecins, float %3, i32 0
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ %x.0 = phi <2 x float> [ %vecins3, %if.then ], [ %vecins5, %if.else ]
+ %add.ptr = getelementptr inbounds float* %p, i32 4
+ %4 = bitcast float* %add.ptr to i8*
+ tail call void @llvm.arm.neon.vst1.v2f32(i8* %4, <2 x float> %x.0, i32 4)
+ ret void
+}
+
+declare void @llvm.arm.neon.vst1.v2f32(i8*, <2 x float>, i32) nounwind
+declare <2 x float> @llvm.arm.neon.vld1.v2f32(i8*, i32) nounwind readonly
+
+; CHECK: f4
+; This function inserts a lane into a fully defined vector.
+; The destination lane isn't read, so the subregs can coalesce.
+; CHECK-NOT: vmov
+; CHECK-NOT: vorr
+define void @f4(float* %p, float* %q) nounwind ssp {
+entry:
+ %0 = bitcast float* %p to i8*
+ %vld1 = tail call <2 x float> @llvm.arm.neon.vld1.v2f32(i8* %0, i32 4)
+ %tobool = icmp eq float* %q, null
+ br i1 %tobool, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %1 = load float* %q, align 4
+ %arrayidx1 = getelementptr inbounds float* %q, i32 1
+ %2 = load float* %arrayidx1, align 4
+ %add = fadd float %1, %2
+ %vecins = insertelement <2 x float> %vld1, float %add, i32 1
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ %x.0 = phi <2 x float> [ %vecins, %if.then ], [ %vld1, %entry ]
+ tail call void @llvm.arm.neon.vst1.v2f32(i8* %0, <2 x float> %x.0, i32 4)
+ ret void
+}
+
+; CHECK: f5
+; Coalesce vector lanes through phis.
+; CHECK: vmov.f32 {{.*}}, #1.0
+; CHECK-NOT: vmov
+; CHECK-NOT: vorr
+; CHECK: %if.end
+; We may leave the last insertelement in the if.end block.
+; It is inserting the %add value into a dead lane, but %add causes interference
+; in the entry block, and we don't do dead lane checks across basic blocks.
+define void @f5(float* %p, float* %q) nounwind ssp {
+entry:
+ %0 = bitcast float* %p to i8*
+ %vld1 = tail call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %0, i32 4)
+ %vecext = extractelement <4 x float> %vld1, i32 0
+ %vecext1 = extractelement <4 x float> %vld1, i32 1
+ %vecext2 = extractelement <4 x float> %vld1, i32 2
+ %vecext3 = extractelement <4 x float> %vld1, i32 3
+ %add = fadd float %vecext3, 1.000000e+00
+ %tobool = icmp eq float* %q, null
+ br i1 %tobool, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ %arrayidx = getelementptr inbounds float* %q, i32 1
+ %1 = load float* %arrayidx, align 4
+ %add4 = fadd float %vecext, %1
+ %2 = load float* %q, align 4
+ %add6 = fadd float %vecext1, %2
+ %arrayidx7 = getelementptr inbounds float* %q, i32 2
+ %3 = load float* %arrayidx7, align 4
+ %add8 = fadd float %vecext2, %3
+ br label %if.end
+
+if.end: ; preds = %entry, %if.then
+ %a.0 = phi float [ %add4, %if.then ], [ %vecext, %entry ]
+ %b.0 = phi float [ %add6, %if.then ], [ %vecext1, %entry ]
+ %c.0 = phi float [ %add8, %if.then ], [ %vecext2, %entry ]
+ %vecinit = insertelement <4 x float> undef, float %a.0, i32 0
+ %vecinit9 = insertelement <4 x float> %vecinit, float %b.0, i32 1
+ %vecinit10 = insertelement <4 x float> %vecinit9, float %c.0, i32 2
+ %vecinit11 = insertelement <4 x float> %vecinit10, float %add, i32 3
+ tail call void @llvm.arm.neon.vst1.v4f32(i8* %0, <4 x float> %vecinit11, i32 4)
+ ret void
+}
+
+declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly
+
+declare void @llvm.arm.neon.vst1.v4f32(i8*, <4 x float>, i32) nounwind
+
+; CHECK: pr13999
+define void @pr13999() nounwind readonly {
+entry:
+ br i1 true, label %outer_loop, label %loop.end
+
+outer_loop:
+ %d = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ %0 = insertelement <2 x double> <double 0.0, double 0.0>, double %d, i32 0
+ br i1 undef, label %after_inner_loop, label %inner_loop
+
+inner_loop:
+ br i1 true, label %after_inner_loop, label %inner_loop
+
+after_inner_loop:
+ %1 = phi <2 x double> [ %0, %outer_loop ], [ <double 0.0, double 0.0>,
+%inner_loop ]
+ %2 = extractelement <2 x double> %1, i32 1
+ %add = fadd double 1.0, %2
+ br i1 false, label %loop.end, label %outer_loop
+
+loop.end:
+ %d.end = phi double [ 0.0, %entry ], [ %add, %after_inner_loop ]
+ ret void
+}
+
+; CHECK: pr14078
+define arm_aapcs_vfpcc i32 @pr14078(i8* nocapture %arg, i8* nocapture %arg1, i32 %arg2) nounwind uwtable readonly {
+bb:
+ br i1 undef, label %bb31, label %bb3
+
+bb3: ; preds = %bb12, %bb
+ %tmp = shufflevector <2 x i64> undef, <2 x i64> undef, <1 x i32> zeroinitializer
+ %tmp4 = bitcast <1 x i64> %tmp to <2 x float>
+ %tmp5 = shufflevector <2 x float> %tmp4, <2 x float> undef, <4 x i32> zeroinitializer
+ %tmp6 = bitcast <4 x float> %tmp5 to <2 x i64>
+ %tmp7 = shufflevector <2 x i64> %tmp6, <2 x i64> undef, <1 x i32> zeroinitializer
+ %tmp8 = bitcast <1 x i64> %tmp7 to <2 x float>
+ %tmp9 = tail call <2 x float> @baz(<2 x float> <float 0xFFFFFFFFE0000000, float 0.000000e+00>, <2 x float> %tmp8, <2 x float> zeroinitializer) nounwind
+ br i1 undef, label %bb10, label %bb12
+
+bb10: ; preds = %bb3
+ %tmp11 = load <4 x float>* undef, align 8
+ br label %bb12
+
+bb12: ; preds = %bb10, %bb3
+ %tmp13 = shufflevector <2 x float> %tmp9, <2 x float> zeroinitializer, <2 x i32> <i32 0, i32 2>
+ %tmp14 = bitcast <2 x float> %tmp13 to <1 x i64>
+ %tmp15 = shufflevector <1 x i64> %tmp14, <1 x i64> zeroinitializer, <2 x i32> <i32 0, i32 1>
+ %tmp16 = bitcast <2 x i64> %tmp15 to <4 x float>
+ %tmp17 = fmul <4 x float> zeroinitializer, %tmp16
+ %tmp18 = bitcast <4 x float> %tmp17 to <2 x i64>
+ %tmp19 = shufflevector <2 x i64> %tmp18, <2 x i64> undef, <1 x i32> zeroinitializer
+ %tmp20 = bitcast <1 x i64> %tmp19 to <2 x float>
+ %tmp21 = tail call <2 x float> @baz67(<2 x float> %tmp20, <2 x float> undef) nounwind
+ %tmp22 = tail call <2 x float> @baz67(<2 x float> %tmp21, <2 x float> %tmp21) nounwind
+ %tmp23 = shufflevector <2 x float> %tmp22, <2 x float> undef, <4 x i32> zeroinitializer
+ %tmp24 = bitcast <4 x float> %tmp23 to <2 x i64>
+ %tmp25 = shufflevector <2 x i64> %tmp24, <2 x i64> undef, <1 x i32> zeroinitializer
+ %tmp26 = bitcast <1 x i64> %tmp25 to <2 x float>
+ %tmp27 = extractelement <2 x float> %tmp26, i32 0
+ %tmp28 = fcmp olt float %tmp27, 0.000000e+00
+ %tmp29 = select i1 %tmp28, i32 0, i32 undef
+ %tmp30 = icmp ult i32 undef, %arg2
+ br i1 %tmp30, label %bb3, label %bb31
+
+bb31: ; preds = %bb12, %bb
+ %tmp32 = phi i32 [ 1, %bb ], [ %tmp29, %bb12 ]
+ ret i32 %tmp32
+}
+
+declare <2 x float> @baz(<2 x float>, <2 x float>, <2 x float>) nounwind readnone
+
+declare <2 x float> @baz67(<2 x float>, <2 x float>) nounwind readnone
+
+%struct.wombat.5 = type { %struct.quux, %struct.quux, %struct.quux, %struct.quux }
+%struct.quux = type { <4 x float> }
+
+; CHECK: pr14079
+define linkonce_odr arm_aapcs_vfpcc %struct.wombat.5 @pr14079(i8* nocapture %arg, i8* nocapture %arg1, i8* nocapture %arg2) nounwind uwtable inlinehint {
+bb:
+ %tmp = shufflevector <2 x i64> zeroinitializer, <2 x i64> undef, <1 x i32> zeroinitializer
+ %tmp3 = bitcast <1 x i64> %tmp to <2 x float>
+ %tmp4 = shufflevector <2 x float> %tmp3, <2 x float> zeroinitializer, <2 x i32> <i32 1, i32 3>
+ %tmp5 = shufflevector <2 x float> %tmp4, <2 x float> undef, <2 x i32> <i32 1, i32 3>
+ %tmp6 = bitcast <2 x float> %tmp5 to <1 x i64>
+ %tmp7 = shufflevector <1 x i64> undef, <1 x i64> %tmp6, <2 x i32> <i32 0, i32 1>
+ %tmp8 = bitcast <2 x i64> %tmp7 to <4 x float>
+ %tmp9 = shufflevector <2 x i64> zeroinitializer, <2 x i64> undef, <1 x i32> <i32 1>
+ %tmp10 = bitcast <1 x i64> %tmp9 to <2 x float>
+ %tmp11 = shufflevector <2 x float> %tmp10, <2 x float> undef, <2 x i32> <i32 0, i32 2>
+ %tmp12 = shufflevector <2 x float> %tmp11, <2 x float> undef, <2 x i32> <i32 0, i32 2>
+ %tmp13 = bitcast <2 x float> %tmp12 to <1 x i64>
+ %tmp14 = shufflevector <1 x i64> %tmp13, <1 x i64> undef, <2 x i32> <i32 0, i32 1>
+ %tmp15 = bitcast <2 x i64> %tmp14 to <4 x float>
+ %tmp16 = insertvalue %struct.wombat.5 undef, <4 x float> %tmp8, 1, 0
+ %tmp17 = insertvalue %struct.wombat.5 %tmp16, <4 x float> %tmp15, 2, 0
+ %tmp18 = insertvalue %struct.wombat.5 %tmp17, <4 x float> undef, 3, 0
+ ret %struct.wombat.5 %tmp18
+}
+
+; CHECK: adjustCopiesBackFrom
+; The shuffle in if.else3 must be preserved even though adjustCopiesBackFrom
+; is tempted to remove it.
+; CHECK: %if.else3
+; CHECK: vorr d
+define internal void @adjustCopiesBackFrom(<2 x i64>* noalias nocapture sret %agg.result, <2 x i64> %in) {
+entry:
+ %0 = extractelement <2 x i64> %in, i32 0
+ %cmp = icmp slt i64 %0, 1
+ %.in = select i1 %cmp, <2 x i64> <i64 0, i64 undef>, <2 x i64> %in
+ %1 = extractelement <2 x i64> %in, i32 1
+ %cmp1 = icmp slt i64 %1, 1
+ br i1 %cmp1, label %if.then2, label %if.else3
+
+if.then2: ; preds = %entry
+ %2 = insertelement <2 x i64> %.in, i64 0, i32 1
+ br label %if.end4
+
+if.else3: ; preds = %entry
+ %3 = shufflevector <2 x i64> %.in, <2 x i64> %in, <2 x i32> <i32 0, i32 3>
+ br label %if.end4
+
+if.end4: ; preds = %if.else3, %if.then2
+ %result.2 = phi <2 x i64> [ %2, %if.then2 ], [ %3, %if.else3 ]
+ store <2 x i64> %result.2, <2 x i64>* %agg.result, align 128
+ ret void
+}
+
+; <rdar://problem/12758887>
+; RegisterCoalescer::updateRegDefsUses() could visit an instruction more than
+; once under rare circumstances. When widening a register from QPR to DTriple
+; with the original virtual register in dsub_1_dsub_2, the double rewrite would
+; produce an invalid sub-register.
+;
+; This is because dsub_1_dsub_2 is not an idempotent sub-register index.
+; It will translate %vr:dsub_0 -> %vr:dsub_1.
+define hidden fastcc void @radar12758887() nounwind optsize ssp {
+entry:
+ br i1 undef, label %for.body, label %for.end70
+
+for.body: ; preds = %for.end, %entry
+ br i1 undef, label %for.body29, label %for.end
+
+for.body29: ; preds = %for.body29, %for.body
+ %0 = load <2 x double>* null, align 1
+ %splat40 = shufflevector <2 x double> %0, <2 x double> undef, <2 x i32> zeroinitializer
+ %mul41 = fmul <2 x double> undef, %splat40
+ %add42 = fadd <2 x double> undef, %mul41
+ %splat44 = shufflevector <2 x double> %0, <2 x double> undef, <2 x i32> <i32 1, i32 1>
+ %mul45 = fmul <2 x double> undef, %splat44
+ %add46 = fadd <2 x double> undef, %mul45
+ br i1 undef, label %for.end, label %for.body29
+
+for.end: ; preds = %for.body29, %for.body
+ %accumR2.0.lcssa = phi <2 x double> [ zeroinitializer, %for.body ], [ %add42, %for.body29 ]
+ %accumI2.0.lcssa = phi <2 x double> [ zeroinitializer, %for.body ], [ %add46, %for.body29 ]
+ %1 = shufflevector <2 x double> %accumI2.0.lcssa, <2 x double> undef, <2 x i32> <i32 1, i32 0>
+ %add58 = fadd <2 x double> undef, %1
+ %mul61 = fmul <2 x double> %add58, undef
+ %add63 = fadd <2 x double> undef, %mul61
+ %add64 = fadd <2 x double> undef, %add63
+ %add67 = fadd <2 x double> undef, %add64
+ store <2 x double> %add67, <2 x double>* undef, align 1
+ br i1 undef, label %for.end70, label %for.body
+
+for.end70: ; preds = %for.end, %entry
+ ret void
+}
diff --git a/test/CodeGen/ARM/constants.ll b/test/CodeGen/ARM/constants.ll
index f4c1b5acef91..3baa103e3d5d 100644
--- a/test/CodeGen/ARM/constants.ll
+++ b/test/CodeGen/ARM/constants.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=armv4t-unknown-linux-gnueabi -disable-cgp-branch-opts | FileCheck %s
+; RUN: llc < %s -mtriple=armv4t-unknown-linux-gnueabi -disable-cgp-branch-opts -verify-machineinstrs | FileCheck %s
define i32 @f1() {
; CHECK: f1
@@ -45,6 +45,16 @@ r:
ret void
}
+define i32 @f8() nounwind {
+; Check that constant propagation through (i32)-1 => (float)Nan => (i32)-1
+; gives expected result
+; CHECK: f8
+; CHECK: mvn r0, #0
+ %tmp0 = bitcast i32 -1 to float
+ %tmp1 = bitcast float %tmp0 to i32
+ ret i32 %tmp1
+}
+
%t1 = type { <3 x float>, <3 x float> }
@const1 = global %t1 { <3 x float> zeroinitializer,
diff --git a/test/CodeGen/ARM/crash-shufflevector.ll b/test/CodeGen/ARM/crash-shufflevector.ll
new file mode 100644
index 000000000000..bdc0e0ea4db0
--- /dev/null
+++ b/test/CodeGen/ARM/crash-shufflevector.ll
@@ -0,0 +1,10 @@
+; RUN: llc < %s -mtriple=armv7
+
+declare void @g(<16 x i8>)
+define void @f(<4 x i8> %param1, <4 x i8> %param2) {
+ %y1 = shufflevector <4 x i8> %param1, <4 x i8> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+ %y2 = shufflevector <4 x i8> %param2, <4 x i8> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
+ %z = shufflevector <16 x i8> %y1, <16 x i8> %y2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 16, i32 17, i32 18, i32 19>
+ call void @g(<16 x i8> %z)
+ ret void
+} \ No newline at end of file
diff --git a/test/CodeGen/ARM/darwin-section-order.ll b/test/CodeGen/ARM/darwin-section-order.ll
new file mode 100644
index 000000000000..701028c0a537
--- /dev/null
+++ b/test/CodeGen/ARM/darwin-section-order.ll
@@ -0,0 +1,21 @@
+; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
+
+; CHECK: .section __TEXT,__text,regular,pure_instructions
+; CHECK: .section __TEXT,myprecious
+; CHECK: .section __TEXT,__textcoal_nt,coalesced,pure_instructions
+; CHECK: .section __TEXT,__const_coal,coalesced
+; CHECK: .section __TEXT,__picsymbolstub4,symbol_stubs,none,16
+; CHECK: .section __TEXT,__StaticInit,regular,pure_instructions
+
+
+define void @normal() nounwind readnone {
+; CHECK: .section __TEXT,__text,regular,pure_instructions
+; CHECK: _normal:
+ ret void
+}
+
+define void @special() nounwind readnone section "__TEXT,myprecious" {
+; CHECK: .section __TEXT,myprecious
+; CHECK: _special:
+ ret void
+}
diff --git a/test/CodeGen/ARM/deps-fix.ll b/test/CodeGen/ARM/deps-fix.ll
new file mode 100644
index 000000000000..288697a4dc7f
--- /dev/null
+++ b/test/CodeGen/ARM/deps-fix.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s -march=arm -mcpu=cortex-a9 -mattr=+neon,+neonfp -float-abi=hard -mtriple armv7-linux-gnueabi | FileCheck %s
+
+;; This test checks that the ExecutionDepsFix pass performs the domain changes
+;; even when some dependencies are propagated through implicit definitions.
+
+; CHECK: fun_a
+define <4 x float> @fun_a(<4 x float> %in, <4 x float> %x, float %y) nounwind {
+; CHECK: vext
+; CHECK: vext
+; CHECK: vadd.f32
+ %1 = insertelement <4 x float> %in, float %y, i32 0
+ %2 = fadd <4 x float> %1, %x
+ ret <4 x float> %2
+}
+; CHECK: fun_b
+define <4 x i32> @fun_b(<4 x i32> %in, <4 x i32> %x, i32 %y) nounwind {
+; CHECK: vmov.32
+; CHECK: vadd.i32
+ %1 = insertelement <4 x i32> %in, i32 %y, i32 0
+ %2 = add <4 x i32> %1, %x
+ ret <4 x i32> %2
+}
diff --git a/test/CodeGen/ARM/div.ll b/test/CodeGen/ARM/div.ll
index 3d29e05a0ccf..82cfca182b80 100644
--- a/test/CodeGen/ARM/div.ll
+++ b/test/CodeGen/ARM/div.ll
@@ -1,9 +1,13 @@
-; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=CHECK-ARM
+; RUN: llc < %s -mtriple=arm-apple-ios -mcpu=cortex-a8 | FileCheck %s -check-prefix=CHECK-ARM
+; RUN: llc < %s -mtriple=arm-apple-ios -mcpu=swift | FileCheck %s -check-prefix=CHECK-SWIFT
define i32 @f1(i32 %a, i32 %b) {
entry:
; CHECK-ARM: f1
; CHECK-ARM: __divsi3
+
+; CHECK-SWIFT: f1
+; CHECK-SWIFT: sdiv
%tmp1 = sdiv i32 %a, %b ; <i32> [#uses=1]
ret i32 %tmp1
}
@@ -12,6 +16,9 @@ define i32 @f2(i32 %a, i32 %b) {
entry:
; CHECK-ARM: f2
; CHECK-ARM: __udivsi3
+
+; CHECK-SWIFT: f2
+; CHECK-SWIFT: udiv
%tmp1 = udiv i32 %a, %b ; <i32> [#uses=1]
ret i32 %tmp1
}
@@ -20,6 +27,10 @@ define i32 @f3(i32 %a, i32 %b) {
entry:
; CHECK-ARM: f3
; CHECK-ARM: __modsi3
+
+; CHECK-SWIFT: f3
+; CHECK-SWIFT: sdiv
+; CHECK-SWIFT: mls
%tmp1 = srem i32 %a, %b ; <i32> [#uses=1]
ret i32 %tmp1
}
@@ -28,6 +39,10 @@ define i32 @f4(i32 %a, i32 %b) {
entry:
; CHECK-ARM: f4
; CHECK-ARM: __umodsi3
+
+; CHECK-SWIFT: f4
+; CHECK-SWIFT: udiv
+; CHECK-SWIFT: mls
%tmp1 = urem i32 %a, %b ; <i32> [#uses=1]
ret i32 %tmp1
}
diff --git a/test/CodeGen/ARM/divmod.ll b/test/CodeGen/ARM/divmod.ll
index 7fbf8f409036..577f8aa7d39b 100644
--- a/test/CodeGen/ARM/divmod.ll
+++ b/test/CodeGen/ARM/divmod.ll
@@ -1,10 +1,18 @@
-; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=cortex-a8 | FileCheck %s
+; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=cortex-a8 | FileCheck %s -check-prefix=A8
+; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=swift | FileCheck %s -check-prefix=SWIFT
+
+; rdar://12481395
define void @foo(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp {
entry:
-; CHECK: foo:
-; CHECK: bl ___divmodsi4
-; CHECK-NOT: bl ___divmodsi4
+; A8: foo:
+; A8: bl ___divmodsi4
+; A8-NOT: bl ___divmodsi4
+
+; SWIFT: foo:
+; SWIFT: sdiv
+; SWIFT: mls
+; SWIFT-NOT: bl __divmodsi4
%div = sdiv i32 %x, %y
store i32 %div, i32* %P, align 4
%rem = srem i32 %x, %y
@@ -15,9 +23,14 @@ entry:
define void @bar(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp {
entry:
-; CHECK: bar:
-; CHECK: bl ___udivmodsi4
-; CHECK-NOT: bl ___udivmodsi4
+; A8: bar:
+; A8: bl ___udivmodsi4
+; A8-NOT: bl ___udivmodsi4
+
+; SWIFT: bar:
+; SWIFT: udiv
+; SWIFT: mls
+; SWIFT-NOT: bl __udivmodsi4
%div = udiv i32 %x, %y
store i32 %div, i32* %P, align 4
%rem = urem i32 %x, %y
@@ -32,14 +45,18 @@ entry:
define void @do_indent(i32 %cols) nounwind {
entry:
-; CHECK: do_indent:
+; A8: do_indent:
+; SWIFT: do_indent:
%0 = load i32* @flags, align 4
%1 = and i32 %0, 67108864
%2 = icmp eq i32 %1, 0
br i1 %2, label %bb1, label %bb
bb:
-; CHECK: bl ___divmodsi4
+; A8: bl ___divmodsi4
+; SWIFT: sdiv
+; SWIFT: mls
+; SWIFT-NOT: bl __divmodsi4
%3 = load i32* @tabsize, align 4
%4 = srem i32 %cols, %3
%5 = sdiv i32 %cols, %3
@@ -60,9 +77,14 @@ declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind
; rdar://11714607
define i32 @howmany(i32 %x, i32 %y) nounwind {
entry:
-; CHECK: howmany:
-; CHECK: bl ___udivmodsi4
-; CHECK-NOT: ___udivsi3
+; A8: howmany:
+; A8: bl ___udivmodsi4
+; A8-NOT: ___udivsi3
+
+; SWIFT: howmany:
+; SWIFT: udiv
+; SWIFT: mls
+; SWIFT-NOT: bl __udivmodsi4
%rem = urem i32 %x, %y
%div = udiv i32 %x, %y
%not.cmp = icmp ne i32 %rem, 0
diff --git a/test/CodeGen/ARM/domain-conv-vmovs.ll b/test/CodeGen/ARM/domain-conv-vmovs.ll
new file mode 100644
index 000000000000..a5c41144584c
--- /dev/null
+++ b/test/CodeGen/ARM/domain-conv-vmovs.ll
@@ -0,0 +1,100 @@
+; RUN: llc -verify-machineinstrs -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a9 -mattr=+neon,+neonfp -float-abi=hard < %s | FileCheck %s
+
+define <2 x float> @test_vmovs_via_vext_lane0to0(float %arg, <2 x float> %in) {
+; CHECK: test_vmovs_via_vext_lane0to0:
+ %vec = insertelement <2 x float> %in, float %arg, i32 0
+ %res = fadd <2 x float> %vec, %vec
+
+; CHECK: vext.32 d1, d1, d0, #1
+; CHECK: vext.32 d1, d1, d1, #1
+; CHECK: vadd.f32 {{d[0-9]+}}, d1, d1
+
+ ret <2 x float> %res
+}
+
+define <2 x float> @test_vmovs_via_vext_lane0to1(float %arg, <2 x float> %in) {
+; CHECK: test_vmovs_via_vext_lane0to1:
+ %vec = insertelement <2 x float> %in, float %arg, i32 1
+ %res = fadd <2 x float> %vec, %vec
+
+; CHECK: vext.32 d1, d1, d1, #1
+; CHECK: vext.32 d1, d1, d0, #1
+; CHECK: vadd.f32 {{d[0-9]+}}, d1, d1
+
+ ret <2 x float> %res
+}
+
+define <2 x float> @test_vmovs_via_vext_lane1to0(float, float %arg, <2 x float> %in) {
+; CHECK: test_vmovs_via_vext_lane1to0:
+ %vec = insertelement <2 x float> %in, float %arg, i32 0
+ %res = fadd <2 x float> %vec, %vec
+
+; CHECK: vext.32 d1, d1, d1, #1
+; CHECK: vext.32 d1, d0, d1, #1
+; CHECK: vadd.f32 {{d[0-9]+}}, d1, d1
+
+ ret <2 x float> %res
+}
+
+define <2 x float> @test_vmovs_via_vext_lane1to1(float, float %arg, <2 x float> %in) {
+; CHECK: test_vmovs_via_vext_lane1to1:
+ %vec = insertelement <2 x float> %in, float %arg, i32 1
+ %res = fadd <2 x float> %vec, %vec
+
+; CHECK: vext.32 d1, d0, d1, #1
+; CHECK: vext.32 d1, d1, d1, #1
+; CHECK: vadd.f32 {{d[0-9]+}}, d1, d1
+
+ ret <2 x float> %res
+}
+
+
+define float @test_vmovs_via_vdup(float, float %ret, float %lhs, float %rhs) {
+; CHECK: test_vmovs_via_vdup:
+
+ ; Do an operation (which will end up NEON because of +neonfp) to convince the
+ ; execution-domain pass that NEON is a good thing to use.
+ %res = fadd float %ret, %ret
+ ; It makes sense for LLVM to do the addition in d0 here, because it's going
+ ; to be returned. This means it will want a "vmov s0, s1":
+; CHECK: vdup.32 d0, d0[1]
+
+ ret float %res
+}
+
+declare float @llvm.sqrt.f32(float)
+
+declare void @bar()
+
+; This is a comp
+define float @test_ineligible(float, float %in) {
+; CHECK: test_ineligible:
+
+ %sqrt = call float @llvm.sqrt.f32(float %in)
+ %val = fadd float %sqrt, %sqrt
+
+ ; This call forces a move from a callee-saved register to the return-reg. That
+ ; move is not eligible for conversion to a d-register instructions because the
+ ; use-def chains would be messed up. Primarily a compile-test (we used to
+ ; internal fault).
+ call void @bar()
+; CHECL: bl bar
+; CHECK: vext.32
+; CHECK: vext.32
+ ret float %val
+}
+
+define i32 @test_vmovs_no_sreg(i32 %in) {
+; CHECK: test_vmovs_no_sreg:
+
+ ; Check that the movement to and from GPRs takes place in the NEON domain.
+; CHECK: vmov.32 d
+ %x = bitcast i32 %in to float
+
+ %res = fadd float %x, %x
+
+; CHECK: vmov.32 r{{[0-9]+}}, d
+ %resi = bitcast float %res to i32
+
+ ret i32 %resi
+}
diff --git a/test/CodeGen/ARM/fabss.ll b/test/CodeGen/ARM/fabss.ll
index bcb4ee745234..46c2f1c65fe5 100644
--- a/test/CodeGen/ARM/fabss.ll
+++ b/test/CodeGen/ARM/fabss.ll
@@ -14,12 +14,12 @@ entry:
declare float @fabsf(float)
; VFP2: test:
-; VFP2: vabs.f32 s1, s1
+; VFP2: vabs.f32 s2, s2
; NFP1: test:
; NFP1: vabs.f32 d1, d1
; NFP0: test:
-; NFP0: vabs.f32 s1, s1
+; NFP0: vabs.f32 s2, s2
; CORTEXA8: test:
; CORTEXA8: vadd.f32 [[D1:d[0-9]+]]
diff --git a/test/CodeGen/ARM/fadds.ll b/test/CodeGen/ARM/fadds.ll
index e35103c045eb..48ef5ed88fb0 100644
--- a/test/CodeGen/ARM/fadds.ll
+++ b/test/CodeGen/ARM/fadds.ll
@@ -10,14 +10,14 @@ entry:
}
; VFP2: test:
-; VFP2: vadd.f32 s0, s1, s0
+; VFP2: vadd.f32 s
; NFP1: test:
-; NFP1: vadd.f32 d0, d1, d0
+; NFP1: vadd.f32 d
; NFP0: test:
-; NFP0: vadd.f32 s0, s1, s0
+; NFP0: vadd.f32 s
; CORTEXA8: test:
-; CORTEXA8: vadd.f32 d0, d1, d0
+; CORTEXA8: vadd.f32 d
; CORTEXA9: test:
; CORTEXA9: vadd.f32 s{{.}}, s{{.}}, s{{.}}
diff --git a/test/CodeGen/ARM/fast-isel-pic.ll b/test/CodeGen/ARM/fast-isel-pic.ll
new file mode 100644
index 000000000000..867d53f973db
--- /dev/null
+++ b/test/CodeGen/ARM/fast-isel-pic.ll
@@ -0,0 +1,61 @@
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=arm-apple-ios | FileCheck %s --check-prefix=ARM
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARMv7
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s --check-prefix=THUMB-ELF
+; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=pic -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefix=ARMv7-ELF
+
+@g = global i32 0, align 4
+
+define i32 @LoadGV() {
+entry:
+; THUMB: LoadGV
+; THUMB: movw [[reg0:r[0-9]+]],
+; THUMB: movt [[reg0]],
+; THUMB: add [[reg0]], pc
+; THUMB-ELF: LoadGV
+; THUMB-ELF: ldr.n r[[reg0:[0-9]+]],
+; THUMB-ELF: ldr.n r[[reg1:[0-9]+]],
+; THUMB-ELF: ldr r[[reg0]], [r[[reg1]], r[[reg0]]]
+; ARM: LoadGV
+; ARM: ldr [[reg1:r[0-9]+]],
+; ARM: add [[reg1]], pc, [[reg1]]
+; ARMv7: LoadGV
+; ARMv7: movw [[reg2:r[0-9]+]],
+; ARMv7: movt [[reg2]],
+; ARMv7: add [[reg2]], pc, [[reg2]]
+; ARMv7-ELF: LoadGV
+; ARMv7-ELF: ldr r[[reg2:[0-9]+]],
+; ARMv7-ELF: ldr r[[reg3:[0-9]+]],
+; ARMv7-ELF: ldr r[[reg2]], [r[[reg3]], r[[reg2]]]
+ %tmp = load i32* @g
+ ret i32 %tmp
+}
+
+@i = external global i32
+
+define i32 @LoadIndirectSymbol() {
+entry:
+; THUMB: LoadIndirectSymbol
+; THUMB: movw r[[reg3:[0-9]+]],
+; THUMB: movt r[[reg3]],
+; THUMB: add r[[reg3]], pc
+; THUMB: ldr r[[reg3]], [r[[reg3]]]
+; THUMB-ELF: LoadIndirectSymbol
+; THUMB-ELF: ldr.n r[[reg3:[0-9]+]],
+; THUMB-ELF: ldr.n r[[reg4:[0-9]+]],
+; THUMB-ELF: ldr r[[reg3]], [r[[reg4]], r[[reg3]]]
+; ARM: LoadIndirectSymbol
+; ARM: ldr [[reg4:r[0-9]+]],
+; ARM: ldr [[reg4]], [pc, [[reg4]]]
+; ARMv7: LoadIndirectSymbol
+; ARMv7: movw r[[reg5:[0-9]+]],
+; ARMv7: movt r[[reg5]],
+; ARMv7: add r[[reg5]], pc, r[[reg5]]
+; ARMv7: ldr r[[reg5]], [r[[reg5]]]
+; ARMv7-ELF: LoadIndirectSymbol
+; ARMv7-ELF: ldr r[[reg5:[0-9]+]],
+; ARMv7-ELF: ldr r[[reg6:[0-9]+]],
+; ARMv7-ELF: ldr r[[reg5]], [r[[reg6]], r[[reg5]]]
+ %tmp = load i32* @i
+ ret i32 %tmp
+}
diff --git a/test/CodeGen/ARM/fast-isel.ll b/test/CodeGen/ARM/fast-isel.ll
index ecd5fe27a4b7..41fda4132632 100644
--- a/test/CodeGen/ARM/fast-isel.ll
+++ b/test/CodeGen/ARM/fast-isel.ll
@@ -1,5 +1,7 @@
; 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
; Very basic fast-isel functionality.
define i32 @add(i32 %a, i32 %b) nounwind {
@@ -238,3 +240,67 @@ entry:
}
declare void @llvm.trap() nounwind
+
+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
+}
diff --git a/test/CodeGen/ARM/fdivs.ll b/test/CodeGen/ARM/fdivs.ll
index 31c1ca940502..8fab00213585 100644
--- a/test/CodeGen/ARM/fdivs.ll
+++ b/test/CodeGen/ARM/fdivs.ll
@@ -10,14 +10,14 @@ entry:
}
; VFP2: test:
-; VFP2: vdiv.f32 s0, s1, s0
+; VFP2: vdiv.f32 s0, s2, s0
; NFP1: test:
-; NFP1: vdiv.f32 s0, s1, s0
+; NFP1: vdiv.f32 s0, s2, s0
; NFP0: test:
-; NFP0: vdiv.f32 s0, s1, s0
+; NFP0: vdiv.f32 s0, s2, s0
; CORTEXA8: test:
-; CORTEXA8: vdiv.f32 s0, s1, s0
+; CORTEXA8: vdiv.f32 s0, s2, s0
; CORTEXA9: test:
; CORTEXA9: vdiv.f32 s{{.}}, s{{.}}, s{{.}}
diff --git a/test/CodeGen/ARM/fmuls.ll b/test/CodeGen/ARM/fmuls.ll
index 3c3182bc6341..1566a9272db1 100644
--- a/test/CodeGen/ARM/fmuls.ll
+++ b/test/CodeGen/ARM/fmuls.ll
@@ -10,15 +10,15 @@ entry:
}
; VFP2: test:
-; VFP2: vmul.f32 s0, s1, s0
+; VFP2: vmul.f32 s
; NFP1: test:
-; NFP1: vmul.f32 d0, d1, d0
+; NFP1: vmul.f32 d
; NFP0: test:
-; NFP0: vmul.f32 s0, s1, s0
+; NFP0: vmul.f32 s
; CORTEXA8: test:
-; CORTEXA8: vmul.f32 d0, d1, d0
+; CORTEXA8: vmul.f32 d
; CORTEXA9: test:
; CORTEXA9: vmul.f32 s{{.}}, s{{.}}, s{{.}}
diff --git a/test/CodeGen/ARM/fp-fast.ll b/test/CodeGen/ARM/fp-fast.ll
new file mode 100644
index 000000000000..ec5718738177
--- /dev/null
+++ b/test/CodeGen/ARM/fp-fast.ll
@@ -0,0 +1,60 @@
+; RUN: llc -march=arm -mcpu=cortex-a9 -mattr=+vfp4 -enable-unsafe-fp-math < %s | FileCheck %s
+
+; CHECK: test1
+define float @test1(float %x) {
+; CHECK-NOT: vfma
+; CHECK: vmul.f32
+; CHECK-NOT: vfma
+ %t1 = fmul float %x, 3.0
+ %t2 = call float @llvm.fma.f32(float %x, float 2.0, float %t1)
+ ret float %t2
+}
+
+; CHECK: test2
+define float @test2(float %x, float %y) {
+; CHECK-NOT: vmul
+; CHECK: vfma.f32
+; CHECK-NOT: vmul
+ %t1 = fmul float %x, 3.0
+ %t2 = call float @llvm.fma.f32(float %t1, float 2.0, float %y)
+ ret float %t2
+}
+
+; CHECK: test3
+define float @test3(float %x, float %y) {
+; CHECK-NOT: vfma
+; CHECK: vadd.f32
+; CHECK-NOT: vfma
+ %t2 = call float @llvm.fma.f32(float %x, float 1.0, float %y)
+ ret float %t2
+}
+
+; CHECK: test4
+define float @test4(float %x, float %y) {
+; CHECK-NOT: vfma
+; CHECK: vsub.f32
+; CHECK-NOT: vfma
+ %t2 = call float @llvm.fma.f32(float %x, float -1.0, float %y)
+ ret float %t2
+}
+
+; CHECK: test5
+define float @test5(float %x) {
+; CHECK-NOT: vfma
+; CHECK: vmul.f32
+; CHECK-NOT: vfma
+ %t2 = call float @llvm.fma.f32(float %x, float 2.0, float %x)
+ ret float %t2
+}
+
+; CHECK: test6
+define float @test6(float %x) {
+; CHECK-NOT: vfma
+; CHECK: vmul.f32
+; CHECK-NOT: vfma
+ %t1 = fsub float -0.0, %x
+ %t2 = call float @llvm.fma.f32(float %x, float 5.0, float %t1)
+ ret float %t2
+}
+
+declare float @llvm.fma.f32(float, float, float)
diff --git a/test/CodeGen/ARM/fp_convert.ll b/test/CodeGen/ARM/fp_convert.ll
index 7002cecf3640..44298b9c5d8d 100644
--- a/test/CodeGen/ARM/fp_convert.ll
+++ b/test/CodeGen/ARM/fp_convert.ll
@@ -31,7 +31,7 @@ define float @test3(i32 %a, i32 %b) {
; VFP2: test3:
; VFP2: vcvt.f32.u32 s{{.}}, s{{.}}
; NEON: test3:
-; NEON: vcvt.f32.u32 d0, d0
+; NEON: vcvt.f32.u32 d
entry:
%0 = add i32 %a, %b
%1 = uitofp i32 %0 to float
@@ -42,7 +42,7 @@ define float @test4(i32 %a, i32 %b) {
; VFP2: test4:
; VFP2: vcvt.f32.s32 s{{.}}, s{{.}}
; NEON: test4:
-; NEON: vcvt.f32.s32 d0, d0
+; NEON: vcvt.f32.s32 d
entry:
%0 = add i32 %a, %b
%1 = sitofp i32 %0 to float
diff --git a/test/CodeGen/ARM/fsubs.ll b/test/CodeGen/ARM/fsubs.ll
index bea8d5f4f30b..f039e74c8ee6 100644
--- a/test/CodeGen/ARM/fsubs.ll
+++ b/test/CodeGen/ARM/fsubs.ll
@@ -8,6 +8,6 @@ entry:
ret float %0
}
-; VFP2: vsub.f32 s0, s1, s0
-; NFP1: vsub.f32 d0, d1, d0
-; NFP0: vsub.f32 s0, s1, s0
+; VFP2: vsub.f32 s
+; NFP1: vsub.f32 d
+; NFP0: vsub.f32 s
diff --git a/test/CodeGen/ARM/ifcvt1.ll b/test/CodeGen/ARM/ifcvt1.ll
index cd870bb5d4b2..fd831442c14b 100644
--- a/test/CodeGen/ARM/ifcvt1.ll
+++ b/test/CodeGen/ARM/ifcvt1.ll
@@ -1,17 +1,21 @@
-; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s
+; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s -check-prefix=A8
+; RUN: llc < %s -march=arm -mcpu=swift | FileCheck %s -check-prefix=SWIFT
define i32 @t1(i32 %a, i32 %b) {
-; CHECK: t1:
+; A8: t1:
+; SWIFT: t1:
%tmp2 = icmp eq i32 %a, 0
br i1 %tmp2, label %cond_false, label %cond_true
cond_true:
-; CHECK: subeq r0, r1, #1
+; A8: subeq r0, r1, #1
+; SWIFT: sub r0, r1, #1
%tmp5 = add i32 %b, 1
ret i32 %tmp5
cond_false:
-; CHECK: addne r0, r1, #1
+; A8: addne r0, r1, #1
+; SWIFT: addne r0, r1, #1
%tmp7 = add i32 %b, -1
ret i32 %tmp7
}
diff --git a/test/CodeGen/ARM/ifcvt12.ll b/test/CodeGen/ARM/ifcvt12.ll
new file mode 100644
index 000000000000..77bdca57e555
--- /dev/null
+++ b/test/CodeGen/ARM/ifcvt12.ll
@@ -0,0 +1,15 @@
+; RUN: llc < %s -mtriple=arm-apple-darwin -mcpu=cortex-a8 | FileCheck %s
+define i32 @f1(i32 %a, i32 %b, i32 %c) {
+; CHECK: f1:
+; CHECK: mlsne r0, r0, r1, r2
+ %tmp1 = icmp eq i32 %a, 0
+ br i1 %tmp1, label %cond_false, label %cond_true
+
+cond_true:
+ %tmp2 = mul i32 %a, %b
+ %tmp3 = sub i32 %c, %tmp2
+ ret i32 %tmp3
+
+cond_false:
+ ret i32 %a
+}
diff --git a/test/CodeGen/ARM/ifcvt5.ll b/test/CodeGen/ARM/ifcvt5.ll
index 95f5c97f2a9a..5081791bc257 100644
--- a/test/CodeGen/ARM/ifcvt5.ll
+++ b/test/CodeGen/ARM/ifcvt5.ll
@@ -1,4 +1,6 @@
-; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=cortex-a8 | FileCheck %s -check-prefix=A8
+; RUN: llc < %s -mtriple=armv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT
+; rdar://8402126
@x = external global i32* ; <i32**> [#uses=1]
@@ -10,8 +12,12 @@ entry:
}
define i32 @t1(i32 %a, i32 %b) {
-; CHECK: t1:
-; CHECK: poplt {r7, pc}
+; A8: t1:
+; A8: poplt {r7, pc}
+
+; SWIFT: t1:
+; SWIFT: pop {r7, pc}
+; SWIFT: pop {r7, pc}
entry:
%tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1]
br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
diff --git a/test/CodeGen/ARM/indirectbr-2.ll b/test/CodeGen/ARM/indirectbr-2.ll
new file mode 100644
index 000000000000..084f520a8ee5
--- /dev/null
+++ b/test/CodeGen/ARM/indirectbr-2.ll
@@ -0,0 +1,46 @@
+; RUN: llc < %s -O0 -relocation-model=pic -mtriple=thumbv7-apple-ios | FileCheck %s
+; <rdar://problem/12529625>
+
+@foo = global i32 34879, align 4
+@DWJumpTable2808 = global [2 x i32] [i32 sub (i32 ptrtoint (i8* blockaddress(@func, %14) to i32), i32 ptrtoint (i8* blockaddress(@func, %4) to i32)), i32 sub (i32 ptrtoint (i8* blockaddress(@func, %13) to i32), i32 ptrtoint (i8* blockaddress(@func, %4) to i32))]
+@0 = internal constant [45 x i8] c"func XXXXXXXXXXX :: bb xxxxxxxxxxxxxxxxxxxx\0A\00"
+
+; The indirect branch has the two destinations as successors. The lone PHI
+; statement shouldn't be implicitly defined.
+
+; CHECK: func:
+; CHECK: Ltmp1: @ Block address taken
+; CHECK-NOT: @ implicit-def: R0
+; CHECK: @ 4-byte Reload
+
+define i32 @func() nounwind ssp {
+ %1 = alloca i32, align 4
+ %2 = load i32* @foo, align 4
+ %3 = icmp eq i32 %2, 34879
+ br label %4
+
+; <label>:4 ; preds = %0
+ %5 = zext i1 %3 to i32
+ %6 = mul i32 %5, 287
+ %7 = add i32 %6, 2
+ %8 = getelementptr [2 x i32]* @DWJumpTable2808, i32 0, i32 %5
+ %9 = load i32* %8
+ %10 = add i32 %9, ptrtoint (i8* blockaddress(@func, %4) to i32)
+ %11 = inttoptr i32 %10 to i8*
+ %12 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([45 x i8]* @0, i32 0, i32 0))
+ indirectbr i8* %11, [label %13, label %14]
+
+; <label>:13 ; preds = %4
+ %tmp14 = phi i32 [ %7, %4 ]
+ store i32 23958, i32* @foo, align 4
+ %tmp15 = load i32* %1, align 4
+ %tmp16 = icmp eq i32 %tmp15, 0
+ %tmp17 = zext i1 %tmp16 to i32
+ %tmp21 = add i32 %tmp17, %tmp14
+ ret i32 %tmp21
+
+; <label>:14 ; preds = %4
+ ret i32 42
+}
+
+declare i32 @printf(i8*, ...)
diff --git a/test/CodeGen/ARM/integer_insertelement.ll b/test/CodeGen/ARM/integer_insertelement.ll
new file mode 100644
index 000000000000..1d72afefb5b8
--- /dev/null
+++ b/test/CodeGen/ARM/integer_insertelement.ll
@@ -0,0 +1,35 @@
+; RUN: llc %s -o - -march=arm -mattr=+neon | FileCheck %s
+
+; This test checks that when inserting one (integer) element into a vector,
+; the vector is not spuriously copied. "vorr dX, dY, dY" is the way of moving
+; one DPR to another that we check for.
+
+; CHECK: @f
+; CHECK-NOT: vorr d
+; CHECK: vmov.32 d
+; CHECK-NOT: vorr d
+; CHECK: mov pc, lr
+define <4 x i32> @f(<4 x i32> %in) {
+ %1 = insertelement <4 x i32> %in, i32 255, i32 3
+ ret <4 x i32> %1
+}
+
+; CHECK: @g
+; CHECK-NOT: vorr d
+; CHECK: vmov.16 d
+; CHECK-NOT: vorr d
+; CHECK: mov pc, lr
+define <8 x i16> @g(<8 x i16> %in) {
+ %1 = insertelement <8 x i16> %in, i16 255, i32 7
+ ret <8 x i16> %1
+}
+
+; CHECK: @h
+; CHECK-NOT: vorr d
+; CHECK: vmov.8 d
+; CHECK-NOT: vorr d
+; CHECK: mov pc, lr
+define <16 x i8> @h(<16 x i8> %in) {
+ %1 = insertelement <16 x i8> %in, i8 255, i32 15
+ ret <16 x i8> %1
+}
diff --git a/test/CodeGen/ARM/ldr_post.ll b/test/CodeGen/ARM/ldr_post.ll
index 8ddf025dbf1b..a6ca43448380 100644
--- a/test/CodeGen/ARM/ldr_post.ll
+++ b/test/CodeGen/ARM/ldr_post.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -march=arm | FileCheck %s
+; RUN: llc < %s -march=arm -mcpu=swift | FileCheck %s
; CHECK: test1:
; CHECK: ldr {{.*, \[.*]}}, -r2
diff --git a/test/CodeGen/ARM/ldr_pre.ll b/test/CodeGen/ARM/ldr_pre.ll
index e904e5fd2cdb..6c40ad7326b6 100644
--- a/test/CodeGen/ARM/ldr_pre.ll
+++ b/test/CodeGen/ARM/ldr_pre.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -march=arm | FileCheck %s
+; RUN: llc < %s -march=arm -mcpu=swift | FileCheck %s
; CHECK: test1:
; CHECK: ldr {{.*!}}
diff --git a/test/CodeGen/ARM/longMAC.ll b/test/CodeGen/ARM/longMAC.ll
new file mode 100644
index 000000000000..e4a00e9ac303
--- /dev/null
+++ b/test/CodeGen/ARM/longMAC.ll
@@ -0,0 +1,44 @@
+; RUN: llc < %s -march=arm | FileCheck %s
+; Check generated signed and unsigned multiply accumulate long.
+
+define i64 @MACLongTest1(i32 %a, i32 %b, i64 %c) {
+;CHECK: MACLongTest1:
+;CHECK: umlal
+ %conv = zext i32 %a to i64
+ %conv1 = zext i32 %b to i64
+ %mul = mul i64 %conv1, %conv
+ %add = add i64 %mul, %c
+ ret i64 %add
+}
+
+define i64 @MACLongTest2(i32 %a, i32 %b, i64 %c) {
+;CHECK: MACLongTest2:
+;CHECK: smlal
+ %conv = sext i32 %a to i64
+ %conv1 = sext i32 %b to i64
+ %mul = mul nsw i64 %conv1, %conv
+ %add = add nsw i64 %mul, %c
+ ret i64 %add
+}
+
+define i64 @MACLongTest3(i32 %a, i32 %b, i32 %c) {
+;CHECK: MACLongTest3:
+;CHECK: umlal
+ %conv = zext i32 %b to i64
+ %conv1 = zext i32 %a to i64
+ %mul = mul i64 %conv, %conv1
+ %conv2 = zext i32 %c to i64
+ %add = add i64 %mul, %conv2
+ ret i64 %add
+}
+
+define i64 @MACLongTest4(i32 %a, i32 %b, i32 %c) {
+;CHECK: MACLongTest4:
+;CHECK: smlal
+ %conv = sext i32 %b to i64
+ %conv1 = sext i32 %a to i64
+ %mul = mul nsw i64 %conv, %conv1
+ %conv2 = sext i32 %c to i64
+ %add = add nsw i64 %mul, %conv2
+ ret i64 %add
+}
diff --git a/test/CodeGen/ARM/mls.ll b/test/CodeGen/ARM/mls.ll
index a6cdba445451..066bf98de651 100644
--- a/test/CodeGen/ARM/mls.ll
+++ b/test/CodeGen/ARM/mls.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -march=arm -mattr=+v6t2 | FileCheck %s
+; RUN: llc < %s -march=arm -mattr=+v6t2 -arm-use-mulops=false | FileCheck %s -check-prefix=NO_MULOPS
define i32 @f1(i32 %a, i32 %b, i32 %c) {
%tmp1 = mul i32 %a, %b
@@ -13,4 +14,15 @@ define i32 @f2(i32 %a, i32 %b, i32 %c) {
ret i32 %tmp2
}
+; CHECK: f1:
; CHECK: mls r0, r0, r1, r2
+; NO_MULOPS: f1:
+; NO_MULOPS: mul r0, r0, r1
+; NO_MULOPS-NEXT: sub r0, r2, r0
+
+; CHECK: f2:
+; CHECK: mul r0, r0, r1
+; CHECK-NEXT: sub r0, r0, r2
+; NO_MULOPS: f2:
+; NO_MULOPS: mul r0, r0, r1
+; NO_MULOPS-NEXT: sub r0, r0, r2
diff --git a/test/CodeGen/ARM/neon-fma.ll b/test/CodeGen/ARM/neon-fma.ll
new file mode 100644
index 000000000000..d2cca5009d6b
--- /dev/null
+++ b/test/CodeGen/ARM/neon-fma.ll
@@ -0,0 +1,22 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -mcpu=swift | FileCheck %s
+
+; CHECK: test_v2f32
+; CHECK: vfma.f32 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+
+define <2 x float> @test_v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone ssp {
+entry:
+ %call = tail call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone
+ ret <2 x float> %call
+}
+
+; CHECK: test_v4f32
+; CHECK: vfma.f32 {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
+
+define <4 x float> @test_v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind readnone ssp {
+entry:
+ %call = tail call <4 x float> @llvm.fma.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind readnone
+ ret <4 x float> %call
+}
+
+declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone
+declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) nounwind readnone
diff --git a/test/CodeGen/ARM/neon_ld2.ll b/test/CodeGen/ARM/neon_ld2.ll
index 944bfe060298..497619ed746a 100644
--- a/test/CodeGen/ARM/neon_ld2.ll
+++ b/test/CodeGen/ARM/neon_ld2.ll
@@ -1,10 +1,16 @@
; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
+; RUN: llc < %s -march=arm -mcpu=swift | FileCheck %s --check-prefix=SWIFT
; CHECK: t1
-; CHECK: vldmia
-; CHECK: vldmia
+; CHECK: vld1.64
+; CHECK: vld1.64
; CHECK: vadd.i64 q
-; CHECK: vstmia
+; CHECK: vst1.64
+; SWIFT: t1
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}}
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}}
+; SWIFT: vadd.i64 q
+; SWIFT: vst1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}}
define void @t1(<4 x i32>* %r, <2 x i64>* %a, <2 x i64>* %b) nounwind {
entry:
%0 = load <2 x i64>* %a, align 16 ; <<2 x i64>> [#uses=1]
@@ -16,11 +22,17 @@ entry:
}
; CHECK: t2
-; CHECK: vldmia
-; CHECK: vldmia
+; CHECK: vld1.64
+; CHECK: vld1.64
; CHECK: vsub.i64 q
; CHECK: vmov r0, r1, d
; CHECK: vmov r2, r3, d
+; SWIFT: t2
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}}
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+, :128\]}}
+; SWIFT: vsub.i64 q
+; SWIFT: vmov r0, r1, d
+; SWIFT: vmov r2, r3, d
define <4 x i32> @t2(<2 x i64>* %a, <2 x i64>* %b) nounwind readonly {
entry:
%0 = load <2 x i64>* %a, align 16 ; <<2 x i64>> [#uses=1]
@@ -30,3 +42,18 @@ entry:
ret <4 x i32> %3
}
+; Limited alignment.
+; SWIFT: t3
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+}}
+; SWIFT: vld1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+}}
+; SWIFT: vadd.i64 q
+; SWIFT: vst1.64 {{.d[0-9]+, d[0-9]+}, \[r[0-9]+}}
+define void @t3(<4 x i32>* %r, <2 x i64>* %a, <2 x i64>* %b) nounwind {
+entry:
+ %0 = load <2 x i64>* %a, align 8
+ %1 = load <2 x i64>* %b, align 8
+ %2 = add <2 x i64> %0, %1
+ %3 = bitcast <2 x i64> %2 to <4 x i32>
+ store <4 x i32> %3, <4 x i32>* %r, align 8
+ ret void
+}
diff --git a/test/CodeGen/ARM/opt-shuff-tstore.ll b/test/CodeGen/ARM/opt-shuff-tstore.ll
index df98e231ccfd..74c9a21355d7 100644
--- a/test/CodeGen/ARM/opt-shuff-tstore.ll
+++ b/test/CodeGen/ARM/opt-shuff-tstore.ll
@@ -2,7 +2,7 @@
; CHECK: func_4_8
; CHECK: vst1.32
-; CHECK-NEXT: bx lr
+; CHECK: bx lr
define void @func_4_8(<4 x i8> %param, <4 x i8>* %p) {
%r = add <4 x i8> %param, <i8 1, i8 2, i8 3, i8 4>
store <4 x i8> %r, <4 x i8>* %p
@@ -11,7 +11,7 @@ define void @func_4_8(<4 x i8> %param, <4 x i8>* %p) {
; CHECK: func_2_16
; CHECK: vst1.32
-; CHECK-NEXT: bx lr
+; CHECK: bx lr
define void @func_2_16(<2 x i16> %param, <2 x i16>* %p) {
%r = add <2 x i16> %param, <i16 1, i16 2>
store <2 x i16> %r, <2 x i16>* %p
diff --git a/test/CodeGen/ARM/reg_sequence.ll b/test/CodeGen/ARM/reg_sequence.ll
index 05794e4ebddb..6d6586e4f283 100644
--- a/test/CodeGen/ARM/reg_sequence.ll
+++ b/test/CodeGen/ARM/reg_sequence.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -march=arm -mcpu=cortex-a8 | FileCheck %s
-; RUN: llc < %s -march=arm -mcpu=cortex-a8 -regalloc=basic | FileCheck %s
+; RUN: llc < %s -mtriple=arm-apple-ios -mcpu=cortex-a8 | FileCheck %s
+; RUN: llc < %s -mtriple=arm-apple-ios -mcpu=cortex-a8 -regalloc=basic | FileCheck %s
; Implementing vld / vst as REG_SEQUENCE eliminates the extra vmov's.
%struct.int16x8_t = type { <8 x i16> }
@@ -124,7 +124,6 @@ return1:
return2:
; CHECK: %return2
; CHECK: vadd.i32
-; CHECK: vorr {{q[0-9]+}}, {{q[0-9]+}}
; CHECK-NOT: vmov
; CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
%tmp100 = extractvalue %struct.__neon_int32x4x2_t %tmp2, 0 ; <<4 x i32>> [#uses=1]
@@ -137,7 +136,7 @@ return2:
define <8 x i16> @t5(i16* %A, <8 x i16>* %B) nounwind {
; CHECK: t5:
-; CHECK: vldmia
+; CHECK: vld1.32
; How can FileCheck match Q and D registers? We need a lisp interpreter.
; CHECK: vorr {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
; CHECK-NOT: vmov
@@ -243,8 +242,8 @@ define arm_aapcs_vfpcc float @t9(%0* nocapture, %3* nocapture) nounwind {
; CHECK: vldr
; CHECK-NOT: vmov d{{.*}}, d16
; CHECK: vmov.i32 d17
-; CHECK-NEXT: vstmia r0, {d16, d17}
-; CHECK-NEXT: vstmia r0, {d16, d17}
+; CHECK-NEXT: vst1.64 {d16, d17}, [r0, :128]
+; CHECK-NEXT: vst1.64 {d16, d17}, [r0, :128]
%3 = bitcast double 0.000000e+00 to <2 x float> ; <<2 x float>> [#uses=2]
%4 = shufflevector <2 x float> %3, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> ; <<4 x float>> [#uses=1]
store <4 x float> %4, <4 x float>* undef, align 16
diff --git a/test/CodeGen/ARM/select.ll b/test/CodeGen/ARM/select.ll
index 557556662892..62708ed53d05 100644
--- a/test/CodeGen/ARM/select.ll
+++ b/test/CodeGen/ARM/select.ll
@@ -80,7 +80,7 @@ define double @f7(double %a, double %b) {
; CHECK-NEON: adr [[R2:r[0-9]+]], LCPI7_0
; CHECK-NEON-NEXT: cmp r0, [[R3]]
; CHECK-NEON-NEXT: it eq
-; CHECK-NEON-NEXT: addeq.w {{r.*}}, [[R2]]
+; CHECK-NEON-NEXT: addeq{{.*}} [[R2]], #4
; CHECK-NEON-NEXT: ldr
; CHECK-NEON: bx
diff --git a/test/CodeGen/ARM/select_xform.ll b/test/CodeGen/ARM/select_xform.ll
index 26f7cb68901f..750780891261 100644
--- a/test/CodeGen/ARM/select_xform.ll
+++ b/test/CodeGen/ARM/select_xform.ll
@@ -9,7 +9,7 @@ define i32 @t1(i32 %a, i32 %b, i32 %c) nounwind {
; T2: t1:
; T2: mvn r0, #-2147483648
-; T2: addle.w r1, r1
+; T2: addle r1, r0
; T2: mov r0, r1
%tmp1 = icmp sgt i32 %c, 10
%tmp2 = select i1 %tmp1, i32 0, i32 2147483647
@@ -23,7 +23,7 @@ define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
; ARM: mov r0, r1
; T2: t2:
-; T2: suble.w r1, r1, #10
+; T2: suble r1, #10
; T2: mov r0, r1
%tmp1 = icmp sgt i32 %c, 10
%tmp2 = select i1 %tmp1, i32 0, i32 10
@@ -33,12 +33,12 @@ define i32 @t2(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
define i32 @t3(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
; ARM: t3:
-; ARM: mvnlt r2, #0
-; ARM: and r0, r2, r3
+; ARM: andge r3, r3, r2
+; ARM: mov r0, r3
; T2: t3:
-; T2: movlt.w r2, #-1
-; T2: and.w r0, r2, r3
+; T2: andge r3, r2
+; T2: mov r0, r3
%cond = icmp slt i32 %a, %b
%z = select i1 %cond, i32 -1, i32 %x
%s = and i32 %z, %y
@@ -47,12 +47,12 @@ define i32 @t3(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
define i32 @t4(i32 %a, i32 %b, i32 %x, i32 %y) nounwind {
; ARM: t4:
-; ARM: movlt r2, #0
-; ARM: orr r0, r2, r3
+; ARM: orrge r3, r3, r2
+; ARM: mov r0, r3
; T2: t4:
-; T2: movlt r2, #0
-; T2: orr.w r0, r2, r3
+; T2: orrge r3, r2
+; T2: mov r0, r3
%cond = icmp slt i32 %a, %b
%z = select i1 %cond, i32 0, i32 %x
%s = or i32 %z, %y
@@ -81,7 +81,7 @@ define i32 @t6(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
; T2: t6:
; T2-NOT: movge
-; T2: eorlt.w r3, r3, r2
+; T2: eorlt r3, r2
%cond = icmp slt i32 %a, %b
%tmp1 = select i1 %cond, i32 %c, i32 0
%tmp2 = xor i32 %tmp1, %d
@@ -179,3 +179,46 @@ define i32 @t12(i32 %a, i32 %b) nounwind {
%tmp1 = select i1 %cond, i32 %a, i32 %x
ret i32 %tmp1
}
+
+; Handle frame index operands.
+define void @pr13628() nounwind uwtable align 2 {
+ %x3 = alloca i8, i32 256, align 8
+ %x4 = load i8* undef, align 1
+ %x5 = icmp ne i8 %x4, 0
+ %x6 = select i1 %x5, i8* %x3, i8* null
+ call void @bar(i8* %x6) nounwind
+ ret void
+}
+declare void @bar(i8*)
+
+; Fold zext i1 into predicated add
+define i32 @t13(i32 %c, i32 %a) nounwind readnone ssp {
+entry:
+; ARM: t13
+; ARM: cmp r1, #10
+; ARM: addgt r0, r0, #1
+
+; T2: t13
+; T2: cmp r1, #10
+; T2: addgt r0, #1
+ %cmp = icmp sgt i32 %a, 10
+ %conv = zext i1 %cmp to i32
+ %add = add i32 %conv, %c
+ ret i32 %add
+}
+
+; Fold sext i1 into predicated sub
+define i32 @t14(i32 %c, i32 %a) nounwind readnone ssp {
+entry:
+; ARM: t14
+; ARM: cmp r1, #10
+; ARM: subgt r0, r0, #1
+
+; T2: t14
+; T2: cmp r1, #10
+; T2: subgt r0, #1
+ %cmp = icmp sgt i32 %a, 10
+ %conv = sext i1 %cmp to i32
+ %add = add i32 %conv, %c
+ ret i32 %add
+}
diff --git a/test/CodeGen/ARM/struct_byval.ll b/test/CodeGen/ARM/struct_byval.ll
index 99ba475ad7b1..e9541c278803 100644
--- a/test/CodeGen/ARM/struct_byval.ll
+++ b/test/CodeGen/ARM/struct_byval.ll
@@ -44,3 +44,47 @@ entry:
declare i32 @e1(%struct.SmallStruct* nocapture byval %in) nounwind
declare i32 @e2(%struct.LargeStruct* nocapture byval %in) nounwind
declare i32 @e3(%struct.LargeStruct* nocapture byval align 16 %in) nounwind
+
+; rdar://12442472
+; We can't do tail call since address of s is passed to the callee and part of
+; s is in caller's local frame.
+define void @f3(%struct.SmallStruct* nocapture byval %s) nounwind optsize {
+; CHECK: f3
+; CHECK: bl _consumestruct
+entry:
+ %0 = bitcast %struct.SmallStruct* %s to i8*
+ tail call void @consumestruct(i8* %0, i32 80) optsize
+ ret void
+}
+
+define void @f4(%struct.SmallStruct* nocapture byval %s) nounwind optsize {
+; CHECK: f4
+; CHECK: bl _consumestruct
+entry:
+ %addr = getelementptr inbounds %struct.SmallStruct* %s, i32 0, i32 0
+ %0 = bitcast i32* %addr to i8*
+ tail call void @consumestruct(i8* %0, i32 80) optsize
+ ret void
+}
+
+; We can do tail call here since s is in the incoming argument area.
+define void @f5(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize {
+; CHECK: f5
+; CHECK: b _consumestruct
+entry:
+ %0 = bitcast %struct.SmallStruct* %s to i8*
+ tail call void @consumestruct(i8* %0, i32 80) optsize
+ ret void
+}
+
+define void @f6(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize {
+; CHECK: f6
+; CHECK: b _consumestruct
+entry:
+ %addr = getelementptr inbounds %struct.SmallStruct* %s, i32 0, i32 0
+ %0 = bitcast i32* %addr to i8*
+ tail call void @consumestruct(i8* %0, i32 80) optsize
+ ret void
+}
+
+declare void @consumestruct(i8* nocapture %structp, i32 %structsize) nounwind
diff --git a/test/CodeGen/ARM/sub-cmp-peephole.ll b/test/CodeGen/ARM/sub-cmp-peephole.ll
index 6fcbdee30d34..2961b94d2c1e 100644
--- a/test/CodeGen/ARM/sub-cmp-peephole.ll
+++ b/test/CodeGen/ARM/sub-cmp-peephole.ll
@@ -63,3 +63,24 @@ if.then:
if.else:
ret i32 %sub
}
+
+; If the sub/rsb instruction is predicated, we can't use the flags.
+; <rdar://problem/12263428>
+; Test case from MultiSource/Benchmarks/Ptrdist/bc/number.s
+; CHECK: bc_raise
+; CHECK: rsbeq
+; CHECK: cmp
+define i32 @bc_raise() nounwind ssp {
+entry:
+ %val.2.i = select i1 undef, i32 0, i32 undef
+ %sub.i = sub nsw i32 0, %val.2.i
+ %retval.0.i = select i1 undef, i32 %val.2.i, i32 %sub.i
+ %cmp1 = icmp eq i32 %retval.0.i, 0
+ br i1 %cmp1, label %land.lhs.true, label %if.end11
+
+land.lhs.true: ; preds = %num2long.exit
+ ret i32 17
+
+if.end11: ; preds = %num2long.exit
+ ret i32 23
+}
diff --git a/test/CodeGen/ARM/sub.ll b/test/CodeGen/ARM/sub.ll
index 474043afc11d..7f82ca701261 100644
--- a/test/CodeGen/ARM/sub.ll
+++ b/test/CodeGen/ARM/sub.ll
@@ -1,4 +1,4 @@
-; RUN: llc -march=arm < %s | FileCheck %s
+; RUN: llc -march=arm -mcpu=cortex-a8 < %s | FileCheck %s
; 171 = 0x000000ab
define i64 @f1(i64 %a) {
diff --git a/test/CodeGen/ARM/subreg-remat.ll b/test/CodeGen/ARM/subreg-remat.ll
index 03ae12c6dea0..455bfce0f2e5 100644
--- a/test/CodeGen/ARM/subreg-remat.ll
+++ b/test/CodeGen/ARM/subreg-remat.ll
@@ -4,14 +4,14 @@ target triple = "thumbv7-apple-ios"
;
; The vector %v2 is built like this:
;
-; %vreg6:ssub_1<def> = VMOVSR %vreg0<kill>, pred:14, pred:%noreg, %vreg6<imp-def>; DPR_VFP2:%vreg6 GPR:%vreg0
+; %vreg6:ssub_1<def> = ...
; %vreg6:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg; mem:LD4[ConstantPool] DPR_VFP2:%vreg6
;
; When %vreg6 spills, the VLDRS constant pool load cannot be rematerialized
; since it implicitly reads the ssub_1 sub-register.
;
; CHECK: f1
-; CHECK: vmov s1, r0
+; CHECK: vmov d0, r0, r0
; CHECK: vldr s0, LCPI
; The vector must be spilled:
; CHECK: vstr d0,
diff --git a/test/CodeGen/ARM/trap.ll b/test/CodeGen/ARM/trap.ll
index 38842a9646ff..21865f8e4aed 100644
--- a/test/CodeGen/ARM/trap.ll
+++ b/test/CodeGen/ARM/trap.ll
@@ -14,4 +14,16 @@ entry:
unreachable
}
+define void @t2() nounwind {
+entry:
+; INSTR: t2:
+; INSTR: trap
+
+; FUNC: t2:
+; FUNC: bl __trap
+ call void @llvm.debugtrap()
+ unreachable
+}
+
declare void @llvm.trap() nounwind
+declare void @llvm.debugtrap() nounwind
diff --git a/test/CodeGen/ARM/twoaddrinstr.ll b/test/CodeGen/ARM/twoaddrinstr.ll
index 4e227dd5be36..fc2aa1e568e2 100644
--- a/test/CodeGen/ARM/twoaddrinstr.ll
+++ b/test/CodeGen/ARM/twoaddrinstr.ll
@@ -4,18 +4,18 @@
define void @PR13378() nounwind {
; This was orriginally a crasher trying to schedule the instructions.
; CHECK: PR13378:
-; CHECK: vldmia
+; CHECK: vld1.32
+; CHECK-NEXT: vst1.32
+; CHECK-NEXT: vst1.32
; CHECK-NEXT: vmov.f32
-; CHECK-NEXT: vstmia
-; CHECK-NEXT: vstmia
; CHECK-NEXT: vmov.f32
-; CHECK-NEXT: vstmia
+; CHECK-NEXT: vst1.32
entry:
- %0 = load <4 x float>* undef
- store <4 x float> zeroinitializer, <4 x float>* undef
- store <4 x float> %0, <4 x float>* undef
+ %0 = load <4 x float>* undef, align 4
+ store <4 x float> zeroinitializer, <4 x float>* undef, align 4
+ store <4 x float> %0, <4 x float>* undef, align 4
%1 = insertelement <4 x float> %0, float 1.000000e+00, i32 3
- store <4 x float> %1, <4 x float>* undef
+ store <4 x float> %1, <4 x float>* undef, align 4
unreachable
}
diff --git a/test/CodeGen/ARM/unaligned_load_store.ll b/test/CodeGen/ARM/unaligned_load_store.ll
index 869b92675def..3064202eb3fe 100644
--- a/test/CodeGen/ARM/unaligned_load_store.ll
+++ b/test/CodeGen/ARM/unaligned_load_store.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -march=arm -pre-RA-sched=source | FileCheck %s -check-prefix=EXPANDED
-; RUN: llc < %s -mtriple=armv6-apple-darwin -mcpu=cortex-a8 -arm-strict-align -pre-RA-sched=source | FileCheck %s -check-prefix=EXPANDED
+; RUN: llc < %s -mtriple=armv6-apple-darwin -mcpu=cortex-a8 -mattr=-neon -arm-strict-align -pre-RA-sched=source | FileCheck %s -check-prefix=EXPANDED
; RUN: llc < %s -mtriple=armv6-apple-darwin -mcpu=cortex-a8 | FileCheck %s -check-prefix=UNALIGNED
; rdar://7113725
@@ -59,3 +59,19 @@ entry:
store double %tmp, double* %b, align 1
ret void
}
+
+define void @byte_word_ops(i32* %a, i32* %b) nounwind {
+entry:
+; EXPANDED: byte_word_ops:
+; EXPANDED: ldrb
+; EXPANDED: strb
+
+; UNALIGNED: byte_word_ops:
+; UNALIGNED-NOT: ldrb
+; UNALIGNED: ldr
+; UNALIGNED-NOT: strb
+; UNALIGNED: str
+ %tmp = load i32* %a, align 1
+ store i32 %tmp, i32* %b, align 1
+ ret void
+}
diff --git a/test/CodeGen/ARM/unaligned_load_store_vector.ll b/test/CodeGen/ARM/unaligned_load_store_vector.ll
new file mode 100644
index 000000000000..25ae6517937b
--- /dev/null
+++ b/test/CodeGen/ARM/unaligned_load_store_vector.ll
@@ -0,0 +1,487 @@
+;RUN: llc < %s -march=arm -mattr=+v7 -mattr=+neon | FileCheck %s
+
+;ALIGN = 1
+;SIZE = 64
+;TYPE = <8 x i8>
+define void @v64_v8i8_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v8i8_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i8>*
+ %vo = bitcast i8* %po to <8 x i8>*
+;CHECK: vld1.8
+ %v1 = load <8 x i8>* %vi, align 1
+;CHECK: vst1.8
+ store <8 x i8> %v1, <8 x i8>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 64
+;TYPE = <4 x i16>
+define void @v64_v4i16_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v4i16_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i16>*
+ %vo = bitcast i8* %po to <4 x i16>*
+;CHECK: vld1.8
+ %v1 = load <4 x i16>* %vi, align 1
+;CHECK: vst1.8
+ store <4 x i16> %v1, <4 x i16>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 64
+;TYPE = <2 x i32>
+define void @v64_v2i32_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2i32_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i32>*
+ %vo = bitcast i8* %po to <2 x i32>*
+;CHECK: vld1.8
+ %v1 = load <2 x i32>* %vi, align 1
+;CHECK: vst1.8
+ store <2 x i32> %v1, <2 x i32>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 64
+;TYPE = <2 x float>
+define void @v64_v2f32_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2f32_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x float>*
+ %vo = bitcast i8* %po to <2 x float>*
+;CHECK: vld1.8
+ %v1 = load <2 x float>* %vi, align 1
+;CHECK: vst1.8
+ store <2 x float> %v1, <2 x float>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 128
+;TYPE = <16 x i8>
+define void @v128_v16i8_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v16i8_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <16 x i8>*
+ %vo = bitcast i8* %po to <16 x i8>*
+;CHECK: vld1.8
+ %v1 = load <16 x i8>* %vi, align 1
+;CHECK: vst1.8
+ store <16 x i8> %v1, <16 x i8>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 128
+;TYPE = <8 x i16>
+define void @v128_v8i16_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v8i16_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i16>*
+ %vo = bitcast i8* %po to <8 x i16>*
+;CHECK: vld1.8
+ %v1 = load <8 x i16>* %vi, align 1
+;CHECK: vst1.8
+ store <8 x i16> %v1, <8 x i16>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 128
+;TYPE = <4 x i32>
+define void @v128_v4i32_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4i32_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i32>*
+ %vo = bitcast i8* %po to <4 x i32>*
+;CHECK: vld1.8
+ %v1 = load <4 x i32>* %vi, align 1
+;CHECK: vst1.8
+ store <4 x i32> %v1, <4 x i32>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 128
+;TYPE = <2 x i64>
+define void @v128_v2i64_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v2i64_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i64>*
+ %vo = bitcast i8* %po to <2 x i64>*
+;CHECK: vld1.8
+ %v1 = load <2 x i64>* %vi, align 1
+;CHECK: vst1.8
+ store <2 x i64> %v1, <2 x i64>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 1
+;SIZE = 128
+;TYPE = <4 x float>
+define void @v128_v4f32_1(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4f32_1:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x float>*
+ %vo = bitcast i8* %po to <4 x float>*
+;CHECK: vld1.8
+ %v1 = load <4 x float>* %vi, align 1
+;CHECK: vst1.8
+ store <4 x float> %v1, <4 x float>* %vo, align 1
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 64
+;TYPE = <8 x i8>
+define void @v64_v8i8_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v8i8_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i8>*
+ %vo = bitcast i8* %po to <8 x i8>*
+;CHECK: vld1.16
+ %v1 = load <8 x i8>* %vi, align 2
+;CHECK: vst1.16
+ store <8 x i8> %v1, <8 x i8>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 64
+;TYPE = <4 x i16>
+define void @v64_v4i16_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v4i16_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i16>*
+ %vo = bitcast i8* %po to <4 x i16>*
+;CHECK: vld1.16
+ %v1 = load <4 x i16>* %vi, align 2
+;CHECK: vst1.16
+ store <4 x i16> %v1, <4 x i16>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 64
+;TYPE = <2 x i32>
+define void @v64_v2i32_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2i32_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i32>*
+ %vo = bitcast i8* %po to <2 x i32>*
+;CHECK: vld1.16
+ %v1 = load <2 x i32>* %vi, align 2
+;CHECK: vst1.16
+ store <2 x i32> %v1, <2 x i32>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 64
+;TYPE = <2 x float>
+define void @v64_v2f32_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2f32_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x float>*
+ %vo = bitcast i8* %po to <2 x float>*
+;CHECK: vld1.16
+ %v1 = load <2 x float>* %vi, align 2
+;CHECK: vst1.16
+ store <2 x float> %v1, <2 x float>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 128
+;TYPE = <16 x i8>
+define void @v128_v16i8_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v16i8_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <16 x i8>*
+ %vo = bitcast i8* %po to <16 x i8>*
+;CHECK: vld1.16
+ %v1 = load <16 x i8>* %vi, align 2
+;CHECK: vst1.16
+ store <16 x i8> %v1, <16 x i8>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 128
+;TYPE = <8 x i16>
+define void @v128_v8i16_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v8i16_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i16>*
+ %vo = bitcast i8* %po to <8 x i16>*
+;CHECK: vld1.16
+ %v1 = load <8 x i16>* %vi, align 2
+;CHECK: vst1.16
+ store <8 x i16> %v1, <8 x i16>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 128
+;TYPE = <4 x i32>
+define void @v128_v4i32_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4i32_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i32>*
+ %vo = bitcast i8* %po to <4 x i32>*
+;CHECK: vld1.16
+ %v1 = load <4 x i32>* %vi, align 2
+;CHECK: vst1.16
+ store <4 x i32> %v1, <4 x i32>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 128
+;TYPE = <2 x i64>
+define void @v128_v2i64_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v2i64_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i64>*
+ %vo = bitcast i8* %po to <2 x i64>*
+;CHECK: vld1.16
+ %v1 = load <2 x i64>* %vi, align 2
+;CHECK: vst1.16
+ store <2 x i64> %v1, <2 x i64>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 2
+;SIZE = 128
+;TYPE = <4 x float>
+define void @v128_v4f32_2(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4f32_2:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x float>*
+ %vo = bitcast i8* %po to <4 x float>*
+;CHECK: vld1.16
+ %v1 = load <4 x float>* %vi, align 2
+;CHECK: vst1.16
+ store <4 x float> %v1, <4 x float>* %vo, align 2
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 64
+;TYPE = <8 x i8>
+define void @v64_v8i8_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v8i8_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i8>*
+ %vo = bitcast i8* %po to <8 x i8>*
+;CHECK: vldr
+ %v1 = load <8 x i8>* %vi, align 4
+;CHECK: vstr
+ store <8 x i8> %v1, <8 x i8>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 64
+;TYPE = <4 x i16>
+define void @v64_v4i16_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v4i16_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i16>*
+ %vo = bitcast i8* %po to <4 x i16>*
+;CHECK: vldr
+ %v1 = load <4 x i16>* %vi, align 4
+;CHECK: vstr
+ store <4 x i16> %v1, <4 x i16>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 64
+;TYPE = <2 x i32>
+define void @v64_v2i32_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2i32_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i32>*
+ %vo = bitcast i8* %po to <2 x i32>*
+;CHECK: vldr
+ %v1 = load <2 x i32>* %vi, align 4
+;CHECK: vstr
+ store <2 x i32> %v1, <2 x i32>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 64
+;TYPE = <2 x float>
+define void @v64_v2f32_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v64_v2f32_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x float>*
+ %vo = bitcast i8* %po to <2 x float>*
+;CHECK: vldr
+ %v1 = load <2 x float>* %vi, align 4
+;CHECK: vstr
+ store <2 x float> %v1, <2 x float>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 128
+;TYPE = <16 x i8>
+define void @v128_v16i8_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v16i8_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <16 x i8>*
+ %vo = bitcast i8* %po to <16 x i8>*
+;CHECK: vld1.32
+ %v1 = load <16 x i8>* %vi, align 4
+;CHECK: vst1.32
+ store <16 x i8> %v1, <16 x i8>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 128
+;TYPE = <8 x i16>
+define void @v128_v8i16_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v8i16_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <8 x i16>*
+ %vo = bitcast i8* %po to <8 x i16>*
+;CHECK: vld1.32
+ %v1 = load <8 x i16>* %vi, align 4
+;CHECK: vst1.32
+ store <8 x i16> %v1, <8 x i16>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 128
+;TYPE = <4 x i32>
+define void @v128_v4i32_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4i32_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x i32>*
+ %vo = bitcast i8* %po to <4 x i32>*
+;CHECK: vld1.32
+ %v1 = load <4 x i32>* %vi, align 4
+;CHECK: vst1.32
+ store <4 x i32> %v1, <4 x i32>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 128
+;TYPE = <2 x i64>
+define void @v128_v2i64_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v2i64_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <2 x i64>*
+ %vo = bitcast i8* %po to <2 x i64>*
+;CHECK: vld1.32
+ %v1 = load <2 x i64>* %vi, align 4
+;CHECK: vst1.32
+ store <2 x i64> %v1, <2 x i64>* %vo, align 4
+ ret void
+}
+
+
+;ALIGN = 4
+;SIZE = 128
+;TYPE = <4 x float>
+define void @v128_v4f32_4(i8* noalias nocapture %out, i8* noalias nocapture %in) nounwind {
+;CHECK: v128_v4f32_4:
+entry:
+ %po = getelementptr i8* %out, i32 0
+ %pi = getelementptr i8* %in, i32 0
+ %vi = bitcast i8* %pi to <4 x float>*
+ %vo = bitcast i8* %po to <4 x float>*
+;CHECK: vld1.32
+ %v1 = load <4 x float>* %vi, align 4
+;CHECK: vst1.32
+ store <4 x float> %v1, <4 x float>* %vo, align 4
+ ret void
+}
+
diff --git a/test/CodeGen/ARM/vbsl-constant.ll b/test/CodeGen/ARM/vbsl-constant.ll
index f157dbdb970c..ffda0a51bdd0 100644
--- a/test/CodeGen/ARM/vbsl-constant.ll
+++ b/test/CodeGen/ARM/vbsl-constant.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
+; RUN: llc < %s -mtriple=arm-apple-ios -mattr=+neon | FileCheck %s
define <8 x i8> @v_bsli8(<8 x i8>* %A, <8 x i8>* %B, <8 x i8>* %C) nounwind {
;CHECK: v_bsli8:
@@ -59,8 +59,8 @@ define <1 x i64> @v_bsli64(<1 x i64>* %A, <1 x i64>* %B, <1 x i64>* %C) nounwind
define <16 x i8> @v_bslQi8(<16 x i8>* %A, <16 x i8>* %B, <16 x i8>* %C) nounwind {
;CHECK: v_bslQi8:
-;CHECK: vldmia
-;CHECK: vldmia
+;CHECK: vld1.32
+;CHECK: vld1.32
;CHECK: vbsl
%tmp1 = load <16 x i8>* %A
%tmp2 = load <16 x i8>* %B
@@ -73,8 +73,8 @@ define <16 x i8> @v_bslQi8(<16 x i8>* %A, <16 x i8>* %B, <16 x i8>* %C) nounwind
define <8 x i16> @v_bslQi16(<8 x i16>* %A, <8 x i16>* %B, <8 x i16>* %C) nounwind {
;CHECK: v_bslQi16:
-;CHECK: vldmia
-;CHECK: vldmia
+;CHECK: vld1.32
+;CHECK: vld1.32
;CHECK: vbsl
%tmp1 = load <8 x i16>* %A
%tmp2 = load <8 x i16>* %B
@@ -87,8 +87,8 @@ define <8 x i16> @v_bslQi16(<8 x i16>* %A, <8 x i16>* %B, <8 x i16>* %C) nounwin
define <4 x i32> @v_bslQi32(<4 x i32>* %A, <4 x i32>* %B, <4 x i32>* %C) nounwind {
;CHECK: v_bslQi32:
-;CHECK: vldmia
-;CHECK: vldmia
+;CHECK: vld1.32
+;CHECK: vld1.32
;CHECK: vbsl
%tmp1 = load <4 x i32>* %A
%tmp2 = load <4 x i32>* %B
@@ -101,9 +101,9 @@ define <4 x i32> @v_bslQi32(<4 x i32>* %A, <4 x i32>* %B, <4 x i32>* %C) nounwin
define <2 x i64> @v_bslQi64(<2 x i64>* %A, <2 x i64>* %B, <2 x i64>* %C) nounwind {
;CHECK: v_bslQi64:
-;CHECK: vldmia
-;CHECK: vldmia
-;CHECK: vldmia
+;CHECK: vld1.32
+;CHECK: vld1.32
+;CHECK: vld1.64
;CHECK: vbsl
%tmp1 = load <2 x i64>* %A
%tmp2 = load <2 x i64>* %B
diff --git a/test/CodeGen/ARM/vbsl.ll b/test/CodeGen/ARM/vbsl.ll
index 9f3bb4e1030c..750fb0de5383 100644
--- a/test/CodeGen/ARM/vbsl.ll
+++ b/test/CodeGen/ARM/vbsl.ll
@@ -1,5 +1,7 @@
; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
+; rdar://12471808
+
define <8 x i8> @v_bsli8(<8 x i8>* %A, <8 x i8>* %B, <8 x i8>* %C) nounwind {
;CHECK: v_bsli8:
;CHECK: vbsl
@@ -103,3 +105,98 @@ define <2 x i64> @v_bslQi64(<2 x i64>* %A, <2 x i64>* %B, <2 x i64>* %C) nounwin
%tmp7 = or <2 x i64> %tmp4, %tmp6
ret <2 x i64> %tmp7
}
+
+define <8 x i8> @f1(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) nounwind readnone optsize ssp {
+; CHECK: f1:
+; CHECK: vbsl
+ %vbsl.i = tail call <8 x i8> @llvm.arm.neon.vbsl.v8i8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) nounwind
+ ret <8 x i8> %vbsl.i
+}
+
+define <4 x i16> @f2(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c) nounwind readnone optsize ssp {
+; CHECK: f2:
+; CHECK: vbsl
+ %vbsl3.i = tail call <4 x i16> @llvm.arm.neon.vbsl.v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c) nounwind
+ ret <4 x i16> %vbsl3.i
+}
+
+define <2 x i32> @f3(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) nounwind readnone optsize ssp {
+; CHECK: f3:
+; CHECK: vbsl
+ %vbsl3.i = tail call <2 x i32> @llvm.arm.neon.vbsl.v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) nounwind
+ ret <2 x i32> %vbsl3.i
+}
+
+define <2 x float> @f4(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind readnone optsize ssp {
+; CHECK: f4:
+; CHECK: vbsl
+ %vbsl4.i = tail call <2 x float> @llvm.arm.neon.vbsl.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c) nounwind
+ ret <2 x float> %vbsl4.i
+}
+
+define <16 x i8> @g1(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) nounwind readnone optsize ssp {
+; CHECK: g1:
+; CHECK: vbsl
+ %vbsl.i = tail call <16 x i8> @llvm.arm.neon.vbsl.v16i8(<16 x i8> %a, <16 x i8> %b, <16 x i8> %c) nounwind
+ ret <16 x i8> %vbsl.i
+}
+
+define <8 x i16> @g2(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c) nounwind readnone optsize ssp {
+; CHECK: g2:
+; CHECK: vbsl
+ %vbsl3.i = tail call <8 x i16> @llvm.arm.neon.vbsl.v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c) nounwind
+ ret <8 x i16> %vbsl3.i
+}
+
+define <4 x i32> @g3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) nounwind readnone optsize ssp {
+; CHECK: g3:
+; CHECK: vbsl
+ %vbsl3.i = tail call <4 x i32> @llvm.arm.neon.vbsl.v4i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) nounwind
+ ret <4 x i32> %vbsl3.i
+}
+
+define <4 x float> @g4(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind readnone optsize ssp {
+; CHECK: g4:
+; CHECK: vbsl
+ %vbsl4.i = tail call <4 x float> @llvm.arm.neon.vbsl.v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) nounwind
+ ret <4 x float> %vbsl4.i
+}
+
+define <1 x i64> @test_vbsl_s64(<1 x i64> %a, <1 x i64> %b, <1 x i64> %c) nounwind readnone optsize ssp {
+; CHECK: test_vbsl_s64:
+; CHECK: vbsl d
+ %vbsl3.i = tail call <1 x i64> @llvm.arm.neon.vbsl.v1i64(<1 x i64> %a, <1 x i64> %b, <1 x i64> %c) nounwind
+ ret <1 x i64> %vbsl3.i
+}
+
+define <1 x i64> @test_vbsl_u64(<1 x i64> %a, <1 x i64> %b, <1 x i64> %c) nounwind readnone optsize ssp {
+; CHECK: test_vbsl_u64:
+; CHECK: vbsl d
+ %vbsl3.i = tail call <1 x i64> @llvm.arm.neon.vbsl.v1i64(<1 x i64> %a, <1 x i64> %b, <1 x i64> %c) nounwind
+ ret <1 x i64> %vbsl3.i
+}
+
+define <2 x i64> @test_vbslq_s64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) nounwind readnone optsize ssp {
+; CHECK: test_vbslq_s64:
+; CHECK: vbsl q
+ %vbsl3.i = tail call <2 x i64> @llvm.arm.neon.vbsl.v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) nounwind
+ ret <2 x i64> %vbsl3.i
+}
+
+define <2 x i64> @test_vbslq_u64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) nounwind readnone optsize ssp {
+; CHECK: test_vbslq_u64:
+; CHECK: vbsl q
+ %vbsl3.i = tail call <2 x i64> @llvm.arm.neon.vbsl.v2i64(<2 x i64> %a, <2 x i64> %b, <2 x i64> %c) nounwind
+ ret <2 x i64> %vbsl3.i
+}
+
+declare <4 x i32> @llvm.arm.neon.vbsl.v4i32(<4 x i32>, <4 x i32>, <4 x i32>) nounwind readnone
+declare <8 x i16> @llvm.arm.neon.vbsl.v8i16(<8 x i16>, <8 x i16>, <8 x i16>) nounwind readnone
+declare <16 x i8> @llvm.arm.neon.vbsl.v16i8(<16 x i8>, <16 x i8>, <16 x i8>) nounwind readnone
+declare <2 x i32> @llvm.arm.neon.vbsl.v2i32(<2 x i32>, <2 x i32>, <2 x i32>) nounwind readnone
+declare <4 x i16> @llvm.arm.neon.vbsl.v4i16(<4 x i16>, <4 x i16>, <4 x i16>) nounwind readnone
+declare <8 x i8> @llvm.arm.neon.vbsl.v8i8(<8 x i8>, <8 x i8>, <8 x i8>) nounwind readnone
+declare <2 x float> @llvm.arm.neon.vbsl.v2f32(<2 x float>, <2 x float>, <2 x float>) nounwind readnone
+declare <4 x float> @llvm.arm.neon.vbsl.v4f32(<4 x float>, <4 x float>, <4 x float>) nounwind readnone
+declare <2 x i64> @llvm.arm.neon.vbsl.v2i64(<2 x i64>, <2 x i64>, <2 x i64>) nounwind readnone
+declare <1 x i64> @llvm.arm.neon.vbsl.v1i64(<1 x i64>, <1 x i64>, <1 x i64>) nounwind readnone
diff --git a/test/CodeGen/ARM/vdup.ll b/test/CodeGen/ARM/vdup.ll
index 05332e4d8c5b..2cf94d63ca14 100644
--- a/test/CodeGen/ARM/vdup.ll
+++ b/test/CodeGen/ARM/vdup.ll
@@ -261,3 +261,73 @@ define void @redundantVdup(<8 x i8>* %ptr) nounwind {
store <8 x i8> %2, <8 x i8>* %ptr, align 8
ret void
}
+
+define <4 x i32> @tdupi(i32 %x, i32 %y) {
+;CHECK: tdupi
+;CHECK: vdup.32
+ %1 = insertelement <4 x i32> undef, i32 %x, i32 0
+ %2 = insertelement <4 x i32> %1, i32 %x, i32 1
+ %3 = insertelement <4 x i32> %2, i32 %x, i32 2
+ %4 = insertelement <4 x i32> %3, i32 %y, i32 3
+ ret <4 x i32> %4
+}
+
+define <4 x float> @tdupf(float %x, float %y) {
+;CHECK: tdupf
+;CHECK: vdup.32
+ %1 = insertelement <4 x float> undef, float %x, i32 0
+ %2 = insertelement <4 x float> %1, float %x, i32 1
+ %3 = insertelement <4 x float> %2, float %x, i32 2
+ %4 = insertelement <4 x float> %3, float %y, i32 3
+ ret <4 x float> %4
+}
+
+; This test checks that when splatting an element from a vector into another,
+; the value isn't moved out to GPRs first.
+define <4 x i32> @tduplane(<4 x i32> %invec) {
+;CHECK: tduplane
+;CHECK-NOT: vmov {{.*}}, d16[1]
+;CHECK: vdup.32 {{.*}}, d16[1]
+ %in = extractelement <4 x i32> %invec, i32 1
+ %1 = insertelement <4 x i32> undef, i32 %in, i32 0
+ %2 = insertelement <4 x i32> %1, i32 %in, i32 1
+ %3 = insertelement <4 x i32> %2, i32 %in, i32 2
+ %4 = insertelement <4 x i32> %3, i32 255, i32 3
+ ret <4 x i32> %4
+}
+
+define <2 x float> @check_f32(<4 x float> %v) nounwind {
+;CHECK: check_f32:
+;CHECK: vdup.32 {{.*}}, d{{..}}[1]
+ %x = extractelement <4 x float> %v, i32 3
+ %1 = insertelement <2 x float> undef, float %x, i32 0
+ %2 = insertelement <2 x float> %1, float %x, i32 1
+ ret <2 x float> %2
+}
+
+define <2 x i32> @check_i32(<4 x i32> %v) nounwind {
+;CHECK: check_i32:
+;CHECK: vdup.32 {{.*}}, d{{..}}[1]
+ %x = extractelement <4 x i32> %v, i32 3
+ %1 = insertelement <2 x i32> undef, i32 %x, i32 0
+ %2 = insertelement <2 x i32> %1, i32 %x, i32 1
+ ret <2 x i32> %2
+}
+
+define <4 x i16> @check_i16(<8 x i16> %v) nounwind {
+;CHECK: check_i16:
+;CHECK: vdup.16 {{.*}}, d{{..}}[3]
+ %x = extractelement <8 x i16> %v, i32 3
+ %1 = insertelement <4 x i16> undef, i16 %x, i32 0
+ %2 = insertelement <4 x i16> %1, i16 %x, i32 1
+ ret <4 x i16> %2
+}
+
+define <8 x i8> @check_i8(<16 x i8> %v) nounwind {
+;CHECK: check_i8:
+;CHECK: vdup.8 {{.*}}, d{{..}}[3]
+ %x = extractelement <16 x i8> %v, i32 3
+ %1 = insertelement <8 x i8> undef, i8 %x, i32 0
+ %2 = insertelement <8 x i8> %1, i8 %x, i32 1
+ ret <8 x i8> %2
+}
diff --git a/test/CodeGen/ARM/vector-extend-narrow.ll b/test/CodeGen/ARM/vector-extend-narrow.ll
index 8fd3db29197e..22af79762128 100644
--- a/test/CodeGen/ARM/vector-extend-narrow.ll
+++ b/test/CodeGen/ARM/vector-extend-narrow.ll
@@ -62,3 +62,14 @@ define <4 x i8> @i(<4 x i8>* %x) {
%2 = sdiv <4 x i8> zeroinitializer, %1
ret <4 x i8> %2
}
+; CHECK: j:
+define <4 x i32> @j(<4 x i8>* %in) nounwind {
+ ; CHECK: vld1
+ ; CHECK: vmovl.u8
+ ; CHECK: vmovl.u16
+ ; CHECK-NOT: vand
+ %1 = load <4 x i8>* %in, align 4
+ %2 = zext <4 x i8> %1 to <4 x i32>
+ ret <4 x i32> %2
+}
+
diff --git a/test/CodeGen/ARM/vext.ll b/test/CodeGen/ARM/vext.ll
index e224bdfe25a5..f404eb8be5b7 100644
--- a/test/CodeGen/ARM/vext.ll
+++ b/test/CodeGen/ARM/vext.ll
@@ -74,6 +74,39 @@ define <16 x i8> @test_vextRq_undef(<16 x i8>* %A, <16 x i8>* %B) nounwind {
ret <16 x i8> %tmp3
}
+define <16 x i8> @test_vextq_undef_op2(<16 x i8> %a) nounwind {
+;CHECK: test_vextq_undef_op2:
+;CHECK: vext
+entry:
+ %tmp1 = shufflevector <16 x i8> %a, <16 x i8> undef, <16 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1>
+ ret <16 x i8> %tmp1
+}
+
+define <8 x i8> @test_vextd_undef_op2(<8 x i8> %a) nounwind {
+;CHECK: test_vextd_undef_op2:
+;CHECK: vext
+entry:
+ %tmp1 = shufflevector <8 x i8> %a, <8 x i8> undef, <8 x i32> <i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1>
+ ret <8 x i8> %tmp1
+}
+
+
+define <16 x i8> @test_vextq_undef_op2_undef(<16 x i8> %a) nounwind {
+;CHECK: test_vextq_undef_op2_undef:
+;CHECK: vext
+entry:
+ %tmp1 = shufflevector <16 x i8> %a, <16 x i8> undef, <16 x i32> <i32 2, i32 3, i32 4, i32 undef, i32 undef, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1>
+ ret <16 x i8> %tmp1
+}
+
+define <8 x i8> @test_vextd_undef_op2_undef(<8 x i8> %a) nounwind {
+;CHECK: test_vextd_undef_op2_undef:
+;CHECK: vext
+entry:
+ %tmp1 = shufflevector <8 x i8> %a, <8 x i8> undef, <8 x i32> <i32 2, i32 3, i32 undef, i32 undef, i32 6, i32 7, i32 undef, i32 1>
+ ret <8 x i8> %tmp1
+}
+
; Tests for ReconstructShuffle function. Indices have to be carefully
; chosen to reach lowering phase as a BUILD_VECTOR.
diff --git a/test/CodeGen/ARM/vget_lane.ll b/test/CodeGen/ARM/vget_lane.ll
index 1fc885d61372..c9ce3b7450b6 100644
--- a/test/CodeGen/ARM/vget_lane.ll
+++ b/test/CodeGen/ARM/vget_lane.ll
@@ -200,7 +200,7 @@ define <8 x i16> @vsetQ_lane16(<8 x i16>* %A, i16 %B) nounwind {
define <4 x i32> @vsetQ_lane32(<4 x i32>* %A, i32 %B) nounwind {
;CHECK: vsetQ_lane32:
-;CHECK: vmov.32
+;CHECK: vmov.32 d{{.*}}[1], r1
%tmp1 = load <4 x i32>* %A
%tmp2 = insertelement <4 x i32> %tmp1, i32 %B, i32 1
ret <4 x i32> %tmp2
diff --git a/test/CodeGen/ARM/vselect_imax.ll b/test/CodeGen/ARM/vselect_imax.ll
new file mode 100644
index 000000000000..f5994046de4b
--- /dev/null
+++ b/test/CodeGen/ARM/vselect_imax.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -march=arm -mattr=+neon | FileCheck %s
+; Make sure that ARM backend with NEON handles vselect.
+
+define void @vmax_v4i32(<4 x i32>* %m, <4 x i32> %a, <4 x i32> %b) {
+; CHECK: vcgt.s32 [[QR:q[0-9]+]], [[Q1:q[0-9]+]], [[Q2:q[0-9]+]]
+; CHECK: vbsl [[QR]], [[Q1]], [[Q2]]
+ %cmpres = icmp sgt <4 x i32> %a, %b
+ %maxres = select <4 x i1> %cmpres, <4 x i32> %a, <4 x i32> %b
+ store <4 x i32> %maxres, <4 x i32>* %m
+ ret void
+}
+