summaryrefslogtreecommitdiff
path: root/test/CodeGen/ARM/Windows
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:08:18 +0000
commit5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (patch)
treef5944309621cee4fe0976be6f9ac619b7ebfc4c2 /test/CodeGen/ARM/Windows
parent68bcb7db193e4bc81430063148253d30a791023e (diff)
Notes
Diffstat (limited to 'test/CodeGen/ARM/Windows')
-rw-r--r--test/CodeGen/ARM/Windows/aapcs.ll16
-rw-r--r--test/CodeGen/ARM/Windows/alloca.ll22
-rw-r--r--test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll27
-rw-r--r--test/CodeGen/ARM/Windows/chkstk.ll24
-rw-r--r--test/CodeGen/ARM/Windows/dllimport.ll61
-rw-r--r--test/CodeGen/ARM/Windows/frame-register.ll22
-rw-r--r--test/CodeGen/ARM/Windows/global-minsize.ll16
-rw-r--r--test/CodeGen/ARM/Windows/hard-float.ll10
-rw-r--r--test/CodeGen/ARM/Windows/integer-floating-point-conversion.ll74
-rw-r--r--test/CodeGen/ARM/Windows/long-calls.ll18
-rw-r--r--test/CodeGen/ARM/Windows/mangling.ll9
-rw-r--r--test/CodeGen/ARM/Windows/memset.ll18
-rw-r--r--test/CodeGen/ARM/Windows/mov32t-bundling.ll28
-rw-r--r--test/CodeGen/ARM/Windows/movw-movt-relocations.ll27
-rw-r--r--test/CodeGen/ARM/Windows/no-aeabi.ll32
-rw-r--r--test/CodeGen/ARM/Windows/no-arm-mode.ll5
-rw-r--r--test/CodeGen/ARM/Windows/no-ehabi.ll21
-rw-r--r--test/CodeGen/ARM/Windows/pic.ll16
-rw-r--r--test/CodeGen/ARM/Windows/read-only-data.ll15
-rw-r--r--test/CodeGen/ARM/Windows/structors.ll12
-rw-r--r--test/CodeGen/ARM/Windows/vla.ll31
21 files changed, 504 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/Windows/aapcs.ll b/test/CodeGen/ARM/Windows/aapcs.ll
new file mode 100644
index 000000000000..3f9a09f8e7f5
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/aapcs.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+; AAPCS mandates an 8-byte stack alignment. The alloca is implicitly aligned,
+; and no bic is required.
+
+declare void @callee(i8 *%i)
+
+define void @caller() {
+ %i = alloca i8, align 8
+ call void @callee(i8* %i)
+ ret void
+}
+
+; CHECK: sub sp, #8
+; CHECK-NOT: bic
+
diff --git a/test/CodeGen/ARM/Windows/alloca.ll b/test/CodeGen/ARM/Windows/alloca.ll
new file mode 100644
index 000000000000..6a3d002ab3b3
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/alloca.ll
@@ -0,0 +1,22 @@
+; RUN: llc -O0 -mtriple thumbv7-windows-itanium -filetype asm -o - %s | FileCheck %s
+
+declare arm_aapcs_vfpcc i32 @num_entries()
+
+define arm_aapcs_vfpcc void @test___builtin_alloca() {
+entry:
+ %array = alloca i8*, align 4
+ %call = call arm_aapcs_vfpcc i32 @num_entries()
+ %mul = mul i32 4, %call
+ %0 = alloca i8, i32 %mul
+ store i8* %0, i8** %array, align 4
+ ret void
+}
+
+; CHECK: bl num_entries
+; CHECK: movs [[R1:r[0-9]+]], #7
+; CHECK: add.w [[R0:r[0-9]+]], [[R1]], [[R0]], lsl #2
+; CHECK: bic [[R0]], [[R0]], #7
+; CHECK: lsrs r4, [[R0]], #2
+; CHECK: bl __chkstk
+; CHECK: sub.w sp, sp, r4
+
diff --git a/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll b/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll
new file mode 100644
index 000000000000..a82f6141dbb3
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple thumbv7--windows-itanium -code-model large -filetype obj -o - %s \
+; RUN: | llvm-objdump -no-show-raw-insn -d - | FileCheck %s
+
+; ModuleID = 'reduced.c'
+target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv7--windows-itanium"
+
+define arm_aapcs_vfpcc i8 @isel(i32 %i) {
+entry:
+ %i.addr = alloca i32, align 4
+ %buffer = alloca [4096 x i8], align 1
+ store i32 %i, i32* %i.addr, align 4
+ %0 = load i32* %i.addr, align 4
+ %rem = urem i32 %0, 4096
+ %arrayidx = getelementptr inbounds [4096 x i8]* %buffer, i32 0, i32 %rem
+ %1 = load volatile i8* %arrayidx, align 1
+ ret i8 %1
+}
+
+; CHECK-LABEL: isel
+; CHECK: push {r4, r5}
+; CHECK: movw r4, #{{\d*}}
+; CHECK: movw r12, #0
+; CHECK: movt r12, #0
+; CHECK: blx r12
+; CHECK: sub.w sp, sp, r4
+
diff --git a/test/CodeGen/ARM/Windows/chkstk.ll b/test/CodeGen/ARM/Windows/chkstk.ll
new file mode 100644
index 000000000000..cb787e14b5ba
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/chkstk.ll
@@ -0,0 +1,24 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 %s -o - \
+; RUN: | FileCheck -check-prefix CHECK-DEFAULT-CODE-MODEL %s
+
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -code-model=large %s -o - \
+; RUN: | FileCheck -check-prefix CHECK-LARGE-CODE-MODEL %s
+
+define arm_aapcs_vfpcc void @check_watermark() {
+entry:
+ %buffer = alloca [4096 x i8], align 1
+ ret void
+}
+
+; CHECK-DEFAULT-CODE-MODEL: check_watermark:
+; CHECK-DEFAULT-CODE-MODEL: movw r4, #1024
+; CHECK-DEFAULT-CODE-MODEL: bl __chkstk
+; CHECK-DEFAULT-CODE-MODEL: sub.w sp, sp, r4
+
+; CHECK-LARGE-CODE-MODEL: check_watermark:
+; CHECK-LARGE-CODE-MODEL: movw r12, :lower16:__chkstk
+; CHECK-LARGE-CODE-MODEL: movt r12, :upper16:__chkstk
+; CHECK-LARGE-CODE-MODEL: movw r4, #1024
+; CHECK-LARGE-CODE-MODEL: blx r12
+; CHECK-LARGE-CODE-MODEL: sub.w sp, sp, r4
+
diff --git a/test/CodeGen/ARM/Windows/dllimport.ll b/test/CodeGen/ARM/Windows/dllimport.ll
new file mode 100644
index 000000000000..bc737bd41827
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/dllimport.ll
@@ -0,0 +1,61 @@
+; RUN: llc -mtriple thumbv7-windows -filetype asm -o - %s | FileCheck %s
+
+; ModuleID = 'dllimport.c'
+
+@var = external dllimport global i32
+@ext = external global i32
+declare dllimport arm_aapcs_vfpcc i32 @external()
+declare arm_aapcs_vfpcc i32 @internal()
+
+define arm_aapcs_vfpcc i32 @get_var() {
+ %1 = load i32* @var, align 4
+ ret i32 %1
+}
+
+; CHECK-LABEL: get_var
+; CHECK: movw r0, :lower16:__imp_var
+; CHECK: movt r0, :upper16:__imp_var
+; CHECK: ldr r0, [r0]
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+
+define arm_aapcs_vfpcc i32 @get_ext() {
+ %1 = load i32* @ext, align 4
+ ret i32 %1
+}
+
+; CHECK-LABEL: get_ext
+; CHECK: movw r0, :lower16:ext
+; CHECK: movt r0, :upper16:ext
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+
+define arm_aapcs_vfpcc i32* @get_var_pointer() {
+ ret i32* @var
+}
+
+; CHECK-LABEL: get_var_pointer
+; CHECK: movw r0, :lower16:__imp_var
+; CHECK: movt r0, :upper16:__imp_var
+; CHECK: ldr r0, [r0]
+; CHECK: bx lr
+
+define arm_aapcs_vfpcc i32 @call_external() {
+ %call = tail call arm_aapcs_vfpcc i32 @external()
+ ret i32 %call
+}
+
+; CHECK-LABEL: call_external
+; CHECK: movw r0, :lower16:__imp_external
+; CHECK: movt r0, :upper16:__imp_external
+; CHECK: ldr r0, [r0]
+; CHECK: bx r0
+
+define arm_aapcs_vfpcc i32 @call_internal() {
+ %call = tail call arm_aapcs_vfpcc i32 @internal()
+ ret i32 %call
+}
+
+; CHECK-LABEL: call_internal
+; CHECK: b internal
+
diff --git a/test/CodeGen/ARM/Windows/frame-register.ll b/test/CodeGen/ARM/Windows/frame-register.ll
new file mode 100644
index 000000000000..31167d7352e3
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/frame-register.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple thumbv7-windows -disable-fp-elim -filetype asm -o - %s \
+; RUN: | FileCheck %s
+
+declare void @callee(i32)
+
+define i32 @calleer(i32 %i) {
+entry:
+ %i.addr = alloca i32, align 4
+ %j = alloca i32, align 4
+ store i32 %i, i32* %i.addr, align 4
+ %0 = load i32* %i.addr, align 4
+ %add = add nsw i32 %0, 1
+ store i32 %add, i32* %j, align 4
+ %1 = load i32* %j, align 4
+ call void @callee(i32 %1)
+ %2 = load i32* %j, align 4
+ %add1 = add nsw i32 %2, 1
+ ret i32 %add1
+}
+
+; CHECK: push.w {r11, lr}
+
diff --git a/test/CodeGen/ARM/Windows/global-minsize.ll b/test/CodeGen/ARM/Windows/global-minsize.ll
new file mode 100644
index 000000000000..c0be36caa6c4
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/global-minsize.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=thumbv7-windows -filetype asm -o - %s | FileCheck %s
+
+@i = internal global i32 0, align 4
+
+; Function Attrs: minsize
+define arm_aapcs_vfpcc i32* @function() #0 {
+entry:
+ ret i32* @i
+}
+
+attributes #0 = { minsize }
+
+; CHECK: function:
+; CHECK: movw r0, :lower16:i
+; CHECK: movt r0, :upper16:i
+; CHECK: bx lr
diff --git a/test/CodeGen/ARM/Windows/hard-float.ll b/test/CodeGen/ARM/Windows/hard-float.ll
new file mode 100644
index 000000000000..f7b7ec273ce8
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/hard-float.ll
@@ -0,0 +1,10 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+define float @function(float %f, float %g) nounwind {
+entry:
+ %h = fadd float %f, %g
+ ret float %h
+}
+
+; CHECK: vadd.f32 s0, s0, s1
+
diff --git a/test/CodeGen/ARM/Windows/integer-floating-point-conversion.ll b/test/CodeGen/ARM/Windows/integer-floating-point-conversion.ll
new file mode 100644
index 000000000000..acf21a1caad3
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/integer-floating-point-conversion.ll
@@ -0,0 +1,74 @@
+; RUN: llc -mtriple thumbv7-windows -filetype asm -o - %s | FileCheck %s
+
+define arm_aapcs_vfpcc i64 @stoi64(float %f) {
+entry:
+ %conv = fptosi float %f to i64
+ ret i64 %conv
+}
+
+; CHECK-LABEL: stoi64
+; CHECK: bl __stoi64
+
+define arm_aapcs_vfpcc i64 @stou64(float %f) {
+entry:
+ %conv = fptoui float %f to i64
+ ret i64 %conv
+}
+
+; CHECK-LABEL: stou64
+; CHECK: bl __stou64
+
+define arm_aapcs_vfpcc float @i64tos(i64 %i64) {
+entry:
+ %conv = sitofp i64 %i64 to float
+ ret float %conv
+}
+
+; CHECK-LABEL: i64tos
+; CHECK: bl __i64tos
+
+define arm_aapcs_vfpcc float @u64tos(i64 %u64) {
+entry:
+ %conv = uitofp i64 %u64 to float
+ ret float %conv
+}
+
+; CHECK-LABEL: u64tos
+; CHECK: bl __u64tos
+
+define arm_aapcs_vfpcc i64 @dtoi64(double %d) {
+entry:
+ %conv = fptosi double %d to i64
+ ret i64 %conv
+}
+
+; CHECK-LABEL: dtoi64
+; CHECK: bl __dtoi64
+
+define arm_aapcs_vfpcc i64 @dtou64(double %d) {
+entry:
+ %conv = fptoui double %d to i64
+ ret i64 %conv
+}
+
+; CHECK-LABEL: dtou64
+; CHECK: bl __dtou64
+
+define arm_aapcs_vfpcc double @i64tod(i64 %i64) {
+entry:
+ %conv = sitofp i64 %i64 to double
+ ret double %conv
+}
+
+; CHECK-LABEL: i64tod
+; CHECK: bl __i64tod
+
+define arm_aapcs_vfpcc double @u64tod(i64 %i64) {
+entry:
+ %conv = uitofp i64 %i64 to double
+ ret double %conv
+}
+
+; CHECK-LABEL: u64tod
+; CHECK: bl __u64tod
+
diff --git a/test/CodeGen/ARM/Windows/long-calls.ll b/test/CodeGen/ARM/Windows/long-calls.ll
new file mode 100644
index 000000000000..e35f414579af
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/long-calls.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -arm-long-calls -o - %s \
+; RUN: | FileCheck %s
+
+declare arm_aapcs_vfpcc void @callee()
+
+define arm_aapcs_vfpcc void @caller() nounwind {
+entry:
+ tail call void @callee()
+ ret void
+}
+
+; CHECK-LABEL: caller
+; CHECK: ldr [[REG:r[0-9]+]], [[CPI:.LCPI[_0-9]+]]
+; CHECK: bx [[REG]]
+; CHECK: .align 2
+; CHECK: [[CPI]]:
+; CHECK: .long callee
+
diff --git a/test/CodeGen/ARM/Windows/mangling.ll b/test/CodeGen/ARM/Windows/mangling.ll
new file mode 100644
index 000000000000..ce1fe2ee7e16
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/mangling.ll
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+define void @function() nounwind {
+entry:
+ ret void
+}
+
+; CHECK-LABEL: function
+
diff --git a/test/CodeGen/ARM/Windows/memset.ll b/test/CodeGen/ARM/Windows/memset.ll
new file mode 100644
index 000000000000..500e25e259c6
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/memset.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple thumbv7--windows-itanium -filetype asm -o - %s | FileCheck %s
+
+@source = common global [512 x i8] zeroinitializer, align 4
+
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
+
+define void @function() {
+entry:
+ call void @llvm.memset.p0i8.i32(i8* bitcast ([512 x i8]* @source to i8*), i8 0, i32 512, i32 0, i1 false)
+ unreachable
+}
+
+; CHECK: movw r0, :lower16:source
+; CHECK: movt r0, :upper16:source
+; CHECK: movs r1, #0
+; CHECK: mov.w r2, #512
+; CHECK: memset
+
diff --git a/test/CodeGen/ARM/Windows/mov32t-bundling.ll b/test/CodeGen/ARM/Windows/mov32t-bundling.ll
new file mode 100644
index 000000000000..5f838378fa87
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/mov32t-bundling.ll
@@ -0,0 +1,28 @@
+; RUN: llc -mtriple thumbv7-windows-itanium -filetype asm -o - %s | FileCheck %s
+
+@_begin = external global i8
+@_end = external global i8
+
+declare arm_aapcs_vfpcc void @force_emission()
+
+define arm_aapcs_vfpcc void @bundle() {
+entry:
+ br i1 icmp uge (i32 sub (i32 ptrtoint (i8* @_end to i32), i32 ptrtoint (i8* @_begin to i32)), i32 4), label %if.then, label %if.end
+
+if.then:
+ tail call arm_aapcs_vfpcc void @force_emission()
+ br label %if.end
+
+if.end:
+ ret void
+}
+
+; CHECK-LABEL: bundle
+; CHECK-NOT: subs r0, r1, r0
+; CHECK: movw r0, :lower16:_begin
+; CHECK-NEXT: movt r0, :upper16:_begin
+; CHECK-NEXT: movw r1, :lower16:_end
+; CHECK-NEXT: movt r1, :upper16:_end
+; CHECK-NEXT: subs r0, r1, r0
+; CHECK-NEXT: cmp r0, #4
+
diff --git a/test/CodeGen/ARM/Windows/movw-movt-relocations.ll b/test/CodeGen/ARM/Windows/movw-movt-relocations.ll
new file mode 100644
index 000000000000..3ae6428d3a6b
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/movw-movt-relocations.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=thumbv7-windows -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-WINDOWS
+
+; RUN: llc -mtriple=thumbv7-eabi -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-EABI
+
+@i = common global i32 0, align 4
+@j = common global i32 0, align 4
+
+; Function Attrs: nounwind optsize readonly
+define i32 @relocation(i32 %j, i32 %k) {
+entry:
+ %0 = load i32* @i, align 4
+ %1 = load i32* @j, align 4
+ %add = add nsw i32 %1, %0
+ ret i32 %add
+}
+
+; CHECK-WINDOWS: movw r[[i:[0-4]]], :lower16:i
+; CHECK-WINDOWS-NEXT: movt r[[i]], :upper16:i
+; CHECK-WINDOWS: movw r[[j:[0-4]]], :lower16:j
+; CHECK-WINDOWS-NEXT: movt r[[j]], :upper16:j
+
+; CHECK-EABI: movw r[[i:[0-4]]], :lower16:i
+; CHECK-EABI: movw r[[j:[0-4]]], :lower16:j
+; CHECK-EABI-NEXT: movt r[[i]], :upper16:i
+; CHECK-EABI-NEXT: movt r[[j]], :upper16:j
diff --git a/test/CodeGen/ARM/Windows/no-aeabi.ll b/test/CodeGen/ARM/Windows/no-aeabi.ll
new file mode 100644
index 000000000000..3971b9ccf580
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/no-aeabi.ll
@@ -0,0 +1,32 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
+
+@source = common global [512 x i8] zeroinitializer, align 4
+@target = common global [512 x i8] zeroinitializer, align 4
+
+define void @move() nounwind {
+entry:
+ call void @llvm.memmove.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i32 0, i1 false)
+ unreachable
+}
+
+; CHECK-NOT: __aeabi_memmove
+
+define void @copy() nounwind {
+entry:
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast ([512 x i8]* @target to i8*), i8* bitcast ([512 x i8]* @source to i8*), i32 512, i32 0, i1 false)
+ unreachable
+}
+
+; CHECK-NOT: __aeabi_memcpy
+
+define i32 @divide(i32 %i, i32 %j) nounwind {
+entry:
+ %quotient = sdiv i32 %i, %j
+ ret i32 %quotient
+}
+
+; CHECK-NOT: __aeabi_idiv
+
diff --git a/test/CodeGen/ARM/Windows/no-arm-mode.ll b/test/CodeGen/ARM/Windows/no-arm-mode.ll
new file mode 100644
index 000000000000..6db031fc9169
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/no-arm-mode.ll
@@ -0,0 +1,5 @@
+; RUN: not llc -mtriple=armv7-windows-itanium -mcpu=cortex-a9 -o /dev/null %s 2>&1 \
+; RUN: | FileCheck %s
+
+; CHECK: does not support ARM mode execution
+
diff --git a/test/CodeGen/ARM/Windows/no-ehabi.ll b/test/CodeGen/ARM/Windows/no-ehabi.ll
new file mode 100644
index 000000000000..4119b6da968e
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/no-ehabi.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+declare void @callee(i32 %i)
+
+define i32 @caller(i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o,
+ i32 %p) {
+entry:
+ %q = add nsw i32 %j, %i
+ %r = add nsw i32 %q, %k
+ %s = add nsw i32 %r, %l
+ call void @callee(i32 %s)
+ %t = add nsw i32 %n, %m
+ %u = add nsw i32 %t, %o
+ %v = add nsw i32 %u, %p
+ call void @callee(i32 %v)
+ %w = add nsw i32 %v, %s
+ ret i32 %w
+}
+
+; CHECK-NOT: .save {{{.*}}}
+
diff --git a/test/CodeGen/ARM/Windows/pic.ll b/test/CodeGen/ARM/Windows/pic.ll
new file mode 100644
index 000000000000..28d371f45217
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/pic.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple thumbv7-windows-itanium -relocation-model pic -filetype asm -o - %s \
+; RUN: | FileCheck %s
+
+@external = external global i8
+
+define arm_aapcs_vfpcc i8 @return_external() {
+entry:
+ %0 = load i8* @external, align 1
+ ret i8 %0
+}
+
+; CHECK-LABEL: return_external
+; CHECK: movw r0, :lower16:external
+; CHECK: movt r0, :upper16:external
+; CHECK: ldrb r0, [r0]
+
diff --git a/test/CodeGen/ARM/Windows/read-only-data.ll b/test/CodeGen/ARM/Windows/read-only-data.ll
new file mode 100644
index 000000000000..0ccb5ededff2
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/read-only-data.ll
@@ -0,0 +1,15 @@
+; RUN: llc -mtriple thumbv7-windows -filetype asm -o - %s | FileCheck %s
+
+@.str = private unnamed_addr constant [7 x i8] c"string\00", align 1
+
+declare arm_aapcs_vfpcc void @callee(i8*)
+
+define arm_aapcs_vfpcc void @function() {
+entry:
+ call arm_aapcs_vfpcc void @callee(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0))
+ ret void
+}
+
+; CHECK: .section .rdata,"rd"
+; CHECK-NOT: .section ".rodata.str1.1"
+
diff --git a/test/CodeGen/ARM/Windows/structors.ll b/test/CodeGen/ARM/Windows/structors.ll
new file mode 100644
index 000000000000..a1a90265c03a
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/structors.ll
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple thumbv7-windows-itanium -o - %s | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @function, i8* null }]
+
+define arm_aapcs_vfpcc void @function() {
+entry:
+ ret void
+}
+
+; CHECK: .section .CRT$XCU,"rd"
+; CHECK: .long function
+
diff --git a/test/CodeGen/ARM/Windows/vla.ll b/test/CodeGen/ARM/Windows/vla.ll
new file mode 100644
index 000000000000..56901dee0dfa
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/vla.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-SMALL-CODE
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -code-model=large -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-LARGE-CODE
+; RUN: llc -mtriple=thumbv7-windows-msvc -mcpu=cortex-a9 -o - %s \
+; RUN: | FileCheck %s -check-prefix CHECK-MSVC
+
+define arm_aapcs_vfpcc i8 @function(i32 %sz, i32 %idx) {
+entry:
+ %vla = alloca i8, i32 %sz, align 1
+ %arrayidx = getelementptr inbounds i8* %vla, i32 %idx
+ %0 = load volatile i8* %arrayidx, align 1
+ ret i8 %0
+}
+
+; CHECK-SMALL-CODE: adds [[R4:r[0-9]+]], #7
+; CHECK-SMALL-CODE: bic [[R4]], [[R4]], #7
+; CHECK-SMALL-CODE: lsrs r4, [[R4]], #2
+; CHECK-SMALL-CODE: bl __chkstk
+; CHECK-SMALL-CODE: sub.w sp, sp, r4
+
+; CHECK-LARGE-CODE: adds [[R4:r[0-9]+]], #7
+; CHECK-LARGE-CODE: bic [[R4]], [[R4]], #7
+; CHECK-LARGE-CODE: lsrs r4, [[R4]], #2
+; CHECK-LARGE-CODE: movw [[IP:r[0-9]+]], :lower16:__chkstk
+; CHECK-LARGE-CODE: movt [[IP]], :upper16:__chkstk
+; CHECK-LARGE-CODE: blx [[IP]]
+; CHECK-LARGE-CODE: sub.w sp, sp, r4
+
+; CHECK-MSVC-NOT: __chkstk
+