summaryrefslogtreecommitdiff
path: root/test/CodeGen/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/ARM')
-rw-r--r--test/CodeGen/ARM/2009-08-31-LSDA-Name.ll8
-rw-r--r--test/CodeGen/ARM/2009-10-16-Scope.ll5
-rw-r--r--test/CodeGen/ARM/2010-04-15-ScavengerDebugValue.ll5
-rw-r--r--test/CodeGen/ARM/2010-06-25-Thumb2ITInvalidIterator.ll7
-rw-r--r--test/CodeGen/ARM/2010-08-04-StackVariable.ll20
-rw-r--r--test/CodeGen/ARM/2010-11-29-PrologueBug.ll25
-rw-r--r--test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll13
-rw-r--r--test/CodeGen/ARM/2011-04-15-AndVFlagPeepholeBug.ll2
-rw-r--r--test/CodeGen/ARM/2011-04-15-RegisterCmpPeephole.ll4
-rw-r--r--test/CodeGen/ARM/2011-04-26-SchedTweak.ll4
-rw-r--r--test/CodeGen/ARM/2011-06-09-TailCallByVal.ll2
-rw-r--r--test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll13
-rw-r--r--test/CodeGen/ARM/2011-08-25-ldmia_ret.ll2
-rw-r--r--test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll3
-rw-r--r--test/CodeGen/ARM/2016-05-01-RegScavengerAssert.ll192
-rw-r--r--test/CodeGen/ARM/ARMLoadStoreDBG.mir164
-rw-r--r--test/CodeGen/ARM/Windows/builtin_longjmp.ll15
-rw-r--r--test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll2
-rw-r--r--test/CodeGen/ARM/Windows/chkstk.ll4
-rw-r--r--test/CodeGen/ARM/Windows/dbzchk.ll192
-rw-r--r--test/CodeGen/ARM/Windows/division.ll23
-rw-r--r--test/CodeGen/ARM/Windows/dllexport.ll75
-rw-r--r--test/CodeGen/ARM/Windows/long-calls.ll4
-rw-r--r--test/CodeGen/ARM/Windows/no-aeabi.ll2
-rw-r--r--test/CodeGen/ARM/Windows/overflow.ll77
-rw-r--r--test/CodeGen/ARM/Windows/tls.ll157
-rw-r--r--test/CodeGen/ARM/align.ll20
-rw-r--r--test/CodeGen/ARM/arm-and-tst-peephole.ll2
-rw-r--r--test/CodeGen/ARM/arm-eabi.ll8
-rw-r--r--test/CodeGen/ARM/arm-interleaved-accesses-extract-user.ll86
-rw-r--r--test/CodeGen/ARM/arm-interleaved-accesses.ll12
-rw-r--r--test/CodeGen/ARM/arm-shrink-wrapping.ll4
-rw-r--r--test/CodeGen/ARM/atomic-64bit.ll186
-rw-r--r--test/CodeGen/ARM/atomic-op.ll111
-rw-r--r--test/CodeGen/ARM/atomic-ops-v8.ll76
-rw-r--r--test/CodeGen/ARM/bfx.ll16
-rw-r--r--test/CodeGen/ARM/build-attributes-encoding.s11
-rw-r--r--test/CodeGen/ARM/build-attributes.ll203
-rw-r--r--test/CodeGen/ARM/byval_load_align.ll2
-rw-r--r--test/CodeGen/ARM/call-tc.ll18
-rw-r--r--test/CodeGen/ARM/call.ll2
-rw-r--r--test/CodeGen/ARM/carry.ll7
-rw-r--r--test/CodeGen/ARM/cdp.ll13
-rw-r--r--test/CodeGen/ARM/cdp2.ll13
-rw-r--r--test/CodeGen/ARM/cmpxchg-O0.ll113
-rw-r--r--test/CodeGen/ARM/cmpxchg-idioms.ll65
-rw-r--r--test/CodeGen/ARM/cmpxchg-weak.ll6
-rw-r--r--test/CodeGen/ARM/coalesce-dbgvalue.ll5
-rw-r--r--test/CodeGen/ARM/code-placement.ll6
-rw-r--r--test/CodeGen/ARM/crash-greedy.ll2
-rw-r--r--test/CodeGen/ARM/cxx-tlscc.ll109
-rw-r--r--test/CodeGen/ARM/dagcombine-anyexttozeroext.ll38
-rw-r--r--test/CodeGen/ARM/darwin-tls.ll17
-rw-r--r--test/CodeGen/ARM/debug-frame-vararg.ll5
-rw-r--r--test/CodeGen/ARM/debug-frame.ll5
-rw-r--r--test/CodeGen/ARM/debug-info-arg.ll5
-rw-r--r--test/CodeGen/ARM/debug-info-blocks.ll5
-rw-r--r--test/CodeGen/ARM/debug-info-branch-folding.ll9
-rw-r--r--test/CodeGen/ARM/debug-info-d16-reg.ll9
-rw-r--r--test/CodeGen/ARM/debug-info-no-frame.ll4
-rw-r--r--test/CodeGen/ARM/debug-info-qreg.ll9
-rw-r--r--test/CodeGen/ARM/debug-info-s16-reg.ll9
-rw-r--r--test/CodeGen/ARM/debug-info-sreg2.ll5
-rw-r--r--test/CodeGen/ARM/debug-segmented-stacks.ll5
-rw-r--r--test/CodeGen/ARM/debugtrap.ll2
-rw-r--r--test/CodeGen/ARM/default-float-abi.ll3
-rw-r--r--test/CodeGen/ARM/default-reloc.ll5
-rw-r--r--test/CodeGen/ARM/divmod-eabi.ll186
-rw-r--r--test/CodeGen/ARM/eh-resume-darwin.ll7
-rw-r--r--test/CodeGen/ARM/ehabi-handlerdata-nounwind.ll4
-rw-r--r--test/CodeGen/ARM/ehabi-handlerdata.ll4
-rw-r--r--test/CodeGen/ARM/ehabi.ll16
-rw-r--r--test/CodeGen/ARM/emutls.ll74
-rw-r--r--test/CodeGen/ARM/emutls_generic.ll18
-rw-r--r--test/CodeGen/ARM/fast-isel-call.ll26
-rw-r--r--test/CodeGen/ARM/fast-isel-deadcode.ll2
-rw-r--r--test/CodeGen/ARM/fast-isel-intrinsic.ll97
-rw-r--r--test/CodeGen/ARM/fast-isel-pie.ll19
-rw-r--r--test/CodeGen/ARM/fast-isel.ll14
-rw-r--r--test/CodeGen/ARM/fast-tail-call.ll1
-rw-r--r--test/CodeGen/ARM/fp16-promote.ll74
-rw-r--r--test/CodeGen/ARM/fp16-v3.ll26
-rw-r--r--test/CodeGen/ARM/fp16.ll15
-rw-r--r--test/CodeGen/ARM/globals.ll12
-rw-r--r--test/CodeGen/ARM/half.ll8
-rw-r--r--test/CodeGen/ARM/hello.ll2
-rw-r--r--test/CodeGen/ARM/ifcvt-iter-indbr.ll2
-rw-r--r--test/CodeGen/ARM/inlineasm-X-allocation.ll21
-rw-r--r--test/CodeGen/ARM/inlineasm-X-constraint.ll157
-rw-r--r--test/CodeGen/ARM/inlineasm-ldr-pseudo.ll4
-rw-r--r--test/CodeGen/ARM/inlineasm3.ll25
-rw-r--r--test/CodeGen/ARM/interrupt-attr.ll8
-rw-r--r--test/CodeGen/ARM/interval-update-remat.ll162
-rw-r--r--test/CodeGen/ARM/intrinsics-coprocessor.ll79
-rw-r--r--test/CodeGen/ARM/intrinsics.ll39
-rw-r--r--test/CodeGen/ARM/invalidated-save-point.ll27
-rw-r--r--test/CodeGen/ARM/ldc2l.ll11
-rw-r--r--test/CodeGen/ARM/ldm-base-writeback.ll21
-rw-r--r--test/CodeGen/ARM/ldr_frame.ll11
-rw-r--r--test/CodeGen/ARM/ldrd.ll52
-rw-r--r--test/CodeGen/ARM/ldstrex-m.ll2
-rw-r--r--test/CodeGen/ARM/legalize-unaligned-load.ll2
-rw-r--r--test/CodeGen/ARM/litpool-licm.ll46
-rw-r--r--test/CodeGen/ARM/local-call.ll20
-rw-r--r--test/CodeGen/ARM/longMAC.ll29
-rw-r--r--test/CodeGen/ARM/lsr-code-insertion.ll4
-rw-r--r--test/CodeGen/ARM/macho-frame-offset.ll12
-rw-r--r--test/CodeGen/ARM/memcpy-no-inline.ll33
-rw-r--r--test/CodeGen/ARM/memfunc.ll29
-rw-r--r--test/CodeGen/ARM/minsize-call-cse.ll28
-rw-r--r--test/CodeGen/ARM/movt.ll6
-rw-r--r--test/CodeGen/ARM/msr-it-block.ll55
-rw-r--r--test/CodeGen/ARM/none-macho.ll10
-rw-r--r--test/CodeGen/ARM/pic.ll4
-rw-r--r--test/CodeGen/ARM/pie.ll18
-rw-r--r--test/CodeGen/ARM/plt-relative-reloc.ll16
-rw-r--r--test/CodeGen/ARM/popcnt.ll16
-rw-r--r--test/CodeGen/ARM/pr26669.ll31
-rw-r--r--test/CodeGen/ARM/preferred-align.ll8
-rw-r--r--test/CodeGen/ARM/rem_crash.ll257
-rw-r--r--test/CodeGen/ARM/returned-ext.ll32
-rw-r--r--test/CodeGen/ARM/sincos.ll18
-rw-r--r--test/CodeGen/ARM/sjlj-prepare-critical-edge.ll4
-rw-r--r--test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll6
-rw-r--r--test/CodeGen/ARM/smul.ll111
-rw-r--r--test/CodeGen/ARM/smulw.ll26
-rw-r--r--test/CodeGen/ARM/special-reg-v8m-base.ll142
-rw-r--r--test/CodeGen/ARM/special-reg-v8m-main.ll214
-rw-r--r--test/CodeGen/ARM/ssat.ll215
-rw-r--r--test/CodeGen/ARM/static-addr-hoisting.ll22
-rw-r--r--test/CodeGen/ARM/stc2.ll11
-rw-r--r--test/CodeGen/ARM/struct_byval.ll31
-rw-r--r--test/CodeGen/ARM/swift-ios.ll68
-rw-r--r--test/CodeGen/ARM/swift-return.ll133
-rw-r--r--test/CodeGen/ARM/swift-vldm.ll1
-rw-r--r--test/CodeGen/ARM/swifterror.ll381
-rw-r--r--test/CodeGen/ARM/swiftself.ll65
-rw-r--r--test/CodeGen/ARM/t2-shrink-ldrpost.ll52
-rw-r--r--test/CodeGen/ARM/tail-call-builtin.ll37
-rw-r--r--test/CodeGen/ARM/tail-call-weak.ll7
-rw-r--r--test/CodeGen/ARM/this-return.ll10
-rw-r--r--test/CodeGen/ARM/thread_pointer.ll4
-rw-r--r--test/CodeGen/ARM/thumb-alignment.ll6
-rw-r--r--test/CodeGen/ARM/thumb-stub.ll10
-rw-r--r--test/CodeGen/ARM/thumb1-ldst-opt.ll2
-rw-r--r--test/CodeGen/ARM/thumb1-varalloc.ll12
-rw-r--r--test/CodeGen/ARM/thumb2-size-opt.ll16
-rw-r--r--test/CodeGen/ARM/tls-models.ll4
-rw-r--r--test/CodeGen/ARM/tls3.ll2
-rw-r--r--test/CodeGen/ARM/trap.ll67
-rw-r--r--test/CodeGen/ARM/truncstore-dag-combine.ll10
-rw-r--r--test/CodeGen/ARM/twoaddrinstr.ll1
-rw-r--r--test/CodeGen/ARM/urem-opt-size.ll45
-rw-r--r--test/CodeGen/ARM/v7k-libcalls.ll9
-rw-r--r--test/CodeGen/ARM/v7k-sincos.ll2
-rw-r--r--test/CodeGen/ARM/vcnt.ll78
-rw-r--r--test/CodeGen/ARM/vcvt_combine.ll8
-rw-r--r--test/CodeGen/ARM/vdiv_combine.ll8
-rw-r--r--test/CodeGen/ARM/vfp-libcalls.ll2
-rw-r--r--test/CodeGen/ARM/vfp-regs-dwarf.ll5
-rw-r--r--test/CodeGen/ARM/vminmax.ll17
-rw-r--r--test/CodeGen/ARM/warn-stack.ll2
-rw-r--r--test/CodeGen/ARM/wide-compares.ll52
-rw-r--r--test/CodeGen/ARM/widen-vmovs.ll2
-rw-r--r--test/CodeGen/ARM/zero-cycle-zero.ll2
165 files changed, 5169 insertions, 884 deletions
diff --git a/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll b/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
index d402c16ccacb..0a9fd8955746 100644
--- a/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
+++ b/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
@@ -1,8 +1,10 @@
; RUN: llc < %s -mtriple=arm-apple-darwin9 -march=arm | FileCheck %s
-; CHECK: .cfi_lsda 16, [[LABEL:.*]]
-; CHECK: .long [[LABEL]]-
-; CHECK: [[LABEL]]:
+; CHECK: ldr r0, [[CPI_PERSONALITY:[A-Za-z0-9_]+]]
+; CHECK: ldr r0, [[CPI_LSDA:[A-Za-z0-9_]+]]
+; CHECK: [[CPI_LSDA]]:
+; CHECK: .long [[LSDA_LABEL:[A-Za-z0-9_]+]]-
+; CHECK: [[LSDA_LABEL]]:
; CHECK: .byte 255 @ @LPStart Encoding = omit
%struct.A = type { i32* }
diff --git a/test/CodeGen/ARM/2009-10-16-Scope.ll b/test/CodeGen/ARM/2009-10-16-Scope.ll
index 613694f091d1..3e687322de4f 100644
--- a/test/CodeGen/ARM/2009-10-16-Scope.ll
+++ b/test/CodeGen/ARM/2009-10-16-Scope.ll
@@ -22,10 +22,11 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
declare i32 @foo(i32) ssp
+!llvm.dbg.cu = !{!0}
!0 = !DILocation(line: 5, column: 2, scope: !1)
!1 = distinct !DILexicalBlock(line: 1, column: 1, file: null, scope: !2)
-!2 = distinct !DISubprogram(name: "bar", linkageName: "bar", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scope: !3)
-!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 1.1", isOptimized: true, emissionKind: 0, file: !8, retainedTypes: !9)
+!2 = distinct !DISubprogram(name: "bar", linkageName: "bar", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, scope: !3)
+!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 1.1", isOptimized: true, emissionKind: FullDebug, file: !8, retainedTypes: !9)
!4 = !DILocalVariable(name: "count_", line: 5, scope: !5, file: !3, type: !6)
!5 = distinct !DILexicalBlock(line: 1, column: 1, file: null, scope: !1)
!6 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/test/CodeGen/ARM/2010-04-15-ScavengerDebugValue.ll b/test/CodeGen/ARM/2010-04-15-ScavengerDebugValue.ll
index 1341830b4a4b..089cff82bc5d 100644
--- a/test/CodeGen/ARM/2010-04-15-ScavengerDebugValue.ll
+++ b/test/CodeGen/ARM/2010-04-15-ScavengerDebugValue.ll
@@ -15,10 +15,10 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!3}
!llvm.module.flags = !{!15}
!0 = !DILocalVariable(name: "b", line: 93, arg: 2, scope: !1, file: !2, type: !6)
-!1 = distinct !DISubprogram(name: "__addvsi3", linkageName: "__addvsi3", line: 94, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !12, scope: null, type: !4)
+!1 = distinct !DISubprogram(name: "__addvsi3", linkageName: "__addvsi3", line: 94, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !12, scope: null, type: !4)
!2 = !DIFile(filename: "libgcc2.c", directory: "/Users/bwilson/local/nightly/test-2010-04-14/build/llvmgcc.roots/llvmgcc~obj/src/gcc")
!12 = !DIFile(filename: "libgcc2.c", directory: "/Users/bwilson/local/nightly/test-2010-04-14/build/llvmgcc.roots/llvmgcc~obj/src/gcc")
-!3 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 00)", isOptimized: true, emissionKind: 0, file: !12, enums: !13, retainedTypes: !13, subprograms: !14)
+!3 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 00)", isOptimized: true, emissionKind: FullDebug, file: !12, enums: !13, retainedTypes: !13)
!4 = !DISubroutineType(types: !5)
!5 = !{!6, !6, !6}
!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "SItype", line: 152, file: !12, baseType: !8)
@@ -28,5 +28,4 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!10 = distinct !DILexicalBlock(line: 94, column: 0, file: !12, scope: !1)
!11 = !DILocation(line: 100, scope: !10)
!13 = !{}
-!14 = !{!1}
!15 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/test/CodeGen/ARM/2010-06-25-Thumb2ITInvalidIterator.ll b/test/CodeGen/ARM/2010-06-25-Thumb2ITInvalidIterator.ll
index 38b352c473b1..5ae1b6626f1a 100644
--- a/test/CodeGen/ARM/2010-06-25-Thumb2ITInvalidIterator.ll
+++ b/test/CodeGen/ARM/2010-06-25-Thumb2ITInvalidIterator.ll
@@ -44,13 +44,12 @@ declare i32 @x1() optsize
declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
-!llvm.dbg.lv.fn = !{!0, !8, !10, !12}
-!llvm.dbg.gv = !{!14}
+!llvm.dbg.cu = !{!3}
!0 = !DILocalVariable(name: "buf", line: 4, arg: 1, scope: !1, file: !2, type: !6)
-!1 = distinct !DISubprogram(name: "x0", linkageName: "x0", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !26, scope: null, type: !4)
+!1 = distinct !DISubprogram(name: "x0", linkageName: "x0", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !26, scope: null, type: !4)
!2 = !DIFile(filename: "t.c", directory: "/private/tmp")
-!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 2.0", isOptimized: true, file: !26)
+!3 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang 2.0", isOptimized: true, file: !26, globals: !{!14})
!4 = !DISubroutineType(types: !5)
!5 = !{null}
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !26, scope: !2, baseType: !7)
diff --git a/test/CodeGen/ARM/2010-08-04-StackVariable.ll b/test/CodeGen/ARM/2010-08-04-StackVariable.ll
index 14ddb59b5387..a90ea137cb7c 100644
--- a/test/CodeGen/ARM/2010-08-04-StackVariable.ll
+++ b/test/CodeGen/ARM/2010-08-04-StackVariable.ll
@@ -1,6 +1,9 @@
; RUN: llc -O0 -mtriple=arm-apple-darwin < %s | grep DW_OP_breg
; Use DW_OP_breg in variable's location expression if the variable is in a stack slot.
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64"
+target triple = "arm-apple-darwin"
+
%struct.SVal = type { i8*, i32 }
define i32 @_Z3fooi4SVal(i32 %i, %struct.SVal* noalias %location) nounwind ssp !dbg !17 {
@@ -78,9 +81,9 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!49}
!0 = !DISubprogram(name: "SVal", line: 11, isLocal: false, isDefinition: false, virtualIndex: 6, isOptimized: false, file: !48, scope: !1, type: !14)
-!1 = !DICompositeType(tag: DW_TAG_structure_type, name: "SVal", line: 1, size: 128, align: 64, file: !48, elements: !4)
+!1 = !DICompositeType(tag: DW_TAG_structure_type, name: "SVal", line: 1, size: 64, align: 64, file: !48, elements: !4)
!2 = !DIFile(filename: "small.cc", directory: "/Users/manav/R8248330")
-!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: 1, file: !48, enums: !47, retainedTypes: !47, subprograms: !46, globals: !47, imports: !47)
+!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", isOptimized: false, emissionKind: FullDebug, file: !48, enums: !47, retainedTypes: !47, globals: !47, imports: !47)
!4 = !{!5, !7, !0, !9}
!5 = !DIDerivedType(tag: DW_TAG_member, name: "Data", line: 7, size: 64, align: 64, file: !48, scope: !1, baseType: !6)
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !48, baseType: null)
@@ -93,24 +96,24 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!14 = !DISubroutineType(types: !15)
!15 = !{null, !12}
-!16 = distinct !DISubprogram(name: "SVal", linkageName: "_ZN4SValC1Ev", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !48, scope: !1, type: !14)
-!17 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi4SVal", line: 16, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !48, scope: !2, type: !18)
+!16 = distinct !DISubprogram(name: "SVal", linkageName: "_ZN4SValC1Ev", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !48, scope: !1, type: !14)
+!17 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi4SVal", line: 16, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !48, scope: !2, type: !18)
!18 = !DISubroutineType(types: !19)
!19 = !{!13, !13, !1}
-!20 = distinct !DISubprogram(name: "main", linkageName: "main", line: 23, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, file: !48, scope: !2, type: !21)
+!20 = distinct !DISubprogram(name: "main", linkageName: "main", line: 23, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !3, file: !48, scope: !2, type: !21)
!21 = !DISubroutineType(types: !22)
!22 = !{!13}
!23 = !DILocalVariable(name: "i", line: 16, arg: 1, scope: !17, file: !2, type: !13)
!24 = !DILocation(line: 16, scope: !17)
!25 = !DILocalVariable(name: "location", line: 16, arg: 2, scope: !17, file: !2, type: !26)
-!26 = !DIDerivedType(tag: DW_TAG_reference_type, name: "SVal", size: 64, align: 64, file: !48, scope: !2, baseType: !1)
+!26 = !DIDerivedType(tag: DW_TAG_reference_type, name: "SVal", size: 32, align: 32, file: !48, scope: !2, baseType: !1)
!27 = !DILocation(line: 17, scope: !28)
!28 = distinct !DILexicalBlock(line: 16, column: 0, file: !2, scope: !17)
!29 = !DILocation(line: 18, scope: !28)
!30 = !DILocation(line: 20, scope: !28)
!31 = !DILocalVariable(name: "this", line: 11, arg: 1, scope: !16, file: !2, type: !32)
-!32 = !DIDerivedType(tag: DW_TAG_const_type, size: 64, align: 64, flags: DIFlagArtificial, file: !48, scope: !2, baseType: !33)
-!33 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, file: !48, scope: !2, baseType: !1)
+!32 = !DIDerivedType(tag: DW_TAG_const_type, flags: DIFlagArtificial, file: !48, scope: !2, baseType: !33)
+!33 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !48, scope: !2, baseType: !1)
!34 = !DILocation(line: 11, scope: !16)
!35 = !DILocation(line: 11, scope: !36)
!36 = distinct !DILexicalBlock(line: 11, column: 0, file: !48, scope: !37)
@@ -123,7 +126,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!43 = !DILocation(line: 26, scope: !39)
!44 = !DILocalVariable(name: "k", line: 26, scope: !39, file: !2, type: !13)
!45 = !DILocation(line: 27, scope: !39)
-!46 = !{!16, !17, !20}
!47 = !{}
!48 = !DIFile(filename: "small.cc", directory: "/Users/manav/R8248330")
!49 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/test/CodeGen/ARM/2010-11-29-PrologueBug.ll b/test/CodeGen/ARM/2010-11-29-PrologueBug.ll
index 4179d8c99d6a..15e17b4fd0f1 100644
--- a/test/CodeGen/ARM/2010-11-29-PrologueBug.ll
+++ b/test/CodeGen/ARM/2010-11-29-PrologueBug.ll
@@ -1,24 +1,17 @@
-; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
-; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB2
+; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s
; rdar://8690640
define i32* @t(i32* %x) nounwind {
entry:
-; ARM-LABEL: t:
-; ARM: push
-; ARM: mov r7, sp
-; ARM: bl _foo
-; ARM: bl _foo
-; ARM: bl _foo
-; ARM: pop {r7, pc}
+; CHECK-LABEL: t:
+; CHECK: push
+; CHECK: mov r7, sp
+; CHECK: bl _foo
+; CHECK: bl _foo
+; CHECK: bl _foo
+; CHECK: pop {r7, pc}
-; THUMB2-LABEL: t:
-; THUMB2: push
-; THUMB2: mov r7, sp
-; THUMB2: blx _foo
-; THUMB2: blx _foo
-; THUMB2: blx _foo
-; THUMB2: pop
%0 = tail call i32* @foo(i32* %x) nounwind
%1 = tail call i32* @foo(i32* %0) nounwind
%2 = tail call i32* @foo(i32* %1) nounwind
diff --git a/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll b/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll
index d5eed8b6a2c4..8c6cf00cc3a0 100644
--- a/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll
+++ b/test/CodeGen/ARM/2011-01-19-MergedGlobalDbg.ll
@@ -78,16 +78,16 @@ entry:
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!49}
-!0 = distinct !DISubprogram(name: "get1", linkageName: "get1", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 4, file: !47, scope: !1, type: !3, variables: !42)
+!0 = distinct !DISubprogram(name: "get1", linkageName: "get1", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 4, file: !47, scope: !1, type: !3, variables: !42)
!1 = !DIFile(filename: "foo.c", directory: "/tmp/")
-!2 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2369.8)", isOptimized: true, emissionKind: 0, file: !47, enums: !48, retainedTypes: !48, subprograms: !40, globals: !41, imports: !48)
+!2 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2369.8)", isOptimized: true, emissionKind: FullDebug, file: !47, enums: !48, retainedTypes: !48, globals: !41, imports: !48)
!3 = !DISubroutineType(types: !4)
!4 = !{!5, !5}
!5 = !DIBasicType(tag: DW_TAG_base_type, name: "_Bool", size: 8, align: 8, encoding: DW_ATE_boolean)
-!6 = distinct !DISubprogram(name: "get2", linkageName: "get2", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 7, file: !47, scope: !1, type: !3, variables: !43)
-!7 = distinct !DISubprogram(name: "get3", linkageName: "get3", line: 10, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 10, file: !47, scope: !1, type: !3, variables: !44)
-!8 = distinct !DISubprogram(name: "get4", linkageName: "get4", line: 13, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 13, file: !47, scope: !1, type: !3, variables: !45)
-!9 = distinct !DISubprogram(name: "get5", linkageName: "get5", line: 16, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 16, file: !47, scope: !1, type: !3, variables: !46)
+!6 = distinct !DISubprogram(name: "get2", linkageName: "get2", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 7, file: !47, scope: !1, type: !3, variables: !43)
+!7 = distinct !DISubprogram(name: "get3", linkageName: "get3", line: 10, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 10, file: !47, scope: !1, type: !3, variables: !44)
+!8 = distinct !DISubprogram(name: "get4", linkageName: "get4", line: 13, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 13, file: !47, scope: !1, type: !3, variables: !45)
+!9 = distinct !DISubprogram(name: "get5", linkageName: "get5", line: 16, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 16, file: !47, scope: !1, type: !3, variables: !46)
!10 = !DILocalVariable(name: "a", line: 4, arg: 1, scope: !0, file: !1, type: !5)
!11 = !DILocalVariable(name: "b", line: 4, scope: !12, file: !1, type: !5)
!12 = distinct !DILexicalBlock(line: 4, column: 0, file: !47, scope: !0)
@@ -118,7 +118,6 @@ entry:
!37 = !DILocation(line: 13, scope: !26)
!38 = !DILocation(line: 16, scope: !9)
!39 = !DILocation(line: 16, scope: !29)
-!40 = !{!0, !6, !7, !8, !9}
!41 = !{!13, !14, !15, !16, !17}
!42 = !{!10, !11}
!43 = !{!18, !19}
diff --git a/test/CodeGen/ARM/2011-04-15-AndVFlagPeepholeBug.ll b/test/CodeGen/ARM/2011-04-15-AndVFlagPeepholeBug.ll
index f17884e0fa41..91adba41b1ac 100644
--- a/test/CodeGen/ARM/2011-04-15-AndVFlagPeepholeBug.ll
+++ b/test/CodeGen/ARM/2011-04-15-AndVFlagPeepholeBug.ll
@@ -3,7 +3,7 @@
; CHECK: _f
; CHECK-NOT: ands
; CHECK: cmp
-; CHECK: blxle _g
+; CHECK: blle _g
define i32 @f(i32 %a, i32 %b) nounwind ssp {
entry:
diff --git a/test/CodeGen/ARM/2011-04-15-RegisterCmpPeephole.ll b/test/CodeGen/ARM/2011-04-15-RegisterCmpPeephole.ll
index 864e2917b7bb..852038147b26 100644
--- a/test/CodeGen/ARM/2011-04-15-RegisterCmpPeephole.ll
+++ b/test/CodeGen/ARM/2011-04-15-RegisterCmpPeephole.ll
@@ -3,7 +3,7 @@
; CHECK: _f
; CHECK: adds
; CHECK-NOT: cmp
-; CHECK: blxeq _h
+; CHECK: bleq _h
define i32 @f(i32 %a, i32 %b) nounwind ssp {
entry:
@@ -22,7 +22,7 @@ if.end: ; preds = %if.then, %entry
; CHECK: _g
; CHECK: orrs
; CHECK-NOT: cmp
-; CHECK: blxeq _h
+; CHECK: bleq _h
define i32 @g(i32 %a, i32 %b) nounwind ssp {
entry:
diff --git a/test/CodeGen/ARM/2011-04-26-SchedTweak.ll b/test/CodeGen/ARM/2011-04-26-SchedTweak.ll
index ee6d79c39f2f..3c5579acf6ae 100644
--- a/test/CodeGen/ARM/2011-04-26-SchedTweak.ll
+++ b/test/CodeGen/ARM/2011-04-26-SchedTweak.ll
@@ -38,9 +38,9 @@ bb:
bb1:
; CHECK: %bb1
; CHECK-NOT: umull
-; CHECK: blx _Get
+; CHECK: bl _Get
; CHECK: umull
-; CHECK: blx _foo
+; CHECK: bl _foo
%tmp5 = load i32, i32* %block_size, align 4
%tmp6 = load i32, i32* %block_count, align 4
%tmp7 = call %struct.FF* @Get() nounwind
diff --git a/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll b/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll
index 12cdd04b7bb7..f4b93ca74fc0 100644
--- a/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll
+++ b/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll
@@ -29,7 +29,7 @@ target triple = "thumbv7-apple-darwin10"
@"\01_fnmatch.initial" = external constant %union.__mbstate_t, align 4
; CHECK: _fnmatch
-; CHECK: blx _fnmatch1
+; CHECK: bl _fnmatch1
define i32 @"\01_fnmatch"(i8* %pattern, i8* %string, i32 %flags) nounwind optsize {
entry:
diff --git a/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll
index 3d82e706862c..4da4fd4c926e 100644
--- a/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll
+++ b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll
@@ -73,16 +73,16 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!49}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", isOptimized: true, emissionKind: 1, file: !47, enums: !48, retainedTypes: !48, subprograms: !40, globals: !41, imports: !48)
-!1 = distinct !DISubprogram(name: "get1", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !47, scope: !2, type: !3, variables: !42)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", isOptimized: true, emissionKind: FullDebug, file: !47, enums: !48, retainedTypes: !48, globals: !41, imports: !48)
+!1 = distinct !DISubprogram(name: "get1", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 5, file: !47, scope: !2, type: !3, variables: !42)
!2 = !DIFile(filename: "ss3.c", directory: "/private/tmp")
!3 = !DISubroutineType(types: !4)
!4 = !{!5}
!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!6 = distinct !DISubprogram(name: "get2", line: 8, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 8, file: !47, scope: !2, type: !3, variables: !43)
-!7 = distinct !DISubprogram(name: "get3", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 11, file: !47, scope: !2, type: !3, variables: !44)
-!8 = distinct !DISubprogram(name: "get4", line: 14, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 14, file: !47, scope: !2, type: !3, variables: !45)
-!9 = distinct !DISubprogram(name: "get5", line: 17, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 17, file: !47, scope: !2, type: !3, variables: !46)
+!6 = distinct !DISubprogram(name: "get2", line: 8, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 8, file: !47, scope: !2, type: !3, variables: !43)
+!7 = distinct !DISubprogram(name: "get3", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 11, file: !47, scope: !2, type: !3, variables: !44)
+!8 = distinct !DISubprogram(name: "get4", line: 14, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 14, file: !47, scope: !2, type: !3, variables: !45)
+!9 = distinct !DISubprogram(name: "get5", line: 17, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 17, file: !47, scope: !2, type: !3, variables: !46)
!10 = !DILocalVariable(name: "a", line: 5, arg: 1, scope: !1, file: !2, type: !5)
!11 = !DILocalVariable(name: "b", line: 5, scope: !12, file: !2, type: !5)
!12 = distinct !DILexicalBlock(line: 5, column: 19, file: !47, scope: !1)
@@ -110,7 +110,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!37 = !DILocation(line: 14, column: 32, scope: !21)
!38 = !DILocation(line: 17, column: 16, scope: !9)
!39 = !DILocation(line: 17, column: 32, scope: !29)
-!40 = !{!1, !6, !7, !8, !9}
!41 = !{!25, !26}
!42 = !{!10, !11}
!43 = !{!13, !14}
diff --git a/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll b/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll
index 9163166177c1..e70f973d6a76 100644
--- a/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll
+++ b/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a9 | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a9 -jump-table-density=40 | FileCheck %s
; Test that ldmia_ret preserves implicit operands for return values.
;
; This CFG is reduced from a benchmark miscompile. With current
diff --git a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
index b47247c5454f..a928543d7cf2 100644
--- a/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
+++ b/test/CodeGen/ARM/2012-09-25-InlineAsmScalarToVectorConv2.ll
@@ -2,9 +2,10 @@
; Check for error message:
; CHECK: scalar-to-vector conversion failed, possible invalid constraint for vector type
+; 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
+ tail call void asm sideeffect "vst1.s32 { ${1:q}, ${2:q} }, [$0]", "r,{q0},{q1}"(i32* %corr, <2 x i64>* undef, i32 %order) nounwind, !srcloc !0
ret void
}
diff --git a/test/CodeGen/ARM/2016-05-01-RegScavengerAssert.ll b/test/CodeGen/ARM/2016-05-01-RegScavengerAssert.ll
new file mode 100644
index 000000000000..15e0dad18232
--- /dev/null
+++ b/test/CodeGen/ARM/2016-05-01-RegScavengerAssert.ll
@@ -0,0 +1,192 @@
+; RUN: llc < %s
+; This test has around 4000 bytes of local variables and it also stresses register allocation
+; to force a register scavenging. It tests if the stack is treated as "BigStack" and thus
+; spill slots are reserved. If not, reg scavenger will assert.
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n8:16:32-S64"
+target triple = "thumbv7--linux-android"
+
+%struct.r = type { i32 (...)**, [10 x [9 x float]], [10 x [9 x float]], [101 x [9 x float]], [101 x [9 x float]], i32, i32, i32, i32, i32, [8 x [2 x i32]], [432 x float], [432 x i32], [10 x i8*], [10 x i8*], [10 x i32], [10 x i32], [10 x i32], [10 x i32], [10 x i32], [10 x i32], i32, i32, i32, i32, float, float, i32, i32, [9 x float], float*, float }
+
+define void @foo(%struct.r* %this, float* %srcR, float* %srcC, float* %tempPntsX, float* %tY, float* %ms, float* %sX, float* %sY, i32* dereferenceable(4) %num, float* %tm, i32 %SR, i32 %lev, i8* %tdata, i32 %siW, i32 %pyw, i32 %pyh, i8* %sdata) #0 align 2 {
+entry:
+ %sFV = alloca [49 x float], align 4
+ %tFV = alloca [49 x float], align 4
+ %TIM = alloca [9 x float], align 4
+ %sort_tmp = alloca [432 x float], align 4
+ %msDiffs = alloca [432 x float], align 4
+ %TM.sroa.0.0.copyload = load float, float* %tm, align 4
+ %TM.sroa.8.0.copyload = load float, float* null, align 4
+ %TM.sroa.9.0..sroa_idx813 = getelementptr inbounds float, float* %tm, i32 6
+ %TM.sroa.9.0.copyload = load float, float* %TM.sroa.9.0..sroa_idx813, align 4
+ %TM.sroa.11.0.copyload = load float, float* undef, align 4
+ br i1 undef, label %for.body.lr.ph, label %if.then343
+
+for.body.lr.ph: ; preds = %entry
+ %arrayidx8 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 1, i32 %lev, i32 0
+ %arrayidx12 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 1, i32 %lev, i32 6
+ %arrayidx15 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 1, i32 %lev, i32 4
+ %arrayidx20 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 1, i32 %lev, i32 7
+ %arrayidx24 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 2, i32 %lev, i32 0
+ %arrayidx28 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 2, i32 %lev, i32 6
+ %arrayidx32 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 2, i32 %lev, i32 4
+ %arrayidx36 = getelementptr inbounds %struct.r, %struct.r* %this, i32 0, i32 2, i32 %lev, i32 7
+ %arrayidx84 = getelementptr inbounds [9 x float], [9 x float]* %TIM, i32 0, i32 6
+ %arrayidx92 = getelementptr inbounds [9 x float], [9 x float]* %TIM, i32 0, i32 7
+ %add116 = add nsw i32 %pyh, 15
+ br label %for.body
+
+for.body: ; preds = %for.cond.cleanup40, %for.body.lr.ph
+ %arrayidx.phi = phi float* [ %sX, %for.body.lr.ph ], [ %arrayidx.inc, %for.cond.cleanup40 ]
+ %arrayidx4.phi = phi float* [ %sY, %for.body.lr.ph ], [ %arrayidx4.inc, %for.cond.cleanup40 ]
+ %0 = load float, float* %arrayidx.phi, align 4
+ %1 = load float, float* %arrayidx4.phi, align 4
+ %2 = load float, float* %arrayidx12, align 4
+ %add = fadd fast float 0.000000e+00, %2
+ %3 = load float, float* %arrayidx20, align 4
+ %add21 = fadd fast float 0.000000e+00, %3
+ %mul3.i = fmul fast float %add21, %TM.sroa.8.0.copyload
+ %add.i = fadd fast float 0.000000e+00, %TM.sroa.11.0.copyload
+ %add5.i = fadd fast float %add.i, %mul3.i
+ %conv6.i = fdiv fast float 1.000000e+00, %add5.i
+ %mul8.i = fmul fast float %add, %TM.sroa.0.0.copyload
+ %add11.i = fadd fast float %mul8.i, %TM.sroa.9.0.copyload
+ %add13.i = fadd fast float %add11.i, 0.000000e+00
+ %4 = load float, float* %arrayidx24, align 4
+ %mul14.i = fmul fast float %add13.i, %4
+ %mul25 = fmul fast float %mul14.i, %conv6.i
+ %add29 = fadd fast float %mul25, 0.000000e+00
+ %arrayidx.inc = getelementptr float, float* %arrayidx.phi, i32 1
+ %arrayidx4.inc = getelementptr float, float* %arrayidx4.phi, i32 1
+ %conv64.1 = sitofp i32 undef to float
+ %conv64.6 = sitofp i32 undef to float
+ br label %for.body41
+
+for.cond.cleanup40: ; preds = %for.body41
+ %call = call fast float undef(%struct.r* nonnull %this, float* undef, i32 49)
+ br label %for.body
+
+for.body41: ; preds = %for.cond.cleanup56.for.body41_crit_edge, %for.body
+ %5 = phi float [ 0.000000e+00, %for.body ], [ %.pre, %for.cond.cleanup56.for.body41_crit_edge ]
+ %sFVData.0840 = phi float* [ undef, %for.body ], [ undef, %for.cond.cleanup56.for.body41_crit_edge ]
+ %dx.0838 = phi i32 [ -3, %for.body ], [ undef, %for.cond.cleanup56.for.body41_crit_edge ]
+ %conv42 = sitofp i32 %dx.0838 to float
+ %add43 = fadd fast float %conv42, %add29
+ %conv44 = fptosi float %add43 to i32
+ %conv48 = sitofp i32 %conv44 to float
+ %mul49 = fmul fast float %5, %conv48
+ %add53 = fadd fast float %mul49, 0.000000e+00
+ %conv111 = fptosi float undef to i32
+ %cond = select i1 undef, i32 %conv111, i32 -16
+ %cond.add116 = select i1 undef, i32 %cond, i32 %add116
+ %cmp132 = icmp sgt i32 undef, -16
+ %cond137 = select i1 %cmp132, i32 undef, i32 -16
+ %cond153 = select i1 undef, i32 %cond137, i32 undef
+ %add.ptr = getelementptr inbounds i8, i8* %sdata, i32 %cond153
+ %mul154 = mul nsw i32 %cond.add116, %siW
+ %add.ptr155 = getelementptr inbounds i8, i8* %add.ptr, i32 %mul154
+ %6 = load i8, i8* %add.ptr155, align 1
+ %conv157 = uitofp i8 %6 to float
+ %incdec.ptr = getelementptr inbounds float, float* %sFVData.0840, i32 1
+ store float %conv157, float* %sFVData.0840, align 4
+ %7 = load float, float* %arrayidx15, align 4
+ %mul65.1 = fmul fast float %7, %conv64.1
+ %8 = load float, float* %arrayidx20, align 4
+ %add69.1 = fadd fast float %mul65.1, %8
+ %conv78.1 = fdiv fast float 1.000000e+00, 0.000000e+00
+ %9 = load float, float* undef, align 4
+ %mul80.1 = fmul fast float %9, %add53
+ %10 = load float, float* undef, align 4
+ %mul82.1 = fmul fast float %10, %add69.1
+ %add83.1 = fadd fast float %mul82.1, %mul80.1
+ %11 = load float, float* %arrayidx84, align 4
+ %add85.1 = fadd fast float %add83.1, %11
+ %mul86.1 = fmul fast float %add85.1, %conv78.1
+ %12 = load float, float* %arrayidx92, align 4
+ %add93.1 = fadd fast float 0.000000e+00, %12
+ %mul94.1 = fmul fast float %add93.1, %conv78.1
+ %13 = load float, float* %arrayidx24, align 4
+ %mul98.1 = fmul fast float %mul86.1, %13
+ %14 = load float, float* %arrayidx28, align 4
+ %add102.1 = fadd fast float %mul98.1, %14
+ %15 = load float, float* %arrayidx32, align 4
+ %mul106.1 = fmul fast float %mul94.1, %15
+ %16 = load float, float* %arrayidx36, align 4
+ %add110.1 = fadd fast float %mul106.1, %16
+ %conv111.1 = fptosi float %add102.1 to i32
+ %conv112.1 = fptosi float %add110.1 to i32
+ %cond.1 = select i1 undef, i32 %conv111.1, i32 -16
+ %cond.add116.1 = select i1 undef, i32 %cond.1, i32 %add116
+ %cond137.1 = select i1 undef, i32 %conv112.1, i32 -16
+ %cond153.1 = select i1 undef, i32 %cond137.1, i32 undef
+ %add.ptr.1 = getelementptr inbounds i8, i8* %sdata, i32 %cond153.1
+ %mul154.1 = mul nsw i32 %cond.add116.1, %siW
+ %add.ptr155.1 = getelementptr inbounds i8, i8* %add.ptr.1, i32 %mul154.1
+ %17 = load i8, i8* %add.ptr155.1, align 1
+ %conv157.1 = uitofp i8 %17 to float
+ %incdec.ptr.1 = getelementptr inbounds float, float* %sFVData.0840, i32 2
+ store float %conv157.1, float* %incdec.ptr, align 4
+ %conv112.2 = fptosi float undef to i32
+ %cond137.2 = select i1 undef, i32 %conv112.2, i32 -16
+ %cond153.2 = select i1 undef, i32 %cond137.2, i32 undef
+ %add.ptr.2 = getelementptr inbounds i8, i8* %sdata, i32 %cond153.2
+ %add.ptr155.2 = getelementptr inbounds i8, i8* %add.ptr.2, i32 0
+ %18 = load i8, i8* %add.ptr155.2, align 1
+ %conv157.2 = uitofp i8 %18 to float
+ %incdec.ptr.2 = getelementptr inbounds float, float* %sFVData.0840, i32 3
+ store float %conv157.2, float* %incdec.ptr.1, align 4
+ %cmp132.3 = icmp sgt i32 undef, -16
+ %cond137.3 = select i1 %cmp132.3, i32 undef, i32 -16
+ %cond153.3 = select i1 undef, i32 %cond137.3, i32 undef
+ %add.ptr.3 = getelementptr inbounds i8, i8* %sdata, i32 %cond153.3
+ %add.ptr155.3 = getelementptr inbounds i8, i8* %add.ptr.3, i32 0
+ %19 = load i8, i8* %add.ptr155.3, align 1
+ %conv157.3 = uitofp i8 %19 to float
+ store float %conv157.3, float* %incdec.ptr.2, align 4
+ %incdec.ptr.5 = getelementptr inbounds float, float* %sFVData.0840, i32 6
+ %20 = load float, float* %arrayidx15, align 4
+ %mul65.6 = fmul fast float %20, %conv64.6
+ %21 = load float, float* %arrayidx20, align 4
+ %add69.6 = fadd fast float %mul65.6, %21
+ %conv78.6 = fdiv fast float 1.000000e+00, 0.000000e+00
+ %22 = load float, float* undef, align 4
+ %mul82.6 = fmul fast float %22, %add69.6
+ %add83.6 = fadd fast float %mul82.6, 0.000000e+00
+ %23 = load float, float* %arrayidx84, align 4
+ %add85.6 = fadd fast float %add83.6, %23
+ %mul86.6 = fmul fast float %add85.6, %conv78.6
+ %24 = load float, float* %arrayidx24, align 4
+ %mul98.6 = fmul fast float %mul86.6, %24
+ %25 = load float, float* %arrayidx28, align 4
+ %add102.6 = fadd fast float %mul98.6, %25
+ %conv111.6 = fptosi float %add102.6 to i32
+ %conv112.6 = fptosi float undef to i32
+ %cond.6 = select i1 undef, i32 %conv111.6, i32 -16
+ %cond.add116.6 = select i1 undef, i32 %cond.6, i32 %add116
+ %cmp132.6 = icmp sgt i32 %conv112.6, -16
+ %cond137.6 = select i1 %cmp132.6, i32 %conv112.6, i32 -16
+ %cond153.6 = select i1 undef, i32 %cond137.6, i32 undef
+ %add.ptr.6 = getelementptr inbounds i8, i8* %sdata, i32 %cond153.6
+ %mul154.6 = mul nsw i32 %cond.add116.6, %siW
+ %add.ptr155.6 = getelementptr inbounds i8, i8* %add.ptr.6, i32 %mul154.6
+ %26 = load i8, i8* %add.ptr155.6, align 1
+ %conv157.6 = uitofp i8 %26 to float
+ store float %conv157.6, float* %incdec.ptr.5, align 4
+ %exitcond874 = icmp eq i32 %dx.0838, 3
+ br i1 %exitcond874, label %for.cond.cleanup40, label %for.cond.cleanup56.for.body41_crit_edge
+
+for.cond.cleanup56.for.body41_crit_edge: ; preds = %for.body41
+ %.pre = load float, float* %arrayidx8, align 4
+ br label %for.body41
+
+if.then343: ; preds = %entry
+ ret void
+}
+
+attributes #0 = { sspstrong uwtable "no-frame-pointer-elim"="false" "target-cpu"="cortex-a7" }
+
+!1 = !{!2, !2, i64 0}
+!2 = !{!"float", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}
+!5 = !{!3, !3, i64 0}
diff --git a/test/CodeGen/ARM/ARMLoadStoreDBG.mir b/test/CodeGen/ARM/ARMLoadStoreDBG.mir
new file mode 100644
index 000000000000..b4f19ecc5610
--- /dev/null
+++ b/test/CodeGen/ARM/ARMLoadStoreDBG.mir
@@ -0,0 +1,164 @@
+# RUN: llc -mtriple thumbv7 -verify-machineinstrs -run-pass arm-ldst-opt %s -o - | FileCheck %s
+--- |
+ ; ModuleID = '/Volumes/Data/llvm/test/CodeGen/ARM/sched-it-debug-nodes.ll'
+ target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+ target triple = "thumbv7"
+
+ %struct.s = type opaque
+
+ ; Function Attrs: nounwind
+ define arm_aapcscc i32 @f(%struct.s* %s, i32 %u, i8* %b, i32 %n) #0 !dbg !4 {
+ entry:
+ tail call void @llvm.dbg.value(metadata %struct.s* %s, i64 0, metadata !18, metadata !27), !dbg !28
+ tail call void @llvm.dbg.value(metadata i32 %u, i64 0, metadata !19, metadata !27), !dbg !28
+ tail call void @llvm.dbg.value(metadata i8* %b, i64 0, metadata !20, metadata !27), !dbg !28
+ tail call void @llvm.dbg.value(metadata i32 %n, i64 0, metadata !21, metadata !27), !dbg !28
+ %cmp = icmp ult i32 %n, 4, !dbg !29
+ br i1 %cmp, label %return, label %if.end, !dbg !31
+
+ if.end: ; preds = %entry
+ tail call arm_aapcscc void @g(%struct.s* %s, i8* %b, i32 %n) #3, !dbg !32
+ br label %return, !dbg !33
+
+ return: ; preds = %if.end, %entry
+ %retval.0 = phi i32 [ 0, %if.end ], [ -1, %entry ]
+ ret i32 %retval.0, !dbg !34
+ }
+
+ declare arm_aapcscc void @g(%struct.s*, i8*, i32) #1
+
+ ; Function Attrs: nounwind readnone
+ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
+
+ attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+ attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+ attributes #2 = { nounwind readnone }
+ attributes #3 = { nounwind }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!22, !23, !24, !25}
+ !llvm.ident = !{!26}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (llvm/trunk 237059)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
+ !1 = !DIFile(filename: "<stdin>", directory: "/Users/compnerd/Source/llvm")
+ !2 = !{}
+ !4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 9, type: !5, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !17)
+ !5 = !DISubroutineType(types: !6)
+ !6 = !{!7, !8, !11, !12, !16}
+ !7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+ !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 32, align: 32)
+ !9 = !DIDerivedType(tag: DW_TAG_typedef, name: "s", file: !1, line: 5, baseType: !10)
+ !10 = !DICompositeType(tag: DW_TAG_structure_type, name: "s", file: !1, line: 5, flags: DIFlagFwdDecl)
+ !11 = !DIBasicType(name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
+ !12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 32, align: 32)
+ !13 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !14)
+ !14 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint8_t", file: !1, line: 2, baseType: !15)
+ !15 = !DIBasicType(name: "unsigned char", size: 8, align: 8, encoding: DW_ATE_unsigned_char)
+ !16 = !DIDerivedType(tag: DW_TAG_typedef, name: "size_t", file: !1, line: 3, baseType: !11)
+ !17 = !{!18, !19, !20, !21}
+ !18 = !DILocalVariable(name: "s", arg: 1, scope: !4, file: !1, line: 9, type: !8)
+ !19 = !DILocalVariable(name: "u", arg: 2, scope: !4, file: !1, line: 9, type: !11)
+ !20 = !DILocalVariable(name: "b", arg: 3, scope: !4, file: !1, line: 9, type: !12)
+ !21 = !DILocalVariable(name: "n", arg: 4, scope: !4, file: !1, line: 9, type: !16)
+ !22 = !{i32 2, !"Dwarf Version", i32 4}
+ !23 = !{i32 2, !"Debug Info Version", i32 3}
+ !24 = !{i32 1, !"wchar_size", i32 4}
+ !25 = !{i32 1, !"min_enum_size", i32 4}
+ !26 = !{!"clang version 3.7.0 (llvm/trunk 237059)"}
+ !27 = !DIExpression()
+ !28 = !DILocation(line: 9, scope: !4)
+ !29 = !DILocation(line: 10, scope: !30)
+ !30 = distinct !DILexicalBlock(scope: !4, file: !1, line: 10)
+ !31 = !DILocation(line: 10, scope: !4)
+ !32 = !DILocation(line: 13, scope: !4)
+ !33 = !DILocation(line: 14, scope: !4)
+ !34 = !DILocation(line: 15, scope: !4)
+
+...
+---
+name: f
+alignment: 1
+exposesReturnsTwice: false
+hasInlineAsm: false
+allVRegsAllocated: true
+isSSA: false
+tracksRegLiveness: true
+tracksSubRegLiveness: false
+liveins:
+ - { reg: '%r0' }
+ - { reg: '%r1' }
+ - { reg: '%r2' }
+ - { reg: '%r3' }
+calleeSavedRegisters: [ '%lr', '%d8', '%d9', '%d10', '%d11', '%d12', '%d13',
+ '%d14', '%d15', '%q4', '%q5', '%q6', '%q7', '%r4',
+ '%r5', '%r6', '%r7', '%r8', '%r9', '%r10', '%r11',
+ '%s16', '%s17', '%s18', '%s19', '%s20', '%s21',
+ '%s22', '%s23', '%s24', '%s25', '%s26', '%s27',
+ '%s28', '%s29', '%s30', '%s31', '%d8_d10', '%d9_d11',
+ '%d10_d12', '%d11_d13', '%d12_d14', '%d13_d15',
+ '%q4_q5', '%q5_q6', '%q6_q7', '%q4_q5_q6_q7', '%r4_r5',
+ '%r6_r7', '%r8_r9', '%r10_r11', '%d8_d9_d10', '%d9_d10_d11',
+ '%d10_d11_d12', '%d11_d12_d13', '%d12_d13_d14',
+ '%d13_d14_d15', '%d8_d10_d12', '%d9_d11_d13', '%d10_d12_d14',
+ '%d11_d13_d15', '%d8_d10_d12_d14', '%d9_d11_d13_d15',
+ '%d9_d10', '%d11_d12', '%d13_d14', '%d9_d10_d11_d12',
+ '%d11_d12_d13_d14' ]
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 8
+ offsetAdjustment: 0
+ maxAlignment: 4
+ adjustsStack: true
+ hasCalls: true
+ maxCallFrameSize: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+stack:
+ - { id: 0, type: spill-slot, offset: -4, size: 4, alignment: 4, callee-saved-register: '%lr' }
+ - { id: 1, type: spill-slot, offset: -8, size: 4, alignment: 4, callee-saved-register: '%r7' }
+body: |
+ bb.0.entry:
+ successors: %bb.1, %bb.2.if.end
+ liveins: %r0, %r1, %r2, %r3, %lr, %r7
+
+ DBG_VALUE debug-use %r0, debug-use _, !18, !27, debug-location !28
+ DBG_VALUE debug-use %r1, debug-use _, !19, !27, debug-location !28
+ DBG_VALUE debug-use %r2, debug-use _, !20, !27, debug-location !28
+ DBG_VALUE debug-use %r3, debug-use _, !21, !27, debug-location !28
+ t2CMPri %r3, 4, 14, _, implicit-def %cpsr, debug-location !31
+ t2Bcc %bb.2.if.end, 2, killed %cpsr
+
+ bb.1:
+ liveins: %lr, %r7
+
+ DBG_VALUE debug-use %r1, debug-use _, !19, !27, debug-location !28
+ %r0 = t2MOVi -1, 14, _, _
+ DBG_VALUE debug-use %r1, debug-use _, !19, !27, debug-location !28
+ tBX_RET 14, _, implicit %r0, debug-location !34
+
+ bb.2.if.end:
+ liveins: %r0, %r2, %r3, %r7, %lr
+
+ %sp = frame-setup t2STMDB_UPD %sp, 14, _, killed %r7, killed %lr
+ frame-setup CFI_INSTRUCTION .cfi_def_cfa_offset 8
+ frame-setup CFI_INSTRUCTION .cfi_offset %lr, -4
+ frame-setup CFI_INSTRUCTION .cfi_offset %r7, -8
+ DBG_VALUE debug-use %r0, debug-use _, !18, !27, debug-location !28
+ DBG_VALUE debug-use %r1, debug-use _, !19, !27, debug-location !28
+ DBG_VALUE debug-use %r2, debug-use _, !20, !27, debug-location !28
+ DBG_VALUE debug-use %r3, debug-use _, !21, !27, debug-location !28
+ %r1 = COPY killed %r2, debug-location !32
+ DBG_VALUE debug-use %r1, debug-use _, !19, !27, debug-location !28
+ %r2 = COPY killed %r3, debug-location !32
+ tBL 14, _, @g, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit %r0, implicit %r1, implicit %r2, implicit-def %sp, debug-location !32
+ %r0 = t2MOVi 0, 14, _, _
+ %sp = t2LDMIA_UPD %sp, 14, _, def %r7, def %lr
+ tBX_RET 14, _, implicit %r0, debug-location !34
+# Verify that the DBG_VALUE is ignored.
+# CHECK: %sp = t2LDMIA_RET %sp, 14, _, def %r7, def %pc, implicit %r0
+
+...
diff --git a/test/CodeGen/ARM/Windows/builtin_longjmp.ll b/test/CodeGen/ARM/Windows/builtin_longjmp.ll
new file mode 100644
index 000000000000..52b6f301bb77
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/builtin_longjmp.ll
@@ -0,0 +1,15 @@
+; RUN: llc -mtriple thumbv7--windows-itanium -filetype asm -o - %s | FileCheck %s
+
+declare void @llvm.eh.sjlj.longjmp(i8*)
+
+define arm_aapcs_vfpcc void @test___builtin_longjump(i8* %b) {
+entry:
+ tail call void @llvm.eh.sjlj.longjmp(i8* %b)
+ unreachable
+}
+
+; CHECK: push.w {r11, lr}
+; CHECK: ldr.w r11, [r0]
+; CHECK: ldr.w sp, [r0, #8]
+; CHECK: ldr.w pc, [r0, #4]
+
diff --git a/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll b/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll
index a314259e499e..d303e9da8604 100644
--- a/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll
+++ b/test/CodeGen/ARM/Windows/chkstk-movw-movt-isel.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple thumbv7--windows-itanium -code-model large -filetype obj -o - %s \
+; RUN: llc -mtriple thumbv7--windows-itanium -code-model large -verify-machineinstrs -filetype obj -o - %s \
; RUN: | llvm-objdump -no-show-raw-insn -d - | FileCheck %s
; ModuleID = 'reduced.c'
diff --git a/test/CodeGen/ARM/Windows/chkstk.ll b/test/CodeGen/ARM/Windows/chkstk.ll
index cb787e14b5ba..330c1f458500 100644
--- a/test/CodeGen/ARM/Windows/chkstk.ll
+++ b/test/CodeGen/ARM/Windows/chkstk.ll
@@ -1,7 +1,7 @@
-; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 %s -o - \
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -verify-machineinstrs %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: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -code-model=large -verify-machineinstrs %s -o - \
; RUN: | FileCheck -check-prefix CHECK-LARGE-CODE-MODEL %s
define arm_aapcs_vfpcc void @check_watermark() {
diff --git a/test/CodeGen/ARM/Windows/dbzchk.ll b/test/CodeGen/ARM/Windows/dbzchk.ll
new file mode 100644
index 000000000000..599a7cf094c4
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/dbzchk.ll
@@ -0,0 +1,192 @@
+; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-DIV
+
+; int f(int n, int d) {
+; if (n / d)
+; return 1;
+; return 0;
+; }
+
+define arm_aapcs_vfpcc i32 @f(i32 %n, i32 %d) {
+entry:
+ %retval = alloca i32, align 4
+ %n.addr = alloca i32, align 4
+ %d.addr = alloca i32, align 4
+ store i32 %n, i32* %n.addr, align 4
+ store i32 %d, i32* %d.addr, align 4
+ %0 = load i32, i32* %n.addr, align 4
+ %1 = load i32, i32* %d.addr, align 4
+ %div = sdiv i32 %0, %1
+ %tobool = icmp ne i32 %div, 0
+ br i1 %tobool, label %if.then, label %if.end
+
+if.then:
+ store i32 1, i32* %retval, align 4
+ br label %return
+
+if.end:
+ store i32 0, i32* %retval, align 4
+ br label %return
+
+return:
+ %2 = load i32, i32* %retval, align 4
+ ret i32 %2
+}
+
+; CHECK-DIV-DAG: BB#0
+; CHECK-DIV-DAG: Successors according to CFG: BB#5({{.*}}) BB#4
+; CHECK-DIV-DAG: BB#1
+; CHECK-DIV-DAG: Successors according to CFG: BB#3
+; CHECK-DIV-DAG: BB#2
+; CHECK-DIV-DAG: Successors according to CFG: BB#3
+; CHECK-DIV-DAG: BB#3
+; CHECK-DIV-DAG: BB#4
+; CHECK-DIV-DAG: Successors according to CFG: BB#1({{.*}}) BB#2
+; CHECK-DIV-DAG: BB#5
+
+; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-MOD
+
+; int r;
+; int g(int l, int m) {
+; if (m <= 0)
+; return 0;
+; return (r = l % m);
+; }
+
+@r = common global i32 0, align 4
+
+define arm_aapcs_vfpcc i32 @g(i32 %l, i32 %m) {
+entry:
+ %cmp = icmp eq i32 %m, 0
+ br i1 %cmp, label %return, label %if.end
+
+if.end:
+ %rem = urem i32 %l, %m
+ store i32 %rem, i32* @r, align 4
+ br label %return
+
+return:
+ %retval.0 = phi i32 [ %rem, %if.end ], [ 0, %entry ]
+ ret i32 %retval.0
+}
+
+; CHECK-MOD-DAG: BB#0
+; CHECK-MOD-DAG: Successors according to CFG: BB#2({{.*}}) BB#1
+; CHECK-MOD-DAG: BB#1
+; CHECK-MOD-DAG: Successors according to CFG: BB#4({{.*}}) BB#3
+; CHECK-MOD-DAG: BB#2
+; CHECK-MOD-DAG: BB#3
+; CHECK-MOD-DAG: Successors according to CFG: BB#2
+; CHECK-MOD-DAG: BB#4
+
+; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-CFG
+; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-CFG-ASM
+
+; unsigned c;
+; extern unsigned long g(void);
+; int f(unsigned u, signed char b) {
+; if (b)
+; c = g() % u;
+; return c;
+; }
+
+@c = common global i32 0, align 4
+
+declare arm_aapcs_vfpcc i32 @i()
+
+define arm_aapcs_vfpcc i32 @h(i32 %u, i8 signext %b) #0 {
+entry:
+ %tobool = icmp eq i8 %b, 0
+ br i1 %tobool, label %entry.if.end_crit_edge, label %if.then
+
+entry.if.end_crit_edge:
+ %.pre = load i32, i32* @c, align 4
+ br label %if.end
+
+if.then:
+ %call = tail call arm_aapcs_vfpcc i32 @i()
+ %rem = urem i32 %call, %u
+ store i32 %rem, i32* @c, align 4
+ br label %if.end
+
+if.end:
+ %0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %rem, %if.then ]
+ ret i32 %0
+}
+
+attributes #0 = { optsize }
+
+; CHECK-CFG-DAG: BB#0
+; CHECK-CFG-DAG: t2Bcc <BB#2>
+; CHECK-CFG-DAG: t2B <BB#1>
+
+; CHECK-CFG-DAG: BB#1
+; CHECK-CFG-DAG: t2B <BB#3>
+
+; CHECK-CFG-DAG: BB#2
+; CHECK-CFG-DAG: tCBZ %vreg{{[0-9]}}, <BB#5>
+; CHECK-CFG-DAG: t2B <BB#4>
+
+; CHECK-CFG-DAG: BB#4
+
+; CHECK-CFG-DAG: BB#3
+; CHECK-CFG-DAG: tBX_RET
+
+; CHECK-CFG-DAG: BB#5
+; CHECK-CFG-DAG: t2UDF 249
+
+; CHECK-CFG-ASM-LABEL: h:
+; CHECK-CFG-ASM: cbz r{{[0-9]}}, .LBB2_2
+; CHECK-CFG-ASM: b .LBB2_4
+; CHECK-CFG-ASM-LABEL: .LBB2_2:
+; CHECK-CFG-ASM-NEXT: udf.w #249
+; CHECK-CFG-ASM-LABEL: .LBB2_4:
+; CHECK-CFG-ASM: bl __rt_udiv
+; CHECK-CFG-ASM: pop.w {{{.*}}, r11, pc}
+
+; RUN: llc -O0 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
+
+; long k(void);
+; int l(void);
+; int j(int i) {
+; if (l() == -1)
+; return 0;
+; return k() % i;
+; }
+
+declare arm_aapcs_vfpcc i32 @k()
+declare arm_aapcs_vfpcc i32 @l()
+
+define arm_aapcs_vfpcc i32 @j(i32 %i) {
+entry:
+ %retval = alloca i32, align 4
+ %i.addr = alloca i32, align 4
+ store i32 %i, i32* %i.addr, align 4
+ %call = call arm_aapcs_vfpcc i32 @l()
+ %cmp = icmp eq i32 %call, -1
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ store i32 0, i32* %retval, align 4
+ br label %return
+
+if.end:
+ %call1 = call arm_aapcs_vfpcc i32 @k()
+ %0 = load i32, i32* %i.addr, align 4
+ %rem = srem i32 %call1, %0
+ store i32 %rem, i32* %retval, align 4
+ br label %return
+
+return:
+ %1 = load i32, i32* %retval, align 4
+ ret i32 %1
+}
+
+; CHECK-WIN__DBZCHK-LABEL: j:
+; CHECK-WIN__DBZCHK: cbz r{{[0-7]}}, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz r8, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz r9, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz r10, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz r11, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz ip, .LBB
+; CHECK-WIN__DBZCHK-NOT: cbz lr, .LBB
+
diff --git a/test/CodeGen/ARM/Windows/division.ll b/test/CodeGen/ARM/Windows/division.ll
index b3ef9c6d278b..f4704ea7ff4b 100644
--- a/test/CodeGen/ARM/Windows/division.ll
+++ b/test/CodeGen/ARM/Windows/division.ll
@@ -7,8 +7,11 @@ entry:
ret i32 %div
}
-; CHECK-LABEL: sdiv32
-; CHECK: b __rt_sdiv
+; CHECK-LABEL: sdiv32:
+; CHECK: cbz r0
+; CHECK: b
+; CHECK: udf.w #249
+; CHECK: bl __rt_sdiv
define arm_aapcs_vfpcc i32 @udiv32(i32 %divisor, i32 %divident) {
entry:
@@ -17,7 +20,10 @@ entry:
}
; CHECK-LABEL: udiv32:
-; CHECK: b __rt_udiv
+; CHECK: cbz r0
+; CHECK: b
+; CHECK: udf.w #249
+; CHECK: bl __rt_udiv
define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) {
entry:
@@ -25,7 +31,11 @@ entry:
ret i64 %div
}
-; CHECK-LABEL: sdiv64
+; CHECK-LABEL: sdiv64:
+; CHECK: orr.w r4, r0, r1
+; CHECK-NEXT: cbz r4
+; CHECK: b
+; CHECK: udf.w #249
; CHECK: bl __rt_sdiv64
define arm_aapcs_vfpcc i64 @udiv64(i64 %divisor, i64 %divident) {
@@ -35,4 +45,9 @@ entry:
}
; CHECK-LABEL: udiv64:
+; CHECK: orr.w r4, r0, r1
+; CHECK-NEXT: cbz r4
+; CHECK: b
+; CHECK: udf.w #249
; CHECK: bl __rt_udiv64
+
diff --git a/test/CodeGen/ARM/Windows/dllexport.ll b/test/CodeGen/ARM/Windows/dllexport.ll
new file mode 100644
index 000000000000..27496208862e
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/dllexport.ll
@@ -0,0 +1,75 @@
+; RUN: llc -mtriple thumbv7--windows-itanium -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU
+; RUN: llc -mtriple thumbv7--windows-gnu -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU
+; RUN: llc -mtriple thumbv7--windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MSVC
+
+define void @f() {
+ ret void
+}
+
+define dllexport void @g() {
+ ret void
+}
+
+define dllexport void @h() unnamed_addr {
+ ret void
+}
+
+declare dllexport void @i()
+
+define linkonce_odr dllexport void @j() {
+ ret void
+}
+
+define linkonce_odr dllexport void @k() alwaysinline {
+ ret void
+}
+
+define weak_odr dllexport void @l() {
+ ret void
+}
+
+@m = dllexport global i32 0, align 4
+@n = dllexport unnamed_addr constant i32 0
+@o = common dllexport global i32 0, align 4
+@p = weak_odr dllexport global i32 0, align 4
+@q = weak_odr dllexport unnamed_addr constant i32 0
+
+@r = dllexport alias void (), void () * @f
+@s = dllexport alias void (), void () * @g
+@t = dllexport alias void (), void () * @f
+@u = weak_odr dllexport alias void (), void () * @g
+
+; CHECK: .section .drectve
+; CHECK-GNU-NOT: -export:f
+; CHECK-GNU: -export:g
+; CHECK-GNU-SAME: -export:h
+; CHECK-GNU-NOT: -export:i
+; CHECK-GNU-SAME: -export:j
+; CHECK-GNU-SAME: -export:k
+; CHECK-GNU-SAME: -export:l
+; CHECK-GNU-SAME: -export:m,data
+; CHECK-GNU-SAME: -export:n,data
+; CHECK-GNU-SAME: -export:o,data
+; CHECK-GNU-SAME: -export:p,data
+; CHECK-GNU-SAME: -export:q,data
+; CHECK-GNU-SAME: -export:r
+; CHECK-GNU-SAME: -export:s
+; CHECK-GNU-SAME: -export:t
+; CHECK-GNU-SAME: -export:u
+; CHECK-MSVC-NOT: /EXPORT:f
+; CHECK-MSVC: /EXPORT:g
+; CHECK-MSVC-SAME: /EXPORT:h
+; CHECK-MSVC-NOT: /EXPORT:i
+; CHECK-MSVC-SAME: /EXPORT:j
+; CHECK-MSVC-SAME: /EXPORT:k
+; CHECK-MSVC-SAME: /EXPORT:l
+; CHECK-MSVC-SAME: /EXPORT:m,DATA
+; CHECK-MSVC-SAME: /EXPORT:n,DATA
+; CHECK-MSVC-SAME: /EXPORT:o,DATA
+; CHECK-MSVC-SAME: /EXPORT:p,DATA
+; CHECK-MSVC-SAME: /EXPORT:q,DATA
+; CHECK-MSVC-SAME: /EXPORT:r
+; CHECK-MSVC-SAME: /EXPORT:s
+; CHECK-MSVC-SAME: /EXPORT:t
+; CHECK-MSVC-SAME: /EXPORT:u
+
diff --git a/test/CodeGen/ARM/Windows/long-calls.ll b/test/CodeGen/ARM/Windows/long-calls.ll
index 4e5bdce146f0..29e6f783ae5f 100644
--- a/test/CodeGen/ARM/Windows/long-calls.ll
+++ b/test/CodeGen/ARM/Windows/long-calls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -mattr=+long-calls -o - %s \
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -relocation-model pic -mattr=+long-calls -o - %s \
; RUN: | FileCheck %s
declare arm_aapcs_vfpcc void @callee()
@@ -12,7 +12,7 @@ entry:
; CHECK-LABEL: caller
; CHECK: ldr [[REG:r[0-9]+]], [[CPI:LCPI[_0-9]+]]
; CHECK: bx [[REG]]
-; CHECK: .align 2
+; CHECK: .p2align 2
; CHECK: [[CPI]]:
; CHECK: .long callee
diff --git a/test/CodeGen/ARM/Windows/no-aeabi.ll b/test/CodeGen/ARM/Windows/no-aeabi.ll
index 3971b9ccf580..a4103b0a676e 100644
--- a/test/CodeGen/ARM/Windows/no-aeabi.ll
+++ b/test/CodeGen/ARM/Windows/no-aeabi.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -verify-machineinstrs -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
diff --git a/test/CodeGen/ARM/Windows/overflow.ll b/test/CodeGen/ARM/Windows/overflow.ll
deleted file mode 100644
index 5f74f25ac224..000000000000
--- a/test/CodeGen/ARM/Windows/overflow.ll
+++ /dev/null
@@ -1,77 +0,0 @@
-; RUN: llc -mtriple thumbv7-windows-gnu -filetype asm -o - %s
-
-define i32 @divsoverflow32(i32 %a, i32 %b) {
- %1 = alloca i32, align 4
- %2 = alloca i32, align 4
- %3 = load i32, i32* %1, align 4
- %4 = load i32, i32* %2, align 4
- %5 = sub nsw i32 0, %4
- %6 = sdiv i32 -2147483647, %3
- %7 = icmp sgt i32 %5, %6
- br i1 %7, label %8, label %9
- call void (...) @abort_simpl32()
- unreachable
- %10 = load i32, i32* %1, align 4
- %11 = load i32, i32* %2, align 4
- %12 = mul nsw i32 %10, %11
- ret i32 %12
-}
-
-declare void @abort_simpl32(...)
-
-define i64 @divsoverflow64(i64 %a, i64 %b) {
- %1 = alloca i64, align 8
- %2 = alloca i64, align 8
- %3 = load i64, i64* %1, align 8
- %4 = load i64, i64* %2, align 8
- %5 = sub nsw i64 0, %4
- %6 = sdiv i64 -9223372036854775808, %3
- %7 = icmp sgt i64 %5, %6
- br i1 %7, label %8, label %9
- call void (...) @abort_simpl64()
- unreachable
- %10 = load i64, i64* %1, align 8
- %11 = load i64, i64* %2, align 8
- %12 = mul nsw i64 %10, %11
- ret i64 %12
-}
-
-declare void @abort_simpl64(...)
-
-define i32 @divuoverflow32(i32 %a, i32 %b) {
- %1 = alloca i32, align 4
- %2 = alloca i32, align 4
- %3 = load i32, i32* %1, align 4
- %4 = load i32, i32* %2, align 4
- %5 = sub nsw i32 0, %4
- %6 = udiv i32 4294967296, %3
- %7 = icmp sgt i32 %5, %6
- br i1 %7, label %8, label %9
- call void (...) @abort_uimpl32()
- unreachable
- %10 = load i32, i32* %1, align 4
- %11 = load i32, i32* %2, align 4
- %12 = mul nsw i32 %10, %11
- ret i32 %12
-}
-
-declare void @abort_uimpl32(...)
-
-define i64 @divuoverflow64(i64 %a, i64 %b) {
- %1 = alloca i64, align 8
- %2 = alloca i64, align 8
- %3 = load i64, i64* %1, align 8
- %4 = load i64, i64* %2, align 8
- %5 = sub nsw i64 0, %4
- %6 = udiv i64 18446744073709551616, %3
- %7 = icmp sgt i64 %5, %6
- br i1 %7, label %8, label %9
- call void (...) @abort_uimpl64()
- unreachable
- %10 = load i64, i64* %1, align 8
- %11 = load i64, i64* %2, align 8
- %12 = mul nsw i64 %10, %11
- ret i64 %12
-}
-
-declare void @abort_uimpl64(...)
diff --git a/test/CodeGen/ARM/Windows/tls.ll b/test/CodeGen/ARM/Windows/tls.ll
new file mode 100644
index 000000000000..689f4e291872
--- /dev/null
+++ b/test/CodeGen/ARM/Windows/tls.ll
@@ -0,0 +1,157 @@
+; RUN: llc -mtriple thumbv7--windows-itanium %s -o - | FileCheck %s
+
+@i = thread_local global i32 0
+@j = external thread_local global i32
+@k = internal thread_local global i32 0
+@l = hidden thread_local global i32 0
+@m = external hidden thread_local global i32
+@n = thread_local global i16 0
+@o = thread_local global i8 0
+
+define i32 @f() {
+ %1 = load i32, i32* @i
+ ret i32 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long i(SECREL32)
+
+define i32 @e() {
+ %1 = load i32, i32* @j
+ ret i32 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long j(SECREL32)
+
+define i32 @d() {
+ %1 = load i32, i32* @k
+ ret i32 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long k(SECREL32)
+
+define i32 @c() {
+ %1 = load i32, i32* @l
+ ret i32 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long l(SECREL32)
+
+define i32 @b() {
+ %1 = load i32, i32* @m
+ ret i32 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK: .long m(SECREL32)
+
+define i16 @a() {
+ %1 = load i16, i16* @n
+ ret i16 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldrh r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK: .long n(SECREL32)
+
+define i8 @Z() {
+ %1 = load i8, i8* @o
+ ret i8 %1
+}
+
+; CHECK: mrc p15, #0, [[TEB:r[0-9]]], c13, c0, #2
+
+; CHECK: movw [[TLS_INDEX:r[0-9]]], :lower16:_tls_index
+; CHECK-NEXT: movt [[TLS_INDEX]], :upper16:_tls_index
+; CHECK-NEXT: ldr [[INDEX:r[0-9]]], {{\[}}[[TLS_INDEX]]]
+
+; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
+; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
+
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
+
+; CHECK-NEXT: ldrb r0, {{\[}}[[TLS]], [[SLOT]]]
+
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long o(SECREL32)
+
diff --git a/test/CodeGen/ARM/align.ll b/test/CodeGen/ARM/align.ll
index 9589e72df2f5..74525909148d 100644
--- a/test/CodeGen/ARM/align.ll
+++ b/test/CodeGen/ARM/align.ll
@@ -8,33 +8,33 @@
; no alignment
@c = global i16 2
-;ELF: .align 1
+;ELF: .p2align 1
;ELF: c:
-;DARWIN: .align 1
+;DARWIN: .p2align 1
;DARWIN: _c:
@d = global i32 3
-;ELF: .align 2
+;ELF: .p2align 2
;ELF: d:
-;DARWIN: .align 2
+;DARWIN: .p2align 2
;DARWIN: _d:
@e = global i64 4
-;ELF: .align 3
+;ELF: .p2align 3
;ELF: e
-;DARWIN: .align 3
+;DARWIN: .p2align 3
;DARWIN: _e:
@f = global float 5.0
-;ELF: .align 2
+;ELF: .p2align 2
;ELF: f:
-;DARWIN: .align 2
+;DARWIN: .p2align 2
;DARWIN: _f:
@g = global double 6.0
-;ELF: .align 3
+;ELF: .p2align 3
;ELF: g:
-;DARWIN: .align 3
+;DARWIN: .p2align 3
;DARWIN: _g:
@bar = common global [75 x i8] zeroinitializer, align 128
diff --git a/test/CodeGen/ARM/arm-and-tst-peephole.ll b/test/CodeGen/ARM/arm-and-tst-peephole.ll
index 04eae8f9afec..151cc1b12ed2 100644
--- a/test/CodeGen/ARM/arm-and-tst-peephole.ll
+++ b/test/CodeGen/ARM/arm-and-tst-peephole.ll
@@ -49,7 +49,7 @@ tailrecurse.switch: ; preds = %tailrecurse
; V8-NEXT: beq
; V8-NEXT: %tailrecurse.switch
; V8: cmp
-; V8-NEXT: bne
+; V8-NEXT: beq
; V8-NEXT: b
; The trailing space in the last line checks that the branch is unconditional
switch i32 %and, label %sw.epilog [
diff --git a/test/CodeGen/ARM/arm-eabi.ll b/test/CodeGen/ARM/arm-eabi.ll
index d1e7a947553f..898055dd1092 100644
--- a/test/CodeGen/ARM/arm-eabi.ll
+++ b/test/CodeGen/ARM/arm-eabi.ll
@@ -3,21 +3,29 @@
; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
+; RUN: llc < %s -mtriple=arm-none-musleabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
+; RUN: llc < %s -mtriple=arm-none-musleabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-eabi -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-eabihf -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-androideabi -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-gnueabi -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-gnueabihf -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
+; RUN: llc < %s -mtriple=arm-none-musleabi -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
+; RUN: llc < %s -mtriple=arm-none-musleabihf -meabi=gnu -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI
; RUN: llc < %s -mtriple=arm-none-eabi -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-eabihf -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-androideabi -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabi -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabihf -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-musleabi -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-musleabihf -meabi=4 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-eabi -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-eabihf -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-androideabi -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabi -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
; RUN: llc < %s -mtriple=arm-none-gnueabihf -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-musleabi -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
+; RUN: llc < %s -mtriple=arm-none-musleabihf -meabi=5 -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI
%struct.my_s = type { [18 x i32] }
diff --git a/test/CodeGen/ARM/arm-interleaved-accesses-extract-user.ll b/test/CodeGen/ARM/arm-interleaved-accesses-extract-user.ll
new file mode 100644
index 000000000000..620cb6356411
--- /dev/null
+++ b/test/CodeGen/ARM/arm-interleaved-accesses-extract-user.ll
@@ -0,0 +1,86 @@
+; RUN: opt < %s -mtriple=arm-eabi -mattr=+neon -interleaved-access -S | FileCheck %s
+
+; CHECK-LABEL: @extract_user_basic(
+; CHECK: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+; CHECK: %[[R:.+]] = extractvalue { <4 x i32>, <4 x i32> } %vldN, 0
+; CHECK: extractelement <4 x i32> %[[R]], i64 1
+define void @extract_user_basic(<8 x i32>* %A, i1 %C) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ br i1 %C, label %if.then, label %if.merge
+
+if.then:
+ %E = extractelement <8 x i32> %L, i32 2
+ br label %if.merge
+
+if.merge:
+ ret void
+}
+
+; CHECK-LABEL: @extract_user_multi(
+; CHECK: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+; CHECK: %[[R:.+]] = extractvalue { <4 x i32>, <4 x i32> } %vldN, 0
+; CHECK: extractelement <4 x i32> %[[R]], i64 0
+; CHECK: extractelement <4 x i32> %[[R]], i64 1
+define void @extract_user_multi(<8 x i32>* %A, i1 %C) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ br i1 %C, label %if.then, label %if.merge
+
+if.then:
+ %E1 = extractelement <8 x i32> %L, i32 0
+ br label %if.merge
+
+if.merge:
+ %E2 = extractelement <8 x i32> %L, i32 2
+ ret void
+}
+
+; CHECK-LABEL: @extract_user_multi_no_dom(
+; CHECK-NOT: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+define void @extract_user_multi_no_dom(<8 x i32>* %A, i1 %C) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %E1 = extractelement <8 x i32> %L, i32 0
+ br i1 %C, label %if.then, label %if.merge
+
+if.then:
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %E2 = extractelement <8 x i32> %L, i32 2
+ br label %if.merge
+
+if.merge:
+ ret void
+}
+
+; CHECK-LABEL: @extract_user_wrong_const_index(
+; CHECK-NOT: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+define void @extract_user_wrong_const_index(<8 x i32>* %A) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %E = extractelement <8 x i32> %L, i32 1
+ ret void
+}
+
+; CHECK-LABEL: @extract_user_undef_index(
+; CHECK-NOT: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+define void @extract_user_undef_index(<8 x i32>* %A) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %E = extractelement <8 x i32> %L, i32 undef
+ ret void
+}
+
+; CHECK-LABEL: @extract_user_var_index(
+; CHECK-NOT: %vldN = call { <4 x i32>, <4 x i32> } @llvm.arm.neon.vld2.v4i32.p0i8
+define void @extract_user_var_index(<8 x i32>* %A, i32 %I) {
+entry:
+ %L = load <8 x i32>, <8 x i32>* %A, align 8
+ %S = shufflevector <8 x i32> %L, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %E = extractelement <8 x i32> %L, i32 %I
+ ret void
+}
diff --git a/test/CodeGen/ARM/arm-interleaved-accesses.ll b/test/CodeGen/ARM/arm-interleaved-accesses.ll
index 002e71f6d9b8..6f3d537176c0 100644
--- a/test/CodeGen/ARM/arm-interleaved-accesses.ll
+++ b/test/CodeGen/ARM/arm-interleaved-accesses.ll
@@ -304,3 +304,15 @@ define void @store_illegal_factor2(<3 x float>* %p, <3 x float> %v) nounwind {
store <3 x float> %tmp1, <3 x float>* %p, align 16
ret void
}
+
+; NEON-LABEL: load_factor2_with_extract_user:
+; NEON: vld2.32 {d16, d17, d18, d19}, [r0:64]
+; NEON: vmov.32 r0, d16[1]
+; NONEON-LABEL: load_factor2_with_extract_user:
+; NONEON-NOT: vld2
+define i32 @load_factor2_with_extract_user(<8 x i32>* %a) {
+ %1 = load <8 x i32>, <8 x i32>* %a, align 8
+ %2 = shufflevector <8 x i32> %1, <8 x i32> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6>
+ %3 = extractelement <8 x i32> %1, i32 2
+ ret i32 %3
+}
diff --git a/test/CodeGen/ARM/arm-shrink-wrapping.ll b/test/CodeGen/ARM/arm-shrink-wrapping.ll
index 9375df4b15cb..cb608fc18d95 100644
--- a/test/CodeGen/ARM/arm-shrink-wrapping.ll
+++ b/test/CodeGen/ARM/arm-shrink-wrapping.ll
@@ -629,7 +629,7 @@ end:
declare double @llvm.pow.f64(double, double)
; This function needs to spill floating point registers to
-; exerce the path where we were deferencing the end iterator
+; exercise the path where we were dereferencing the end iterator
; to access debug info location while inserting the spill code
; during PEI with shrink-wrapping enable.
; CHECK-LABEL: debug_info:
@@ -677,7 +677,7 @@ bb13: ; preds = %bb3, %bb
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: 1, enums: !2, retainedTypes: !2, subprograms: !2, globals: !2, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "a.cpp", directory: "b")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
diff --git a/test/CodeGen/ARM/atomic-64bit.ll b/test/CodeGen/ARM/atomic-64bit.ll
index 573cd45c0825..8841483c97a4 100644
--- a/test/CodeGen/ARM/atomic-64bit.ll
+++ b/test/CodeGen/ARM/atomic-64bit.ll
@@ -172,31 +172,31 @@ define i64 @test6(i64* %ptr, i64 %val) {
define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) {
; CHECK-LABEL: test7:
; CHECK-DAG: mov [[VAL1LO:r[0-9]+]], r1
-; CHECK-DAG: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
-; CHECK-LE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG1]], [[VAL1LO]]
-; CHECK-LE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG2]], r2
-; CHECK-BE-DAG: eor [[MISMATCH_LO:r[0-9]+]], [[REG2]], r2
-; CHECK-BE-DAG: eor [[MISMATCH_HI:r[0-9]+]], [[REG1]], r1
+; CHECK-LE-DAG: eor [[MISMATCH_LO:.*]], [[REG1]], [[VAL1LO]]
+; CHECK-LE-DAG: eor [[MISMATCH_HI:.*]], [[REG2]], r2
+; CHECK-BE-DAG: eor [[MISMATCH_LO:.*]], [[REG2]], r2
+; CHECK-BE-DAG: eor [[MISMATCH_HI:.*]], [[REG1]], r1
; CHECK: orrs {{r[0-9]+}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
; CHECK: bne
+; CHECK-DAG: dmb {{ish$}}
; CHECK: strexd {{[a-z0-9]+}}, {{r[0-9]?[02468]}}, {{r[0-9]?[13579]}}
; CHECK: cmp
-; CHECK: bne
+; CHECK: beq
; CHECK: dmb {{ish$}}
; CHECK-THUMB-LABEL: test7:
-; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG1]], r2
; CHECK-THUMB-LE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG2]], r3
; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_HI:[a-z0-9]+]], [[REG1]], r2
; CHECK-THUMB-BE-DAG: eor.w [[MISMATCH_LO:[a-z0-9]+]], [[REG2]], r3
-; CHECK-THUMB-LE: orrs [[MISMATCH_HI]], [[MISMATCH_LO]]
+; CHECK-THUMB-LE: orrs.w {{.*}}, [[MISMATCH_LO]], [[MISMATCH_HI]]
; CHECK-THUMB: bne
+; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: strexd {{[a-z0-9]+}}, {{[a-z0-9]+}}, {{[a-z0-9]+}}
; CHECK-THUMB: cmp
-; CHECK-THUMB: bne
+; CHECK-THUMB: beq
; CHECK-THUMB: dmb {{ish$}}
%pair = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst seq_cst
@@ -251,21 +251,18 @@ define i64 @test10(i64* %ptr, i64 %val) {
; CHECK-LABEL: test10:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
-; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
-; CHECK-LE: cmp [[REG1]], r1
-; CHECK-BE: cmp [[REG2]], r2
-; CHECK: movwls [[CARRY_LO]], #1
-; CHECK-LE: cmp [[REG2]], r2
-; CHECK-BE: cmp [[REG1]], r1
-; CHECK: movwle [[CARRY_HI]], #1
-; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK: cmp [[CARRY_HI]], #0
+; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
+; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
+; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
+; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
+; CHECK: mov [[CMP:[a-z0-9]+]], #0
+; CHECK: movwge [[CMP]], #1
+; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
-; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}
@@ -273,21 +270,18 @@ define i64 @test10(i64* %ptr, i64 %val) {
; CHECK-THUMB-LABEL: test10:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
-; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+|lr]], #0
-; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+|lr]], #0
-; CHECK-THUMB-LE: cmp [[REG1]], r2
-; CHECK-THUMB-BE: cmp [[REG2]], r3
-; CHECK-THUMB: movls.w [[CARRY_LO]], #1
-; CHECK-THUMB-LE: cmp [[REG2]], r3
-; CHECK-THUMB-BE: cmp [[REG1]], r2
-; CHECK-THUMB: movle [[CARRY_HI]], #1
-; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
-; CHECK-THUMB: cmp [[CARRY_HI]], #0
-; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
+; CHECK-THUMB: movge.w [[CMP]], #1
+; CHECK-THUMB: cmp.w [[CMP]], #0
+; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
-; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
@@ -300,21 +294,18 @@ define i64 @test11(i64* %ptr, i64 %val) {
; CHECK-LABEL: test11:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
-; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
-; CHECK-LE: cmp [[REG1]], r1
-; CHECK-BE: cmp [[REG2]], r2
-; CHECK: movwls [[CARRY_LO]], #1
-; CHECK-LE: cmp [[REG2]], r2
-; CHECK-BE: cmp [[REG1]], r1
-; CHECK: movwls [[CARRY_HI]], #1
-; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK: cmp [[CARRY_HI]], #0
+; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
+; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
+; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
+; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
+; CHECK: mov [[CMP:[a-z0-9]+]], #0
+; CHECK: movwhs [[CMP]], #1
+; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
-; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}
@@ -322,21 +313,18 @@ define i64 @test11(i64* %ptr, i64 %val) {
; CHECK-THUMB-LABEL: test11:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
-; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
-; CHECK-THUMB-LE: cmp [[REG1]], r2
-; CHECK-THUMB-BE: cmp [[REG2]], r3
-; CHECK-THUMB: movls.w [[CARRY_LO]], #1
-; CHECK-THUMB-LE: cmp [[REG2]], r3
-; CHECK-THUMB-BE: cmp [[REG1]], r2
-; CHECK-THUMB: movls [[CARRY_HI]], #1
-; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
-; CHECK-THUMB: cmp [[CARRY_HI]], #0
-; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
+; CHECK-THUMB: movhs.w [[CMP]], #1
+; CHECK-THUMB: cmp.w [[CMP]], #0
+; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
-; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
@@ -349,21 +337,18 @@ define i64 @test12(i64* %ptr, i64 %val) {
; CHECK-LABEL: test12:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
-; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
-; CHECK-LE: cmp [[REG1]], r1
-; CHECK-BE: cmp [[REG2]], r2
-; CHECK: movwhi [[CARRY_LO]], #1
-; CHECK-LE: cmp [[REG2]], r2
-; CHECK-BE: cmp [[REG1]], r1
-; CHECK: movwgt [[CARRY_HI]], #1
-; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK: cmp [[CARRY_HI]], #0
+; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
+; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
+; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
+; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
+; CHECK: mov [[CMP:[a-z0-9]+]], #0
+; CHECK: movwlt [[CMP]], #1
+; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
-; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}
@@ -371,21 +356,18 @@ define i64 @test12(i64* %ptr, i64 %val) {
; CHECK-THUMB-LABEL: test12:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
-; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
-; CHECK-THUMB-LE: cmp [[REG1]], r2
-; CHECK-THUMB-BE: cmp [[REG2]], r3
-; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
-; CHECK-THUMB-LE: cmp [[REG2]], r3
-; CHECK-THUMB-BE: cmp [[REG1]], r2
-; CHECK-THUMB: movgt [[CARRY_HI]], #1
-; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
-; CHECK-THUMB: cmp [[CARRY_HI]], #0
-; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
+; CHECK-THUMB: movlt.w [[CMP]], #1
+; CHECK-THUMB: cmp.w [[CMP]], #0
+; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
-; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
@@ -398,21 +380,18 @@ define i64 @test13(i64* %ptr, i64 %val) {
; CHECK-LABEL: test13:
; CHECK: dmb {{ish$}}
; CHECK: ldrexd [[REG1:(r[0-9]?[02468])]], [[REG2:(r[0-9]?[13579])]]
-; CHECK: mov [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK: mov [[CARRY_HI:[a-z0-9]+]], #0
; CHECK: mov [[OUT_HI:[a-z0-9]+]], r2
-; CHECK-LE: cmp [[REG1]], r1
-; CHECK-BE: cmp [[REG2]], r2
-; CHECK: movwhi [[CARRY_LO]], #1
-; CHECK-LE: cmp [[REG2]], r2
-; CHECK-BE: cmp [[REG1]], r1
-; CHECK: movwhi [[CARRY_HI]], #1
-; CHECK: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK: cmp [[CARRY_HI]], #0
+; CHECK-LE: subs {{[^,]+}}, r1, [[REG1]]
+; CHECK-BE: subs {{[^,]+}}, r2, [[REG2]]
+; CHECK-LE: sbcs {{[^,]+}}, r2, [[REG2]]
+; CHECK-BE: sbcs {{[^,]+}}, r1, [[REG1]]
+; CHECK: mov [[CMP:[a-z0-9]+]], #0
+; CHECK: movwlo [[CMP]], #1
+; CHECK: cmp [[CMP]], #0
; CHECK: movne [[OUT_HI]], [[REG2]]
; CHECK: mov [[OUT_LO:[a-z0-9]+]], r1
; CHECK: movne [[OUT_LO]], [[REG1]]
-; CHECK: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK: cmp
; CHECK: bne
; CHECK: dmb {{ish$}}
@@ -420,21 +399,18 @@ define i64 @test13(i64* %ptr, i64 %val) {
; CHECK-THUMB-LABEL: test13:
; CHECK-THUMB: dmb {{ish$}}
; CHECK-THUMB: ldrexd [[REG1:[a-z0-9]+]], [[REG2:[a-z0-9]+]]
-; CHECK-THUMB: mov.w [[CARRY_LO:[a-z0-9]+]], #0
-; CHECK-THUMB: movs [[CARRY_HI:[a-z0-9]+]], #0
-; CHECK-THUMB-LE: cmp [[REG1]], r2
-; CHECK-THUMB-BE: cmp [[REG2]], r3
-; CHECK-THUMB: movhi.w [[CARRY_LO]], #1
-; CHECK-THUMB-LE: cmp [[REG2]], r3
-; CHECK-THUMB-BE: cmp [[REG1]], r2
-; CHECK-THUMB: movhi [[CARRY_HI]], #1
-; CHECK-THUMB: moveq [[CARRY_HI]], [[CARRY_LO]]
-; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
-; CHECK-THUMB: cmp [[CARRY_HI]], #0
-; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB: mov [[OUT_LO:[a-z0-9]+]], r2
+; CHECK-THUMB-LE: subs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB-BE: subs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-LE: sbcs.w {{[^,]+}}, r3, [[REG2]]
+; CHECK-THUMB-BE: sbcs.w {{[^,]+}}, r2, [[REG1]]
+; CHECK-THUMB: mov.w [[CMP:[a-z0-9]+]], #0
+; CHECK-THUMB: movlo.w [[CMP]], #1
+; CHECK-THUMB: cmp.w [[CMP]], #0
+; CHECK-THUMB: mov [[OUT_HI:[a-z0-9]+]], r3
; CHECK-THUMB: movne [[OUT_HI]], [[REG2]]
; CHECK-THUMB: movne [[OUT_LO]], [[REG1]]
-; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[REG3]], [[REG4]]
+; CHECK-THUMB: strexd {{[a-z0-9]+}}, [[OUT_LO]], [[OUT_HI]]
; CHECK-THUMB: cmp
; CHECK-THUMB: bne
; CHECK-THUMB: dmb {{ish$}}
diff --git a/test/CodeGen/ARM/atomic-op.ll b/test/CodeGen/ARM/atomic-op.ll
index 791389456619..17324d64153d 100644
--- a/test/CodeGen/ARM/atomic-op.ll
+++ b/test/CodeGen/ARM/atomic-op.ll
@@ -1,7 +1,7 @@
; RUN: llc < %s -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix CHECK-ARMV7
; RUN: llc < %s -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-T2
; RUN: llc < %s -mtriple=thumbv6-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-T1
-; RUN: llc < %s -mtriple=thumbv6-apple-ios -verify-machineinstrs -mcpu=cortex-m0 | FileCheck %s --check-prefix=CHECK-M0
+; RUN: llc < %s -mtriple=thumbv6-apple-ios -verify-machineinstrs -mcpu=cortex-m0 | FileCheck %s --check-prefix=CHECK-T1
; RUN: llc < %s -mtriple=thumbv7--none-eabi -thread-model single -verify-machineinstrs | FileCheck %s --check-prefix=CHECK-BAREMETAL
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
@@ -29,8 +29,7 @@ entry:
; CHECK: ldrex
; CHECK: add
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_add_4
- ; CHECK-M0: bl ___sync_fetch_and_add_4
+ ; CHECK-T1: bl ___sync_fetch_and_add_4
; CHECK-BAREMETAL: add
; CHECK-BAREMETAL-NOT: __sync
%0 = atomicrmw add i32* %val1, i32 %tmp monotonic
@@ -38,8 +37,7 @@ entry:
; CHECK: ldrex
; CHECK: sub
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_sub_4
- ; CHECK-M0: bl ___sync_fetch_and_sub_4
+ ; CHECK-T1: bl ___sync_fetch_and_sub_4
; CHECK-BAREMETAL: sub
; CHECK-BAREMETAL-NOT: __sync
%1 = atomicrmw sub i32* %val2, i32 30 monotonic
@@ -47,8 +45,7 @@ entry:
; CHECK: ldrex
; CHECK: add
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_add_4
- ; CHECK-M0: bl ___sync_fetch_and_add_4
+ ; CHECK-T1: bl ___sync_fetch_and_add_4
; CHECK-BAREMETAL: add
; CHECK-BAREMETAL-NOT: __sync
%2 = atomicrmw add i32* %val2, i32 1 monotonic
@@ -56,8 +53,7 @@ entry:
; CHECK: ldrex
; CHECK: sub
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_sub_4
- ; CHECK-M0: bl ___sync_fetch_and_sub_4
+ ; CHECK-T1: bl ___sync_fetch_and_sub_4
; CHECK-BAREMETAL: sub
; CHECK-BAREMETAL-NOT: __sync
%3 = atomicrmw sub i32* %val2, i32 1 monotonic
@@ -65,8 +61,7 @@ entry:
; CHECK: ldrex
; CHECK: and
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_and_4
- ; CHECK-M0: bl ___sync_fetch_and_and_4
+ ; CHECK-T1: bl ___sync_fetch_and_and_4
; CHECK-BAREMETAL: and
; CHECK-BAREMETAL-NOT: __sync
%4 = atomicrmw and i32* %andt, i32 4080 monotonic
@@ -74,8 +69,7 @@ entry:
; CHECK: ldrex
; CHECK: or
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_or_4
- ; CHECK-M0: bl ___sync_fetch_and_or_4
+ ; CHECK-T1: bl ___sync_fetch_and_or_4
; CHECK-BAREMETAL: or
; CHECK-BAREMETAL-NOT: __sync
%5 = atomicrmw or i32* %ort, i32 4080 monotonic
@@ -83,8 +77,7 @@ entry:
; CHECK: ldrex
; CHECK: eor
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_xor_4
- ; CHECK-M0: bl ___sync_fetch_and_xor_4
+ ; CHECK-T1: bl ___sync_fetch_and_xor_4
; CHECK-BAREMETAL: eor
; CHECK-BAREMETAL-NOT: __sync
%6 = atomicrmw xor i32* %xort, i32 4080 monotonic
@@ -92,8 +85,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_min_4
- ; CHECK-M0: bl ___sync_fetch_and_min_4
+ ; CHECK-T1: bl ___sync_fetch_and_min_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%7 = atomicrmw min i32* %val2, i32 16 monotonic
@@ -102,8 +94,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_min_4
- ; CHECK-M0: bl ___sync_fetch_and_min_4
+ ; CHECK-T1: bl ___sync_fetch_and_min_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%8 = atomicrmw min i32* %val2, i32 %neg monotonic
@@ -111,8 +102,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_max_4
- ; CHECK-M0: bl ___sync_fetch_and_max_4
+ ; CHECK-T1: bl ___sync_fetch_and_max_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%9 = atomicrmw max i32* %val2, i32 1 monotonic
@@ -120,8 +110,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_max_4
- ; CHECK-M0: bl ___sync_fetch_and_max_4
+ ; CHECK-T1: bl ___sync_fetch_and_max_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%10 = atomicrmw max i32* %val2, i32 0 monotonic
@@ -129,8 +118,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_4
- ; CHECK-M0: bl ___sync_fetch_and_umin_4
+ ; CHECK-T1: bl ___sync_fetch_and_umin_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%11 = atomicrmw umin i32* %val2, i32 16 monotonic
@@ -139,8 +127,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_4
- ; CHECK-M0: bl ___sync_fetch_and_umin_4
+ ; CHECK-T1: bl ___sync_fetch_and_umin_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%12 = atomicrmw umin i32* %val2, i32 %uneg monotonic
@@ -148,8 +135,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_4
- ; CHECK-M0: bl ___sync_fetch_and_umax_4
+ ; CHECK-T1: bl ___sync_fetch_and_umax_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%13 = atomicrmw umax i32* %val2, i32 1 monotonic
@@ -157,8 +143,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_4
- ; CHECK-M0: bl ___sync_fetch_and_umax_4
+ ; CHECK-T1: bl ___sync_fetch_and_umax_4
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%14 = atomicrmw umax i32* %val2, i32 0 monotonic
@@ -175,8 +160,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_2
- ; CHECK-M0: bl ___sync_fetch_and_umin_2
+ ; CHECK-T1: bl ___sync_fetch_and_umin_2
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%0 = atomicrmw umin i16* %val, i16 16 monotonic
@@ -185,8 +169,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_2
- ; CHECK-M0: bl ___sync_fetch_and_umin_2
+ ; CHECK-T1: bl ___sync_fetch_and_umin_2
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%1 = atomicrmw umin i16* %val, i16 %uneg monotonic
@@ -194,8 +177,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_2
- ; CHECK-M0: bl ___sync_fetch_and_umax_2
+ ; CHECK-T1: bl ___sync_fetch_and_umax_2
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%2 = atomicrmw umax i16* %val, i16 1 monotonic
@@ -203,8 +185,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_2
- ; CHECK-M0: bl ___sync_fetch_and_umax_2
+ ; CHECK-T1: bl ___sync_fetch_and_umax_2
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%3 = atomicrmw umax i16* %val, i16 0 monotonic
@@ -220,8 +201,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_1
- ; CHECK-M0: bl ___sync_fetch_and_umin_1
+ ; CHECK-T1: bl ___sync_fetch_and_umin_1
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%0 = atomicrmw umin i8* %val, i8 16 monotonic
@@ -229,8 +209,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umin_1
- ; CHECK-M0: bl ___sync_fetch_and_umin_1
+ ; CHECK-T1: bl ___sync_fetch_and_umin_1
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%uneg = sub i8 0, 1
@@ -239,8 +218,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_1
- ; CHECK-M0: bl ___sync_fetch_and_umax_1
+ ; CHECK-T1: bl ___sync_fetch_and_umax_1
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%2 = atomicrmw umax i8* %val, i8 1 monotonic
@@ -248,8 +226,7 @@ entry:
; CHECK: ldrex
; CHECK: cmp
; CHECK: strex
- ; CHECK-T1: blx ___sync_fetch_and_umax_1
- ; CHECK-M0: bl ___sync_fetch_and_umax_1
+ ; CHECK-T1: bl ___sync_fetch_and_umax_1
; CHECK-BAREMETAL: cmp
; CHECK-BAREMETAL-NOT: __sync
%3 = atomicrmw umax i8* %val, i8 0 monotonic
@@ -272,31 +249,37 @@ define i32 @test_cmpxchg_fail_order(i32 *%addr, i32 %desired, i32 %new) {
%pair = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst monotonic
%oldval = extractvalue { i32, i1 } %pair, 0
-; CHECK-ARMV7: dmb ish
-; CHECK-ARMV7: [[LOOP_BB:\.?LBB[0-9]+_1]]:
; CHECK-ARMV7: ldrex [[OLDVAL:r[0-9]+]], [r[[ADDR:[0-9]+]]]
; CHECK-ARMV7: cmp [[OLDVAL]], r1
; CHECK-ARMV7: bne [[FAIL_BB:\.?LBB[0-9]+_[0-9]+]]
+; CHECK-ARMV7: dmb ish
+; CHECK-ARMV7: [[LOOP_BB:\.?LBB.*]]:
; CHECK-ARMV7: strex [[SUCCESS:r[0-9]+]], r2, [r[[ADDR]]]
; CHECK-ARMV7: cmp [[SUCCESS]], #0
-; CHECK-ARMV7: bne [[LOOP_BB]]
-; CHECK-ARMV7: dmb ish
-; CHECK-ARMV7: bx lr
+; CHECK-ARMV7: beq [[SUCCESS_BB:\.?LBB.*]]
+; CHECK-ARMV7: ldrex [[OLDVAL]], [r[[ADDR]]]
+; CHECK-ARMV7: cmp [[OLDVAL]], r1
+; CHECK-ARMV7: beq [[LOOP_BB]]
; CHECK-ARMV7: [[FAIL_BB]]:
; CHECK-ARMV7: clrex
; CHECK-ARMV7: bx lr
+; CHECK-ARMV7: [[SUCCESS_BB]]:
+; CHECK-ARMV7: dmb ish
+; CHECK-ARMV7: bx lr
-; CHECK-T2: dmb ish
-; CHECK-T2: [[LOOP_BB:\.?LBB[0-9]+_1]]:
; CHECK-T2: ldrex [[OLDVAL:r[0-9]+]], [r[[ADDR:[0-9]+]]]
; CHECK-T2: cmp [[OLDVAL]], r1
-; CHECK-T2: clrexne
-; CHECK-T2: bxne lr
+; CHECK-T2: bne [[FAIL_BB:\.?LBB.*]]
+; CHECK-T2: dmb ish
+; CHECK-T2: [[LOOP_BB:\.?LBB.*]]:
; CHECK-T2: strex [[SUCCESS:r[0-9]+]], r2, [r[[ADDR]]]
; CHECK-T2: cmp [[SUCCESS]], #0
; CHECK-T2: dmbeq ish
; CHECK-T2: bxeq lr
-; CHECK-T2: b [[LOOP_BB]]
+; CHECK-T2: ldrex [[OLDVAL]], [r[[ADDR]]]
+; CHECK-T2: cmp [[OLDVAL]], r1
+; CHECK-T2: beq [[LOOP_BB]]
+; CHECK-T2: clrex
ret i32 %oldval
}
@@ -336,8 +319,8 @@ define i32 @load_load_add_acquire(i32* %mem1, i32* %mem2) nounwind {
; CHECK: dmb
; CHECK: add r0,
-; CHECK-M0: ___sync_val_compare_and_swap_4
-; CHECK-M0: ___sync_val_compare_and_swap_4
+; CHECK-T1: ___sync_val_compare_and_swap_4
+; CHECK-T1: ___sync_val_compare_and_swap_4
; CHECK-BAREMETAL: ldr {{r[0-9]}}, [r0]
; CHECK-BAREMETAL-NOT: dmb
@@ -358,8 +341,8 @@ define void @store_store_release(i32* %mem1, i32 %val1, i32* %mem2, i32 %val2) {
; CHECK: dmb
; CHECK: str r3, [r2]
-; CHECK-M0: ___sync_lock_test_and_set
-; CHECK-M0: ___sync_lock_test_and_set
+; CHECK-T1: ___sync_lock_test_and_set
+; CHECK-T1: ___sync_lock_test_and_set
; CHECK-BAREMETAL-NOT: dmb
; CHECK-BAREMTEAL: str r1, [r0]
@@ -379,9 +362,9 @@ define void @load_fence_store_monotonic(i32* %mem1, i32* %mem2) {
; CHECK: dmb
; CHECK: str [[R0]], [r1]
-; CHECK-M0: ldr [[R0:r[0-9]]], [r0]
-; CHECK-M0: dmb
-; CHECK-M0: str [[R0]], [r1]
+; CHECK-T1: ldr [[R0:r[0-9]]], [{{r[0-9]+}}]
+; CHECK-T1: {{dmb|bl ___sync_synchronize}}
+; CHECK-T1: str [[R0]], [{{r[0-9]+}}]
; CHECK-BAREMETAL: ldr [[R0:r[0-9]]], [r0]
; CHECK-BAREMETAL-NOT: dmb
diff --git a/test/CodeGen/ARM/atomic-ops-v8.ll b/test/CodeGen/ARM/atomic-ops-v8.ll
index efdb75b63222..77b850bd617b 100644
--- a/test/CodeGen/ARM/atomic-ops-v8.ll
+++ b/test/CodeGen/ARM/atomic-ops-v8.ll
@@ -667,19 +667,14 @@ define void @test_atomic_load_min_i64(i64 %offset) nounwind {
; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
-; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
-; CHECK-ARM-LE: cmp [[OLD1]], r0
-; CHECK-ARM-LE: movwls [[LOCARRY]], #1
-; CHECK-ARM-LE: cmp [[OLD2]], r1
-; CHECK-ARM-LE: movwle [[HICARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD2]], r1
-; CHECK-ARM-BE: movwls [[LOCARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD1]], r0
-; CHECK-ARM-BE: movwle [[HICARRY]], #1
-; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
-; CHECK-ARM: cmp [[HICARRY]], #0
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
+; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
+; CHECK-ARM: movwge [[CMP:r[0-9]+|lr]], #1
+; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
; CHECK-ARM: movne [[MINHI]], [[OLD2]]
; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
; CHECK-ARM: movne [[MINLO]], [[OLD1]]
@@ -785,19 +780,14 @@ define void @test_atomic_load_max_i64(i64 %offset) nounwind {
; CHECK: ldrexd [[OLD1:r[0-9]+]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
-; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
-; CHECK-ARM-LE: cmp [[OLD1]], r0
-; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
-; CHECK-ARM-LE: cmp [[OLD2]], r1
-; CHECK-ARM-LE: movwgt [[HICARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD2]], r1
-; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD1]], r0
-; CHECK-ARM-BE: movwgt [[HICARRY]], #1
-; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
-; CHECK-ARM: cmp [[HICARRY]], #0
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
+; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
+; CHECK-ARM: movwlt [[CMP:r[0-9]+|lr]], #1
+; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
; CHECK-ARM: movne [[MINHI]], [[OLD2]]
; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
; CHECK-ARM: movne [[MINLO]], [[OLD1]]
@@ -903,19 +893,14 @@ define void @test_atomic_load_umin_i64(i64 %offset) nounwind {
; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
-; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
-; CHECK-ARM-LE: cmp [[OLD1]], r0
-; CHECK-ARM-LE: movwls [[LOCARRY]], #1
-; CHECK-ARM-LE: cmp [[OLD2]], r1
-; CHECK-ARM-LE: movwls [[HICARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD2]], r1
-; CHECK-ARM-BE: movwls [[LOCARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD1]], r0
-; CHECK-ARM-BE: movwls [[HICARRY]], #1
-; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
-; CHECK-ARM: cmp [[HICARRY]], #0
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
+; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
+; CHECK-ARM: movwhs [[CMP:r[0-9]+|lr]], #1
+; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
; CHECK-ARM: movne [[MINHI]], [[OLD2]]
; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
; CHECK-ARM: movne [[MINLO]], [[OLD1]]
@@ -1021,19 +1006,14 @@ define void @test_atomic_load_umax_i64(i64 %offset) nounwind {
; CHECK: ldaexd [[OLD1:r[0-9]+|lr]], [[OLD2:r[0-9]+|lr]], [r[[ADDR]]]
; r0, r1 below is a reasonable guess but could change: it certainly comes into the
; function there.
-; CHECK-ARM: mov [[LOCARRY:r[0-9]+|lr]], #0
-; CHECK-ARM: mov [[HICARRY:r[0-9]+|lr]], #0
-; CHECK-ARM-LE: cmp [[OLD1]], r0
-; CHECK-ARM-LE: movwhi [[LOCARRY]], #1
-; CHECK-ARM-LE: cmp [[OLD2]], r1
-; CHECK-ARM-LE: movwhi [[HICARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD2]], r1
-; CHECK-ARM-BE: movwhi [[LOCARRY]], #1
-; CHECK-ARM-BE: cmp [[OLD1]], r0
-; CHECK-ARM-BE: movwhi [[HICARRY]], #1
-; CHECK-ARM: moveq [[HICARRY]], [[LOCARRY]]
-; CHECK-ARM: cmp [[HICARRY]], #0
; CHECK-ARM: mov [[MINHI:r[0-9]+]], r1
+; CHECK-ARM-LE: subs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM-LE: sbcs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: subs {{[^,]+}}, r1, [[OLD2]]
+; CHECK-ARM-BE: sbcs {{[^,]+}}, r0, [[OLD1]]
+; CHECK-ARM: mov [[CMP:r[0-9]+|lr]], #0
+; CHECK-ARM: movwlo [[CMP:r[0-9]+|lr]], #1
+; CHECK-ARM: cmp [[CMP:r[0-9]+|lr]], #0
; CHECK-ARM: movne [[MINHI]], [[OLD2]]
; CHECK-ARM: mov [[MINLO:r[0-9]+]], r0
; CHECK-ARM: movne [[MINLO]], [[OLD1]]
diff --git a/test/CodeGen/ARM/bfx.ll b/test/CodeGen/ARM/bfx.ll
index edb0c1a5a54a..629060218e43 100644
--- a/test/CodeGen/ARM/bfx.ll
+++ b/test/CodeGen/ARM/bfx.ll
@@ -51,3 +51,19 @@ entry:
%add7 = add i32 %add, %2
ret i32 %add7
}
+
+define i32 @ubfx3(i32 %a) {
+; CHECK: ubfx3
+; CHECK: ubfx r0, r0, #11, #1
+ %t1 = and i32 %a, 2048
+ %t2 = lshr i32 %t1, 11
+ ret i32 %t2
+}
+
+define i32 @ubfx4(i32 %a) {
+; CHECK: ubfx4
+; CHECK: ubfx r0, r0, #7, #3
+ %t1 = and i32 %a, 896
+ %t2 = lshr i32 %t1, 7
+ ret i32 %t2
+}
diff --git a/test/CodeGen/ARM/build-attributes-encoding.s b/test/CodeGen/ARM/build-attributes-encoding.s
index 29f13f09d319..5649726c12bb 100644
--- a/test/CodeGen/ARM/build-attributes-encoding.s
+++ b/test/CodeGen/ARM/build-attributes-encoding.s
@@ -54,6 +54,9 @@
// Tag_DIV_use (=44)
.eabi_attribute 44, 2
+// Tag_DSP_extension (=46)
+.eabi_attribute 46, 1
+
// Tag_Virtualization_use (=68)
.eabi_attribute 68, 3
@@ -71,15 +74,15 @@
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x0
// CHECK-NEXT: Offset: 0x34
-// CHECK-NEXT: Size: 71
+// CHECK-NEXT: Size: 73
// CHECK-NEXT: Link: 0
// CHECK-NEXT: Info: 0
// CHECK-NEXT: AddressAlignment: 1
// CHECK-NEXT: EntrySize: 0
// CHECK-NEXT: SectionData (
-// CHECK-NEXT: 0000: 41460000 00616561 62690001 3C000000
+// CHECK-NEXT: 0000: 41480000 00616561 62690001 3E000000
// CHECK-NEXT: 0010: 05636F72 7465782D 61380006 0A074108
// CHECK-NEXT: 0020: 0109020A 030C0214 01150117 01180119
-// CHECK-NEXT: 0030: 011B001C 0124012A 012C0244 036EA001
-// CHECK-NEXT: 0040: 81013100 FA0101
+// CHECK-NEXT: 0030: 011B001C 0124012A 012C022E 0144036E
+// CHECK-NEXT: 0040: A0018101 3100FA01 01
// CHECK-NEXT: )
diff --git a/test/CodeGen/ARM/build-attributes.ll b/test/CodeGen/ARM/build-attributes.ll
index a74b3e441a13..b3b39a0d550f 100644
--- a/test/CodeGen/ARM/build-attributes.ll
+++ b/test/CodeGen/ARM/build-attributes.ll
@@ -27,12 +27,21 @@
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mattr=-fp-armv8,-crypto | FileCheck %s --check-prefix=V8-NEON
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mattr=-crypto | FileCheck %s --check-prefix=V8-FPARMv8-NEON
; RUN: llc < %s -mtriple=armv8-linux-gnueabi | FileCheck %s --check-prefix=V8-FPARMv8-NEON-CRYPTO
+; RUN: llc < %s -mtriple=thumbv8m.base-linux-gnueabi | FileCheck %s --check-prefix=V8MBASELINE
+; RUN: llc < %s -mtriple=thumbv8m.main-linux-gnueabi | FileCheck %s --check-prefix=V8MMAINLINE
+; RUN: llc < %s -mtriple=thumbv8m.main-linux-gnueabi -mattr=+dsp | FileCheck %s --check-prefix=V8MMAINLINE_DSP
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 | FileCheck %s --check-prefix=CORTEX-A5-DEFAULT
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A5-DEFAULT-FAST
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-neon,+d16 | FileCheck %s --check-prefix=CORTEX-A5-NONEON
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-A5-NOFPU
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A5-NOFPU-FAST
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=soft | FileCheck %s --check-prefix=CORTEX-A8-SOFT
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=soft -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A8-SOFT-FAST
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=hard | FileCheck %s --check-prefix=CORTEX-A8-HARD
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=hard -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A8-HARD-FAST
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=soft | FileCheck %s --check-prefix=CORTEX-A8-SOFT
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -float-abi=soft | FileCheck %s --check-prefix=CORTEX-A9-SOFT
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -float-abi=soft -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A9-SOFT-FAST
; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -float-abi=hard | FileCheck %s --check-prefix=CORTEX-A9-HARD
@@ -96,6 +105,12 @@
; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r7 | FileCheck %s --check-prefix=CORTEX-R7
; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r7 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-R7-FAST
; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r7 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
+; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r8 | FileCheck %s --check-prefix=CORTEX-R8
+; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r8 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-R8-FAST
+; RUN: llc < %s -mtriple=armv7r-linux-gnueabi -mcpu=cortex-r8 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
+; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a32 | FileCheck %s --check-prefix=CORTEX-A32
+; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a32 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A32-FAST
+; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a32 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a35 | FileCheck %s --check-prefix=CORTEX-A35
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a35 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A35-FAST
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a35 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
@@ -108,6 +123,7 @@
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a72 | FileCheck %s --check-prefix=CORTEX-A72
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a72 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A72-FAST
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a72 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
+; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=cortex-a73 | FileCheck %s --check-prefix=CORTEX-A73
; RUN: llc < %s -mtriple=armv8.1a-linux-gnueabi | FileCheck %s --check-prefix=GENERIC-ARMV8_1-A
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=exynos-m1 | FileCheck %s --check-prefix=EXYNOS-M1
; RUN: llc < %s -mtriple=armv8-linux-gnueabi -mcpu=exynos-m1 -enable-unsafe-fp-math -disable-fp-elim -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=EXYNOS-M1-FAST
@@ -124,7 +140,6 @@
; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=+vfp4,,+d16,-neon | FileCheck %s --check-prefix=CORTEX-A7-FPUV4
; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=pic | FileCheck %s --check-prefix=RELOC-PIC
; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=static | FileCheck %s --check-prefix=RELOC-OTHER
-; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=default | FileCheck %s --check-prefix=RELOC-OTHER
; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=dynamic-no-pic | FileCheck %s --check-prefix=RELOC-OTHER
; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align | FileCheck %s --check-prefix=RELOC-OTHER
; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align | FileCheck %s --check-prefix=PCS-R9-USE
@@ -135,6 +150,8 @@
; RUN: llc < %s -mtriple=armv8.1a-none-linux-gnueabi -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
; RUN: llc < %s -mtriple=armv8.1a-none-linux-gnueabi | FileCheck %s --check-prefix=NO-STRICT-ALIGN
; ARMv8a (AArch32)
+; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi -mcpu=cortex-a32 | FileCheck %s --check-prefix=NO-STRICT-ALIGN
+; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi -mcpu=cortex-a32 -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi -mcpu=cortex-a35 | FileCheck %s --check-prefix=NO-STRICT-ALIGN
; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi -mcpu=cortex-a35 -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
; RUN: llc < %s -mtriple=armv8-none-linux-gnueabi -mcpu=cortex-a57 | FileCheck %s --check-prefix=NO-STRICT-ALIGN
@@ -373,6 +390,31 @@
; V8-FPARMv8-NEON-CRYPTO: .fpu crypto-neon-fp-armv8
; V8-FPARMv8-NEON-CRYPTO: .eabi_attribute 12, 3
+; V8MBASELINE: .syntax unified
+; '6' is Tag_CPU_arch, '16' is ARM v8-M Baseline
+; V8MBASELINE: .eabi_attribute 6, 16
+; '7' is Tag_CPU_arch_profile, '77' is 'M'
+; V8MBASELINE: .eabi_attribute 7, 77
+; '8' is Tag_ARM_ISA_use
+; V8MBASELINE: .eabi_attribute 8, 0
+; '9' is Tag_Thumb_ISA_use
+; V8MBASELINE: .eabi_attribute 9, 3
+
+; V8MMAINLINE: .syntax unified
+; '6' is Tag_CPU_arch, '17' is ARM v8-M Mainline
+; V8MMAINLINE: .eabi_attribute 6, 17
+; V8MMAINLINE: .eabi_attribute 7, 77
+; V8MMAINLINE: .eabi_attribute 8, 0
+; V8MMAINLINE: .eabi_attribute 9, 3
+; V8MMAINLINE_DSP-NOT: .eabi_attribute 46
+
+; V8MMAINLINE_DSP: .syntax unified
+; V8MBASELINE_DSP: .eabi_attribute 6, 17
+; V8MBASELINE_DSP: .eabi_attribute 7, 77
+; V8MMAINLINE_DSP: .eabi_attribute 8, 0
+; V8MMAINLINE_DSP: .eabi_attribute 9, 3
+; V8MMAINLINE_DSP: .eabi_attribute 46, 1
+
; Tag_CPU_unaligned_access
; NO-STRICT-ALIGN: .eabi_attribute 34, 1
; STRICT-ALIGN: .eabi_attribute 34, 0
@@ -462,6 +504,9 @@
; CORTEX-A7-NOFPU: .eabi_attribute 44, 2
; CORTEX-A7-FPUV4: .eabi_attribute 44, 2
+; Tag_DSP_extension
+; CORTEX-A7-CHECK-NOT: .eabi_attribute 46
+
; Tag_Virtualization_use
; CORTEX-A7-CHECK: .eabi_attribute 68, 3
; CORTEX-A7-NOFPU: .eabi_attribute 68, 3
@@ -486,7 +531,7 @@
; CORTEX-A5-DEFAULT: .eabi_attribute 68, 1
; CORTEX-A5-DEFAULT-FAST-NOT: .eabi_attribute 19
-;; The A5 defaults to a VFPv4 FPU, so it flushed preserving sign when -ffast-math
+;; The A5 defaults to a VFPv4 FPU, so it flushed preserving the sign when -ffast-math
;; is given.
; CORTEX-A5-DEFAULT-FAST: .eabi_attribute 20, 2
; CORTEX-A5-DEFAULT-FAST-NOT: .eabi_attribute 21
@@ -543,6 +588,28 @@
; CORTEX-A5-NOFPU-FAST-NOT: .eabi_attribute 22
; CORTEX-A5-NOFPU-FAST: .eabi_attribute 23, 1
+; CORTEX-A8-SOFT: .cpu cortex-a8
+; CORTEX-A8-SOFT: .eabi_attribute 6, 10
+; CORTEX-A8-SOFT: .eabi_attribute 7, 65
+; CORTEX-A8-SOFT: .eabi_attribute 8, 1
+; CORTEX-A8-SOFT: .eabi_attribute 9, 2
+; CORTEX-A8-SOFT: .fpu neon
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 19
+;; We default to IEEE 754 compliance
+; CORTEX-A8-SOFT: .eabi_attribute 20, 1
+; CORTEX-A8-SOFT: .eabi_attribute 21, 1
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 22
+; CORTEX-A8-SOFT: .eabi_attribute 23, 3
+; CORTEX-A8-SOFT: .eabi_attribute 24, 1
+; CORTEX-A8-SOFT: .eabi_attribute 25, 1
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 27
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 28
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 36, 1
+; CORTEX-A8-SOFT: .eabi_attribute 38, 1
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 42, 1
+; CORTEX-A8-SOFT-NOT: .eabi_attribute 44
+; CORTEX-A8-SOFT: .eabi_attribute 68, 1
+
; CORTEX-A9-SOFT: .cpu cortex-a9
; CORTEX-A9-SOFT: .eabi_attribute 6, 10
; CORTEX-A9-SOFT: .eabi_attribute 7, 65
@@ -565,14 +632,39 @@
; CORTEX-A9-SOFT-NOT: .eabi_attribute 44
; CORTEX-A9-SOFT: .eabi_attribute 68, 1
+; CORTEX-A8-SOFT-FAST-NOT: .eabi_attribute 19
; CORTEX-A9-SOFT-FAST-NOT: .eabi_attribute 19
-;; The A9 defaults to a VFPv3 FPU, so it flushes preseving sign when
+;; The A9 defaults to a VFPv3 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
+; CORTEX-A8-SOFT-FAST: .eabi_attribute 20, 2
; CORTEX-A9-SOFT-FAST: .eabi_attribute 20, 2
; CORTEX-A5-SOFT-FAST-NOT: .eabi_attribute 21
; CORTEX-A5-SOFT-FAST-NOT: .eabi_attribute 22
; CORTEX-A5-SOFT-FAST: .eabi_attribute 23, 1
+; CORTEX-A8-HARD: .cpu cortex-a8
+; CORTEX-A8-HARD: .eabi_attribute 6, 10
+; CORTEX-A8-HARD: .eabi_attribute 7, 65
+; CORTEX-A8-HARD: .eabi_attribute 8, 1
+; CORTEX-A8-HARD: .eabi_attribute 9, 2
+; CORTEX-A8-HARD: .fpu neon
+; CORTEX-A8-HARD-NOT: .eabi_attribute 19
+;; We default to IEEE 754 compliance
+; CORTEX-A8-HARD: .eabi_attribute 20, 1
+; CORTEX-A8-HARD: .eabi_attribute 21, 1
+; CORTEX-A8-HARD-NOT: .eabi_attribute 22
+; CORTEX-A8-HARD: .eabi_attribute 23, 3
+; CORTEX-A8-HARD: .eabi_attribute 24, 1
+; CORTEX-A8-HARD: .eabi_attribute 25, 1
+; CORTEX-A8-HARD-NOT: .eabi_attribute 27
+; CORTEX-A8-HARD: .eabi_attribute 28, 1
+; CORTEX-A8-HARD-NOT: .eabi_attribute 36, 1
+; CORTEX-A8-HARD: .eabi_attribute 38, 1
+; CORTEX-A8-HARD-NOT: .eabi_attribute 42, 1
+; CORTEX-A8-HARD: .eabi_attribute 68, 1
+
+
+
; CORTEX-A9-HARD: .cpu cortex-a9
; CORTEX-A9-HARD: .eabi_attribute 6, 10
; CORTEX-A9-HARD: .eabi_attribute 7, 65
@@ -594,8 +686,16 @@
; CORTEX-A9-HARD: .eabi_attribute 42, 1
; CORTEX-A9-HARD: .eabi_attribute 68, 1
+; CORTEX-A8-HARD-FAST-NOT: .eabi_attribute 19
+;; The A8 defaults to a VFPv3 FPU, so it flushes preserving the sign when
+;; -ffast-math is specified.
+; CORTEX-A8-HARD-FAST: .eabi_attribute 20, 2
+; CORTEX-A8-HARD-FAST-NOT: .eabi_attribute 21
+; CORTEX-A8-HARD-FAST-NOT: .eabi_attribute 22
+; CORTEX-A8-HARD-FAST: .eabi_attribute 23, 1
+
; CORTEX-A9-HARD-FAST-NOT: .eabi_attribute 19
-;; The A9 defaults to a VFPv3 FPU, so it flushes preseving sign when
+;; The A9 defaults to a VFPv3 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-A9-HARD-FAST: .eabi_attribute 20, 2
; CORTEX-A9-HARD-FAST-NOT: .eabi_attribute 21
@@ -621,7 +721,7 @@
; CORTEX-A12-DEFAULT: .eabi_attribute 68, 3
; CORTEX-A12-DEFAULT-FAST-NOT: .eabi_attribute 19
-;; The A12 defaults to a VFPv3 FPU, so it flushes preseving sign when
+;; The A12 defaults to a VFPv3 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-A12-DEFAULT-FAST: .eabi_attribute 20, 2
; CORTEX-A12-HARD-FAST-NOT: .eabi_attribute 21
@@ -678,7 +778,7 @@
; CORTEX-A15: .eabi_attribute 68, 3
; CORTEX-A15-FAST-NOT: .eabi_attribute 19
-;; The A15 defaults to a VFPv3 FPU, so it flushes preseving sign when
+;; The A15 defaults to a VFPv3 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-A15-FAST: .eabi_attribute 20, 2
; CORTEX-A15-FAST-NOT: .eabi_attribute 21
@@ -704,7 +804,7 @@
; CORTEX-A17-DEFAULT: .eabi_attribute 68, 3
; CORTEX-A17-FAST-NOT: .eabi_attribute 19
-;; The A17 defaults to a VFPv3 FPU, so it flushes preseving sign when
+;; The A17 defaults to a VFPv3 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-A17-FAST: .eabi_attribute 20, 2
; CORTEX-A17-FAST-NOT: .eabi_attribute 21
@@ -950,7 +1050,7 @@
; CORTEX-M4-SOFT-NOT: .eabi_attribute 68
; CORTEX-M4-SOFT-FAST-NOT: .eabi_attribute 19
-;; The M4 defaults to a VFPv4 FPU, so it flushes preseving sign when
+;; The M4 defaults to a VFPv4 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-M4-SOFT-FAST: .eabi_attribute 20, 2
; CORTEX-M4-SOFT-FAST-NOT: .eabi_attribute 21
@@ -980,7 +1080,7 @@
; CORTEX-M4-HARD-NOT: .eabi_attribute 68
; CORTEX-M4-HARD-FAST-NOT: .eabi_attribute 19
-;; The M4 defaults to a VFPv4 FPU, so it flushes preseving sign when
+;; The M4 defaults to a VFPv4 FPU, so it flushes preserving the sign when
;; -ffast-math is specified.
; CORTEX-M4-HARD-FAST: .eabi_attribute 20, 2
; CORTEX-M4-HARD-FAST-NOT: .eabi_attribute 21
@@ -1100,7 +1200,7 @@
; CORTEX-R7: .eabi_attribute 7, 82
; CORTEX-R7: .eabi_attribute 8, 1
; CORTEX-R7: .eabi_attribute 9, 2
-; CORTEX-R7: .fpu vfpv3xd
+; CORTEX-R7: .fpu vfpv3-d16-fp16
; CORTEX-R7-NOT: .eabi_attribute 19
;; We default to IEEE 754 compliance
; CORTEX-R7: .eabi_attribute 20, 1
@@ -1109,7 +1209,6 @@
; CORTEX-R7: .eabi_attribute 23, 3
; CORTEX-R7: .eabi_attribute 24, 1
; CORTEX-R7: .eabi_attribute 25, 1
-; CORTEX-R7: .eabi_attribute 27, 1
; CORTEX-R7-NOT: .eabi_attribute 28
; CORTEX-R7: .eabi_attribute 36, 1
; CORTEX-R7: .eabi_attribute 38, 1
@@ -1124,6 +1223,64 @@
; CORTEX-R7-FAST-NOT: .eabi_attribute 22
; CORTEX-R7-FAST: .eabi_attribute 23, 1
+; CORTEX-R8: .cpu cortex-r8
+; CORTEX-R8: .eabi_attribute 6, 10
+; CORTEX-R8: .eabi_attribute 7, 82
+; CORTEX-R8: .eabi_attribute 8, 1
+; CORTEX-R8: .eabi_attribute 9, 2
+; CORTEX-R8: .fpu vfpv3-d16-fp16
+; CORTEX-R8-NOT: .eabi_attribute 19
+;; We default to IEEE 754 compliance
+; CORTEX-R8: .eabi_attribute 20, 1
+; CORTEX-R8: .eabi_attribute 21, 1
+; CORTEX-R8-NOT: .eabi_attribute 22
+; CORTEX-R8: .eabi_attribute 23, 3
+; CORTEX-R8: .eabi_attribute 24, 1
+; CORTEX-R8: .eabi_attribute 25, 1
+; CORTEX-R8-NOT: .eabi_attribute 28
+; CORTEX-R8: .eabi_attribute 36, 1
+; CORTEX-R8: .eabi_attribute 38, 1
+; CORTEX-R8: .eabi_attribute 42, 1
+; CORTEX-R8: .eabi_attribute 44, 2
+; CORTEX-R8-NOT: .eabi_attribute 68
+
+; CORTEX-R8-FAST-NOT: .eabi_attribute 19
+;; The R8 has the VFPv3 FP unit, which always flushes preserving sign.
+; CORTEX-R8-FAST: .eabi_attribute 20, 2
+; CORTEX-R8-FAST-NOT: .eabi_attribute 21
+; CORTEX-R8-FAST-NOT: .eabi_attribute 22
+; CORTEX-R8-FAST: .eabi_attribute 23, 1
+
+; CORTEX-A32: .cpu cortex-a32
+; CORTEX-A32: .eabi_attribute 6, 14
+; CORTEX-A32: .eabi_attribute 7, 65
+; CORTEX-A32: .eabi_attribute 8, 1
+; CORTEX-A32: .eabi_attribute 9, 2
+; CORTEX-A32: .fpu crypto-neon-fp-armv8
+; CORTEX-A32: .eabi_attribute 12, 3
+; CORTEX-A32-NOT: .eabi_attribute 19
+;; We default to IEEE 754 compliance
+; CORTEX-A32: .eabi_attribute 20, 1
+; CORTEX-A32: .eabi_attribute 21, 1
+; CORTEX-A32-NOT: .eabi_attribute 22
+; CORTEX-A32: .eabi_attribute 23, 3
+; CORTEX-A32: .eabi_attribute 24, 1
+; CORTEX-A32: .eabi_attribute 25, 1
+; CORTEX-A32-NOT: .eabi_attribute 27
+; CORTEX-A32-NOT: .eabi_attribute 28
+; CORTEX-A32: .eabi_attribute 36, 1
+; CORTEX-A32: .eabi_attribute 38, 1
+; CORTEX-A32: .eabi_attribute 42, 1
+; CORTEX-A32-NOT: .eabi_attribute 44
+; CORTEX-A32: .eabi_attribute 68, 3
+
+; CORTEX-A32-FAST-NOT: .eabi_attribute 19
+;; The A32 has the ARMv8 FP unit, which always flushes preserving sign.
+; CORTEX-A32-FAST: .eabi_attribute 20, 2
+; CORTEX-A32-FAST-NOT: .eabi_attribute 21
+; CORTEX-A32-FAST-NOT: .eabi_attribute 22
+; CORTEX-A32-FAST: .eabi_attribute 23, 1
+
; CORTEX-A35: .cpu cortex-a35
; CORTEX-A35: .eabi_attribute 6, 14
; CORTEX-A35: .eabi_attribute 7, 65
@@ -1244,6 +1401,30 @@
; CORTEX-A72-FAST-NOT: .eabi_attribute 22
; CORTEX-A72-FAST: .eabi_attribute 23, 1
+; CORTEX-A73: .cpu cortex-a73
+; CORTEX-A73: .eabi_attribute 6, 14
+; CORTEX-A73: .eabi_attribute 7, 65
+; CORTEX-A73: .eabi_attribute 8, 1
+; CORTEX-A73: .eabi_attribute 9, 2
+; CORTEX-A73: .fpu crypto-neon-fp-armv8
+; CORTEX-A73: .eabi_attribute 12, 3
+; CORTEX-A73-NOT: .eabi_attribute 19
+;; We default to IEEE 754 compliance
+; CORTEX-A73: .eabi_attribute 20, 1
+; CORTEX-A73: .eabi_attribute 21, 1
+; CORTEX-A73-NOT: .eabi_attribute 22
+; CORTEX-A73: .eabi_attribute 23, 3
+; CORTEX-A73: .eabi_attribute 24, 1
+; CORTEX-A73: .eabi_attribute 25, 1
+; CORTEX-A73-NOT: .eabi_attribute 27
+; CORTEX-A73-NOT: .eabi_attribute 28
+; CORTEX-A73: .eabi_attribute 36, 1
+; CORTEX-A73: .eabi_attribute 38, 1
+; CORTEX-A73: .eabi_attribute 42, 1
+; CORTEX-A73-NOT: .eabi_attribute 44
+; CORTEX-A73: .eabi_attribute 14, 0
+; CORTEX-A73: .eabi_attribute 68, 3
+
; EXYNOS-M1: .cpu exynos-m1
; EXYNOS-M1: .eabi_attribute 6, 14
; EXYNOS-M1: .eabi_attribute 7, 65
diff --git a/test/CodeGen/ARM/byval_load_align.ll b/test/CodeGen/ARM/byval_load_align.ll
index 2c0910c71d2f..d00d926c7a05 100644
--- a/test/CodeGen/ARM/byval_load_align.ll
+++ b/test/CodeGen/ARM/byval_load_align.ll
@@ -7,7 +7,7 @@
; CHECK: ldr r2, [r[[REG]], #4]
; CHECK: ldr r3, [r[[REG]], #8]
; CHECK-NOT: ldm
-; CHECK: .align 1 @ @sID
+; CHECK: .p2align 1 @ @sID
%struct.ModuleID = type { [32 x i8], [32 x i8], i16 }
diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll
index 8821029520fe..53fa8920ec04 100644
--- a/test/CodeGen/ARM/call-tc.ll
+++ b/test/CodeGen/ARM/call-tc.ll
@@ -12,7 +12,7 @@ declare void @g(i32, i32, i32, i32)
define void @t1() {
; CHECKELF-LABEL: t1:
-; CHECKELF: bl g(PLT)
+; CHECKELF: bl g
call void @g( i32 1, i32 2, i32 3, i32 4 )
ret void
}
@@ -33,7 +33,7 @@ define void @t3() {
; CHECKV6-LABEL: t3:
; CHECKV6: b _t2
; CHECKELF-LABEL: t3:
-; CHECKELF: b t2(PLT)
+; CHECKELF: b t2
; CHECKT2D-LABEL: t3:
; CHECKT2D: b.w _t2
@@ -47,7 +47,7 @@ entry:
; CHECKV6-LABEL: t4:
; CHECKV6: b _sin
; CHECKELF-LABEL: t4:
-; CHECKELF: b sin(PLT)
+; CHECKELF: b sin
%0 = tail call double @sin(double %a) nounwind readonly ; <double> [#uses=1]
ret double %0
}
@@ -57,7 +57,7 @@ entry:
; CHECKV6-LABEL: t5:
; CHECKV6: b _sinf
; CHECKELF-LABEL: t5:
-; CHECKELF: b sinf(PLT)
+; CHECKELF: b sinf
%0 = tail call float @sinf(float %a) nounwind readonly ; <float> [#uses=1]
ret float %0
}
@@ -71,7 +71,7 @@ entry:
; CHECKV6-LABEL: t6:
; CHECKV6: b ___divsi3
; CHECKELF-LABEL: t6:
-; CHECKELF: b __aeabi_idiv(PLT)
+; CHECKELF: b __aeabi_idiv
%0 = sdiv i32 %a, %b
ret i32 %0
}
@@ -87,7 +87,7 @@ entry:
; CHECKT2D-NEXT: bne.w _foo
; CHECKT2D-NEXT: push
; CHECKT2D-NEXT: mov r7, sp
-; CHECKT2D-NEXT: blx _foo
+; CHECKT2D-NEXT: bl _foo
br i1 undef, label %bb, label %bb1.lr.ph
bb1.lr.ph:
@@ -150,8 +150,8 @@ declare i32 @c(i32)
define i32 @t9() nounwind {
; CHECKT2D-LABEL: t9:
-; CHECKT2D: blx __ZN9MutexLockC1Ev
-; CHECKT2D: blx __ZN9MutexLockD1Ev
+; CHECKT2D: bl __ZN9MutexLockC1Ev
+; CHECKT2D: bl __ZN9MutexLockD1Ev
; CHECKT2D: b.w ___divsi3
%lock = alloca %class.MutexLock, align 1
%1 = call %class.MutexLock* @_ZN9MutexLockC1Ev(%class.MutexLock* %lock)
@@ -170,7 +170,7 @@ declare %class.MutexLock* @_ZN9MutexLockD1Ev(%class.MutexLock*) unnamed_addr nou
; otherwise the call to floorf is lost.
define float @libcall_tc_test2(float* nocapture %a, float %b) {
; CHECKT2D-LABEL: libcall_tc_test2:
-; CHECKT2D: blx _floorf
+; CHECKT2D: bl _floorf
; CHECKT2D: b.w _truncf
%1 = load float, float* %a, align 4
%call = tail call float @floorf(float %1)
diff --git a/test/CodeGen/ARM/call.ll b/test/CodeGen/ARM/call.ll
index 87252a91e1b0..05ea556e234c 100644
--- a/test/CodeGen/ARM/call.ll
+++ b/test/CodeGen/ARM/call.ll
@@ -12,7 +12,7 @@
declare void @g(i32, i32, i32, i32)
define void @f() {
-; CHECKELF: PLT
+; CHECKELF: bl g
call void @g( i32 1, i32 2, i32 3, i32 4 )
ret void
}
diff --git a/test/CodeGen/ARM/carry.ll b/test/CodeGen/ARM/carry.ll
index 7ea9be2c61e6..558e2b0e43f7 100644
--- a/test/CodeGen/ARM/carry.ll
+++ b/test/CodeGen/ARM/carry.ll
@@ -11,9 +11,10 @@ entry:
define i64 @f2(i64 %a, i64 %b) {
; CHECK-LABEL: f2:
-; CHECK: adc r
-; CHECK: subs r
-; CHECK: sbc r
+; CHECK: lsl r
+; CHECK: orr r
+; CHECK: rsbs r
+; CHECK: sbc r
entry:
%tmp1 = shl i64 %a, 1
%tmp2 = sub i64 %tmp1, %b
diff --git a/test/CodeGen/ARM/cdp.ll b/test/CodeGen/ARM/cdp.ll
new file mode 100644
index 000000000000..99ec3b284462
--- /dev/null
+++ b/test/CodeGen/ARM/cdp.ll
@@ -0,0 +1,13 @@
+; RUN: not llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s
+; RUN: not llc < %s -march=thumb -mtriple=thumbv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s
+
+; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.cdp
+define void @cdp(i32 %a) #0 {
+ %a.addr = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ %1 = load i32, i32* %a.addr, align 4
+ call void @llvm.arm.cdp(i32 %1, i32 2, i32 3, i32 4, i32 5, i32 6)
+ ret void
+}
+
+declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind
diff --git a/test/CodeGen/ARM/cdp2.ll b/test/CodeGen/ARM/cdp2.ll
new file mode 100644
index 000000000000..c2a00d0fdd72
--- /dev/null
+++ b/test/CodeGen/ARM/cdp2.ll
@@ -0,0 +1,13 @@
+; RUN: not llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s
+; RUN: not llc < %s -march=thumb -mtriple=thumbv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s
+
+; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.cdp2
+define void @cdp2(i32 %a) #0 {
+ %a.addr = alloca i32, align 4
+ store i32 %a, i32* %a.addr, align 4
+ %1 = load i32, i32* %a.addr, align 4
+ call void @llvm.arm.cdp2(i32 %1, i32 2, i32 3, i32 4, i32 5, i32 6)
+ ret void
+}
+
+declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind
diff --git a/test/CodeGen/ARM/cmpxchg-O0.ll b/test/CodeGen/ARM/cmpxchg-O0.ll
new file mode 100644
index 000000000000..ec3005dd8ada
--- /dev/null
+++ b/test/CodeGen/ARM/cmpxchg-O0.ll
@@ -0,0 +1,113 @@
+; RUN: llc -verify-machineinstrs -mtriple=armv7-linux-gnu -O0 %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=thumbv8-linux-gnu -O0 %s -o - | FileCheck %s
+; RUN: llc -verify-machineinstrs -mtriple=thumbv6m-none-eabi -O0 %s -o - | FileCheck %s --check-prefix=CHECK-T1
+
+; CHECK-T1-NOT: ldrex
+; CHECK-T1-NOT: strex
+
+define { i8, i1 } @test_cmpxchg_8(i8* %addr, i8 %desired, i8 %new) nounwind {
+; CHECK-LABEL: test_cmpxchg_8:
+; CHECK: dmb ish
+; CHECK: uxtb [[DESIRED:r[0-9]+]], [[DESIRED]]
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK: ldrexb [[OLD:r[0-9]+]], [r0]
+; CHECK: cmp [[OLD]], [[DESIRED]]
+; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: strexb [[STATUS:r[0-9]+]], r2, [r0]
+; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
+; CHECK: bne [[RETRY]]
+; CHECK: [[DONE]]:
+; CHECK: cmp{{(\.w)?}} [[OLD]], [[DESIRED]]
+; CHECK: {{moveq|movweq}} {{r[0-9]+}}, #1
+; CHECK: dmb ish
+ %res = cmpxchg i8* %addr, i8 %desired, i8 %new seq_cst monotonic
+ ret { i8, i1 } %res
+}
+
+define { i16, i1 } @test_cmpxchg_16(i16* %addr, i16 %desired, i16 %new) nounwind {
+; CHECK-LABEL: test_cmpxchg_16:
+; CHECK: dmb ish
+; CHECK: uxth [[DESIRED:r[0-9]+]], [[DESIRED]]
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK: ldrexh [[OLD:r[0-9]+]], [r0]
+; CHECK: cmp [[OLD]], [[DESIRED]]
+; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: strexh [[STATUS:r[0-9]+]], r2, [r0]
+; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
+; CHECK: bne [[RETRY]]
+; CHECK: [[DONE]]:
+; CHECK: cmp{{(\.w)?}} [[OLD]], [[DESIRED]]
+; CHECK: {{moveq|movweq}} {{r[0-9]+}}, #1
+; CHECK: dmb ish
+ %res = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst monotonic
+ ret { i16, i1 } %res
+}
+
+define { i32, i1 } @test_cmpxchg_32(i32* %addr, i32 %desired, i32 %new) nounwind {
+; CHECK-LABEL: test_cmpxchg_32:
+; CHECK: dmb ish
+; CHECK-NOT: uxt
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK: ldrex [[OLD:r[0-9]+]], [r0]
+; CHECK: cmp [[OLD]], [[DESIRED]]
+; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: strex [[STATUS:r[0-9]+]], r2, [r0]
+; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
+; CHECK: bne [[RETRY]]
+; CHECK: [[DONE]]:
+; CHECK: cmp{{(\.w)?}} [[OLD]], [[DESIRED]]
+; CHECK: {{moveq|movweq}} {{r[0-9]+}}, #1
+; CHECK: dmb ish
+ %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst monotonic
+ ret { i32, i1 } %res
+}
+
+define { i64, i1 } @test_cmpxchg_64(i64* %addr, i64 %desired, i64 %new) nounwind {
+; CHECK-LABEL: test_cmpxchg_64:
+; CHECK: dmb ish
+; CHECK-NOT: uxt
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK: ldrexd [[OLDLO:r[0-9]+]], [[OLDHI:r[0-9]+]], [r0]
+; CHECK: cmp [[OLDLO]], r6
+; CHECK: sbcs{{(\.w)?}} [[STATUS:r[0-9]+]], [[OLDHI]], r7
+; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: strexd [[STATUS]], r4, r5, [r0]
+; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
+; CHECK: bne [[RETRY]]
+; CHECK: [[DONE]]:
+; CHECK: dmb ish
+ %res = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst monotonic
+ ret { i64, i1 } %res
+}
+
+define { i64, i1 } @test_nontrivial_args(i64* %addr, i64 %desired, i64 %new) {
+; CHECK-LABEL: test_nontrivial_args:
+; CHECK: dmb ish
+; CHECK-NOT: uxt
+; CHECK: [[RETRY:.LBB[0-9]+_[0-9]+]]:
+; CHECK: ldrexd [[OLDLO:r[0-9]+]], [[OLDHI:r[0-9]+]], [r0]
+; CHECK: cmp [[OLDLO]], {{r[0-9]+}}
+; CHECK: sbcs{{(\.w)?}} [[STATUS:r[0-9]+]], [[OLDHI]], {{r[0-9]+}}
+; CHECK: bne [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: strexd [[STATUS]], {{r[0-9]+}}, {{r[0-9]+}}, [r0]
+; CHECK: cmp{{(\.w)?}} [[STATUS]], #0
+; CHECK: bne [[RETRY]]
+; CHECK: [[DONE]]:
+; CHECK: dmb ish
+
+ %desired1 = add i64 %desired, 1
+ %new1 = add i64 %new, 1
+ %res = cmpxchg i64* %addr, i64 %desired1, i64 %new1 seq_cst seq_cst
+ ret { i64, i1 } %res
+}
+
+; The following used to trigger an assertion when creating a spill on thumb2
+; for a physreg with RC==GPRPairRegClass.
+; CHECK-LABEL: test_cmpxchg_spillbug:
+; CHECK: ldrexd
+; CHECK: strexd
+; CHECK: bne
+define void @test_cmpxchg_spillbug() {
+ %v = cmpxchg i64* undef, i64 undef, i64 undef seq_cst seq_cst
+ ret void
+}
diff --git a/test/CodeGen/ARM/cmpxchg-idioms.ll b/test/CodeGen/ARM/cmpxchg-idioms.ll
index 81e05acfef79..283202f0cc1f 100644
--- a/test/CodeGen/ARM/cmpxchg-idioms.ll
+++ b/test/CodeGen/ARM/cmpxchg-idioms.ll
@@ -3,26 +3,31 @@
define i32 @test_return(i32* %p, i32 %oldval, i32 %newval) {
; CHECK-LABEL: test_return:
-; CHECK: dmb ishst
-
-; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
; CHECK: cmp [[LOADED]], r1
; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
+; CHECK: dmb ishst
+
+; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: strex [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
-; CHECK: cmp [[STATUS]], #0
-; CHECK: bne [[LOOP]]
+; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
+; CHECK: ldrex [[LOADED]], [r0]
+; CHECK: cmp [[LOADED]], r1
+; CHECK: beq [[LOOP]]
+
+; CHECK: [[FAILED]]:
; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
+; CHECK: clrex
; CHECK: dmb ish
-; CHECK: movs r0, #1
+; CHECK: movs r0, #0
; CHECK: bx lr
-; CHECK: [[FAILED]]:
+; CHECK: [[SUCCESS]]:
; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
; CHECK: dmb ish
-; CHECK: movs r0, #0
+; CHECK: movs r0, #1
; CHECK: bx lr
%pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
@@ -34,26 +39,33 @@ define i32 @test_return(i32* %p, i32 %oldval, i32 %newval) {
define i1 @test_return_bool(i8* %value, i8 %oldValue, i8 %newValue) {
; CHECK-LABEL: test_return_bool:
-; CHECK: dmb ishst
; CHECK: uxtb [[OLDBYTE:r[0-9]+]], r1
-; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: ldrexb [[LOADED:r[0-9]+]], [r0]
; CHECK: cmp [[LOADED]], [[OLDBYTE]]
; CHECK: bne [[FAIL:LBB[0-9]+_[0-9]+]]
+; CHECK: dmb ishst
+
+; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: strexb [[STATUS:r[0-9]+]], {{r[0-9]+}}, [r0]
-; CHECK: cmp [[STATUS]], #0
-; CHECK: bne [[LOOP]]
+; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
+
+; CHECK: ldrexb [[LOADED]], [r0]
+; CHECK: cmp [[LOADED]], [[OLDBYTE]]
+; CHECK: beq [[LOOP]]
+
; FIXME: this eor is redundant. Need to teach DAG combine that.
-; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
-; CHECK: movs [[TMP:r[0-9]+]], #1
+; CHECK: [[FAIL]]:
+; CHECK: clrex
+; CHECK: movs [[TMP:r[0-9]+]], #0
; CHECK: eor r0, [[TMP]], #1
; CHECK: bx lr
-; CHECK: [[FAIL]]:
-; CHECK: movs [[TMP:r[0-9]+]], #0
+; CHECK: [[SUCCESS]]:
+; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
+; CHECK: movs [[TMP:r[0-9]+]], #1
; CHECK: eor r0, [[TMP]], #1
; CHECK: bx lr
@@ -67,26 +79,31 @@ define i1 @test_return_bool(i8* %value, i8 %oldValue, i8 %newValue) {
define void @test_conditional(i32* %p, i32 %oldval, i32 %newval) {
; CHECK-LABEL: test_conditional:
-; CHECK: dmb ishst
-
-; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: ldrex [[LOADED:r[0-9]+]], [r0]
; CHECK: cmp [[LOADED]], r1
; CHECK: bne [[FAILED:LBB[0-9]+_[0-9]+]]
+; CHECK: dmb ishst
+
+; CHECK: [[LOOP:LBB[0-9]+_[0-9]+]]:
; CHECK: strex [[STATUS:r[0-9]+]], r2, [r0]
-; CHECK: cmp [[STATUS]], #0
-; CHECK: bne [[LOOP]]
+; CHECK: cbz [[STATUS]], [[SUCCESS:LBB[0-9]+_[0-9]+]]
-; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
-; CHECK: dmb ish
-; CHECK: b.w _bar
+; CHECK: ldrex [[LOADED]], [r0]
+; CHECK: cmp [[LOADED]], r1
+; CHECK: beq [[LOOP]]
; CHECK: [[FAILED]]:
; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
+; CHECK: clrex
; CHECK: dmb ish
; CHECK: b.w _baz
+; CHECK: [[SUCCESS]]:
+; CHECK-NOT: cmp {{r[0-9]+}}, {{r[0-9]+}}
+; CHECK: dmb ish
+; CHECK: b.w _bar
+
%pair = cmpxchg i32* %p, i32 %oldval, i32 %newval seq_cst seq_cst
%success = extractvalue { i32, i1 } %pair, 1
br i1 %success, label %true, label %false
diff --git a/test/CodeGen/ARM/cmpxchg-weak.ll b/test/CodeGen/ARM/cmpxchg-weak.ll
index 1eac9c41cf92..4038528c91bc 100644
--- a/test/CodeGen/ARM/cmpxchg-weak.ll
+++ b/test/CodeGen/ARM/cmpxchg-weak.ll
@@ -6,11 +6,11 @@ define void @test_cmpxchg_weak(i32 *%addr, i32 %desired, i32 %new) {
%pair = cmpxchg weak i32* %addr, i32 %desired, i32 %new seq_cst monotonic
%oldval = extractvalue { i32, i1 } %pair, 0
; CHECK-NEXT: BB#0:
-; CHECK-NEXT: dmb ish
; CHECK-NEXT: ldrex [[LOADED:r[0-9]+]], [r0]
; CHECK-NEXT: cmp [[LOADED]], r1
; CHECK-NEXT: bne [[LDFAILBB:LBB[0-9]+_[0-9]+]]
; CHECK-NEXT: BB#1:
+; CHECK-NEXT: dmb ish
; CHECK-NEXT: strex [[SUCCESS:r[0-9]+]], r2, [r0]
; CHECK-NEXT: cmp [[SUCCESS]], #0
; CHECK-NEXT: bne [[FAILBB:LBB[0-9]+_[0-9]+]]
@@ -36,13 +36,13 @@ define i1 @test_cmpxchg_weak_to_bool(i32, i32 *%addr, i32 %desired, i32 %new) {
%success = extractvalue { i32, i1 } %pair, 1
; CHECK-NEXT: BB#0:
-; CHECK-NEXT: dmb ish
; CHECK-NEXT: ldrex [[LOADED:r[0-9]+]], [r1]
; CHECK-NEXT: cmp [[LOADED]], r2
; CHECK-NEXT: bne [[LDFAILBB:LBB[0-9]+_[0-9]+]]
; CHECK-NEXT: BB#1:
-; CHECK-NEXT: strex [[SUCCESS:r[0-9]+]], r3, [r1]
+; CHECK-NEXT: dmb ish
; CHECK-NEXT: mov r0, #0
+; CHECK-NEXT: strex [[SUCCESS:r[0-9]+]], r3, [r1]
; CHECK-NEXT: cmp [[SUCCESS]], #0
; CHECK-NEXT: bxne lr
; CHECK-NEXT: dmb ish
diff --git a/test/CodeGen/ARM/coalesce-dbgvalue.ll b/test/CodeGen/ARM/coalesce-dbgvalue.ll
index 4468f1ec9c42..cd45af338fde 100644
--- a/test/CodeGen/ARM/coalesce-dbgvalue.ll
+++ b/test/CodeGen/ARM/coalesce-dbgvalue.ll
@@ -79,11 +79,10 @@ attributes #3 = { nounwind }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!33}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (trunk 182024) (llvm/trunk 182023)", isOptimized: true, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !15, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.4 (trunk 182024) (llvm/trunk 182023)", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !15, imports: !2)
!1 = !DIFile(filename: "pr16110.c", directory: "/d/b")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "pr16110", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, scopeLine: 7, file: !1, scope: !5, type: !6, variables: !9)
+!4 = distinct !DISubprogram(name: "pr16110", line: 7, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !0, scopeLine: 7, file: !1, scope: !5, type: !6, variables: !9)
!5 = !DIFile(filename: "pr16110.c", directory: "/d/b")
!6 = !DISubroutineType(types: !7)
!7 = !{!8}
diff --git a/test/CodeGen/ARM/code-placement.ll b/test/CodeGen/ARM/code-placement.ll
index bf5cf52d8b54..8eaf3d5ab6b2 100644
--- a/test/CodeGen/ARM/code-placement.ll
+++ b/test/CodeGen/ARM/code-placement.ll
@@ -12,9 +12,9 @@ entry:
br i1 %0, label %bb2, label %bb
bb:
-; CHECK: LBB0_1:
-; CHECK: bne LBB0_1
-; CHECK-NOT: b LBB0_1
+; CHECK: LBB0_2:
+; CHECK: bne LBB0_2
+; CHECK-NOT: b LBB0_2
; CHECK: bx lr
%list_addr.05 = phi %struct.list_head* [ %2, %bb ], [ %list, %entry ]
%next.04 = phi %struct.list_head* [ %list_addr.05, %bb ], [ null, %entry ]
diff --git a/test/CodeGen/ARM/crash-greedy.ll b/test/CodeGen/ARM/crash-greedy.ll
index a3d49f620e9c..6a58bb871d35 100644
--- a/test/CodeGen/ARM/crash-greedy.ll
+++ b/test/CodeGen/ARM/crash-greedy.ll
@@ -30,7 +30,7 @@ for.end: ; preds = %cond.end
%call85 = tail call double @exp(double %mul84) nounwind
%mul86 = fmul double %conv78, %call85
%add88 = fadd double 0.000000e+00, %mul86
-; CHECK: blx _exp
+; CHECK: bl _exp
%call100 = tail call double @exp(double %mul84) nounwind
%mul101 = fmul double undef, %call100
%add103 = fadd double %add46, %mul101
diff --git a/test/CodeGen/ARM/cxx-tlscc.ll b/test/CodeGen/ARM/cxx-tlscc.ll
index 11173bbb1978..5d017bbeebca 100644
--- a/test/CodeGen/ARM/cxx-tlscc.ll
+++ b/test/CodeGen/ARM/cxx-tlscc.ll
@@ -1,7 +1,12 @@
; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 | FileCheck %s
-; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 -enable-shrink-wrap=true | FileCheck --check-prefix=CHECK %s
+; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 -enable-shrink-wrap=true | FileCheck %s
; RUN: llc < %s -mtriple=armv7-apple-ios8.0 | FileCheck %s
-; RUN: llc < %s -mtriple=armv7-apple-ios8.0 -enable-shrink-wrap=true | FileCheck --check-prefix=CHECK %s
+; RUN: llc < %s -mtriple=armv7-apple-ios8.0 -enable-shrink-wrap=true | FileCheck %s
+
+; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 -O0 | FileCheck --check-prefix=CHECK-O0 --check-prefix=WATCH-O0 %s
+; RUN: llc < %s -mtriple=armv7-apple-ios8.0 -O0 | FileCheck --check-prefix=CHECK-O0 --check-prefix=IOS-O0 %s
+
+; RUN: llc < %s -mtriple=thumbv7-apple-ios8.0 | FileCheck --check-prefix=THUMB %s
%struct.S = type { i8 }
@@ -10,10 +15,24 @@
@__tls_guard = internal thread_local unnamed_addr global i1 false
@sum1 = internal thread_local global i32 0, align 4
+%class.C = type { i32 }
+@tC = internal thread_local global %class.C zeroinitializer, align 4
+
declare %struct.S* @_ZN1SC1Ev(%struct.S* returned)
declare %struct.S* @_ZN1SD1Ev(%struct.S* returned)
declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
+; Make sure Epilog does not overwrite an explicitly-handled CSR in CXX_FAST_TLS.
+; THUMB-LABEL: _ZTW2sg
+; THUMB: push {{.*}}lr
+; THUMB: blx
+; THUMB: bne [[TH_end:.?LBB0_[0-9]+]]
+; THUMB: blx
+; THUMB: tlv_atexit
+; THUMB: [[TH_end]]:
+; THUMB: blx
+; THUMB: r4
+; THUMB: pop {{.*}}r4
define cxx_fast_tlscc nonnull %struct.S* @_ZTW2sg() nounwind {
%.b.i = load i1, i1* @__tls_guard, align 1
br i1 %.b.i, label %__tls_init.exit, label %init.i
@@ -29,14 +48,13 @@ __tls_init.exit:
}
; CHECK-LABEL: _ZTW2sg
-; CHECK: push {lr}
-; CHECK-NOT: push {r1, r2, r3, r4, r7, lr}
-; CHECK-NOT: push {r9, r12}
+; CHECK: push {r4, r5, r7, lr}
+; CHECK: push {r11, r12}
; CHECK-NOT: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
; CHECK-NOT: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
; CHECK: blx
; CHECK: bne [[BB_end:.?LBB0_[0-9]+]]
-; CHECK; blx
+; CHECK: blx
; CHECK: tlv_atexit
; CHECK: [[BB_end]]:
; CHECK: blx
@@ -44,7 +62,25 @@ __tls_init.exit:
; CHECK-NOT: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
; CHECK-NOT: pop {r9, r12}
; CHECK-NOT: pop {r1, r2, r3, r4, r7, pc}
-; CHECK: pop {lr}
+; CHECK: pop {r4, r5, r7, pc}
+
+; CHECK-O0-LABEL: _ZTW2sg
+; WATCH-O0: push {r1, r2, r3, r6, r7, lr}
+; IOS-O0: push {r1, r2, r3, r7, lr}
+; CHECK-O0: push {r9, r12}
+; CHECK-O0: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
+; CHECK-O0: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
+; CHECK-O0: blx
+; CHECK-O0: bne [[BB_end:.?LBB0_[0-9]+]]
+; CHECK-O0: blx
+; CHECK-O0: tlv_atexit
+; CHECK-O0: [[BB_end]]:
+; CHECK-O0: blx
+; CHECK-O0: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
+; CHECK-O0: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
+; CHECK-O0: pop {r9, r12}
+; WATCH-O0: pop {r1, r2, r3, r6, r7, pc}
+; IOS-O0: pop {r1, r2, r3, r7, pc}
; CHECK-LABEL: _ZTW4sum1
; CHECK-NOT: push {r1, r2, r3, r4, r7, lr}
@@ -52,6 +88,65 @@ __tls_init.exit:
; CHECK-NOT: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
; CHECK-NOT: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
; CHECK: blx
+
+; CHECK-O0-LABEL: _ZTW4sum1
+; CHECK-O0-NOT: vpush
+; CHECK-O0-NOT: vstr
+; CHECK-O0-NOT: vpop
+; CHECK-O0-NOT: vldr
+; CHECK-O0: pop
define cxx_fast_tlscc nonnull i32* @_ZTW4sum1() nounwind {
ret i32* @sum1
}
+
+; Make sure at O0, we don't generate spilling/reloading of the CSRs.
+; CHECK-O0-LABEL: tls_test2
+; CHECK-O0: push
+; CHECK-O0-NOT: vpush
+; CHECK-O0-NOT: vstr
+; CHECK-O0: tls_helper
+; CHECK-O0-NOT: vpop
+; CHECK-O0-NOT: vldr
+; CHECK-O0: pop
+declare cxx_fast_tlscc void @tls_helper()
+define cxx_fast_tlscc %class.C* @tls_test2() #1 {
+ call cxx_fast_tlscc void @tls_helper()
+ ret %class.C* @tC
+}
+
+; Make sure we do not allow tail call when caller and callee have different
+; calling conventions.
+declare %class.C* @_ZN1CD1Ev(%class.C* readnone returned %this)
+; CHECK-LABEL: tls_test
+; CHECK: bl __tlv_atexit
+define cxx_fast_tlscc void @__tls_test() {
+entry:
+ store i32 0, i32* getelementptr inbounds (%class.C, %class.C* @tC, i64 0, i32 0), align 4
+ %0 = tail call i32 @_tlv_atexit(void (i8*)* bitcast (%class.C* (%class.C*)* @_ZN1CD1Ev to void (i8*)*), i8* bitcast (%class.C* @tC to i8*), i8* nonnull @__dso_handle) #1
+ ret void
+}
+
+declare void @somefunc()
+define cxx_fast_tlscc void @test_ccmismatch_notail() {
+; A tail call is not possible here because somefunc does not preserve enough
+; registers.
+; CHECK-LABEL: test_ccmismatch_notail:
+; CHECK-NOT: b _somefunc
+; CHECK: bl _somefunc
+ tail call void @somefunc()
+ ret void
+}
+
+declare cxx_fast_tlscc void @some_fast_tls_func()
+define void @test_ccmismatch_tail() {
+; We can perform a tail call here because some_fast_tls_func preserves all
+; necessary registers (and more).
+; CHECK-LABEL: test_ccmismatch_tail:
+; CHECK-NOT: bl _some_fast_tls_func
+; CHECK: b _some_fast_tls_func
+ tail call cxx_fast_tlscc void @some_fast_tls_func()
+ ret void
+}
+
+attributes #0 = { nounwind "no-frame-pointer-elim"="true" }
+attributes #1 = { nounwind }
diff --git a/test/CodeGen/ARM/dagcombine-anyexttozeroext.ll b/test/CodeGen/ARM/dagcombine-anyexttozeroext.ll
index 8b7153503b1f..206371a8f4e4 100644
--- a/test/CodeGen/ARM/dagcombine-anyexttozeroext.ll
+++ b/test/CodeGen/ARM/dagcombine-anyexttozeroext.ll
@@ -19,12 +19,48 @@ define float @f(<4 x i16>* nocapture %in) {
ret float %7
}
+; CHECK-LABEL: g:
define float @g(<4 x i16>* nocapture %in) {
; CHECK: vldr
%1 = load <4 x i16>, <4 x i16>* %in
- ; CHECK-NOT: uxth
+
+ ; For now we're generating a vmov.16 and a uxth instruction.
+ ; The uxth is redundant, and we should be able to extend without
+ ; having to generate cross-domain copies. Once we can do this
+ ; we should modify the checks below.
+
+ ; CHECK: uxth
%2 = extractelement <4 x i16> %1, i32 0
; CHECK: vcvt.f32.u32
%3 = uitofp i16 %2 to float
ret float %3
}
+
+; The backend generates for the following code an
+; (and 0xff (i32 extract_vector_elt (zext load <4 x i8> to 4 x i16)))
+;
+; The and is not redundant and cannot be removed. Since
+; extract_vector_elt is doing an implicit any_ext, the and
+; is required to guarantee that the top bits are set to zero.
+
+; Ideally should be a zext from <4 x i8> to <4 x 32>.
+
+; CHECK-LABEL: h:
+; CHECK: vld1.32
+; CHECK: uxtb
+define <4 x i32> @h(<4 x i8> *%in) {
+ %1 = load <4 x i8>, <4 x i8>* %in, align 4
+ %2 = extractelement <4 x i8> %1, i32 0
+ %3 = zext i8 %2 to i32
+ %4 = insertelement <4 x i32> undef, i32 %3, i32 0
+ %5 = extractelement <4 x i8> %1, i32 1
+ %6 = zext i8 %5 to i32
+ %7 = insertelement <4 x i32> %4, i32 %6, i32 1
+ %8 = extractelement <4 x i8> %1, i32 2
+ %9 = zext i8 %8 to i32
+ %10 = insertelement <4 x i32> %7, i32 %9, i32 2
+ %11 = extractelement <4 x i8> %1, i32 3
+ %12 = zext i8 %11 to i32
+ %13 = insertelement <4 x i32> %10, i32 %12, i32 3
+ ret <4 x i32> %13
+}
diff --git a/test/CodeGen/ARM/darwin-tls.ll b/test/CodeGen/ARM/darwin-tls.ll
index e19953222020..1043cce6218b 100644
--- a/test/CodeGen/ARM/darwin-tls.ll
+++ b/test/CodeGen/ARM/darwin-tls.ll
@@ -10,6 +10,8 @@
@local_tls_var = thread_local global i32 0
@external_tls_var = external thread_local global i32
+@hidden_external_tls_var = external hidden thread_local global i32
+
define i32 @test_local_tls() {
; T2-MOVT-PIC-LABEL: test_local_tls:
@@ -163,3 +165,18 @@ define i32 @test_external_tls() {
%val = load i32, i32* @external_tls_var, align 4
ret i32 %val
}
+
+; Just need something to trigger an indirect reference to the var.
+define i32 @use_hidden_external_tls() {
+ %val = load i32, i32* @hidden_external_tls_var, align 4
+ ret i32 %val
+}
+
+; T2-MOVT-PIC: .section __DATA,__thread_ptr,thread_local_variable_pointers
+; T2-MOVT-PIC: .p2align 2
+; T2-MOVT-PIC: L_external_tls_var$non_lazy_ptr:
+; T2-MOVT-PIC: .indirect_symbol _external_tls_var
+; T2-MOVT-PIC: .long 0
+; T2-MOVT-PIC: L_hidden_external_tls_var$non_lazy_ptr:
+; T2-MOVT-PIC: .indirect_symbol _hidden_external_tls_var
+; T2-MOVT-PIC: .long 0
diff --git a/test/CodeGen/ARM/debug-frame-vararg.ll b/test/CodeGen/ARM/debug-frame-vararg.ll
index 13ca20c20359..b9eae59cc320 100644
--- a/test/CodeGen/ARM/debug-frame-vararg.ll
+++ b/test/CodeGen/ARM/debug-frame-vararg.ll
@@ -25,11 +25,10 @@
!llvm.module.flags = !{!9, !10}
!llvm.ident = !{!11}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "var.c", directory: "/tmp")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "sum", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
+!4 = distinct !DISubprogram(name: "sum", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
!5 = !DIFile(filename: "var.c", directory: "/tmp")
!6 = !DISubroutineType(types: !7)
!7 = !{!8, !8}
diff --git a/test/CodeGen/ARM/debug-frame.ll b/test/CodeGen/ARM/debug-frame.ll
index 4bd401b68496..9b54a4a463d1 100644
--- a/test/CodeGen/ARM/debug-frame.ll
+++ b/test/CodeGen/ARM/debug-frame.ll
@@ -125,11 +125,10 @@ declare void @_ZSt9terminatev()
!llvm.module.flags = !{!10, !11}
!llvm.ident = !{!12}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "exp.cpp", directory: "/tmp")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "test", linkageName: "_Z4testiiiiiddddd", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
+!4 = distinct !DISubprogram(name: "test", linkageName: "_Z4testiiiiiddddd", line: 4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
!5 = !DIFile(filename: "exp.cpp", directory: "/tmp")
!6 = !DISubroutineType(types: !7)
!7 = !{null, !8, !8, !8, !8, !8, !9, !9, !9, !9, !9}
diff --git a/test/CodeGen/ARM/debug-info-arg.ll b/test/CodeGen/ARM/debug-info-arg.ll
index bf7e7321ae3d..9dd820134dd4 100644
--- a/test/CodeGen/ARM/debug-info-arg.ll
+++ b/test/CodeGen/ARM/debug-info-arg.ll
@@ -32,8 +32,8 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!33}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", isOptimized: true, emissionKind: 1, file: !32, enums: !{}, retainedTypes: !{}, subprograms: !30, imports: null)
-!1 = distinct !DISubprogram(name: "foo", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 11, file: !2, scope: !2, type: !3, variables: !31)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", isOptimized: true, emissionKind: FullDebug, file: !32, enums: !{}, retainedTypes: !{}, imports: null)
+!1 = distinct !DISubprogram(name: "foo", line: 11, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 11, file: !2, scope: !2, type: !3, variables: !31)
!2 = !DIFile(filename: "one.c", directory: "/Volumes/Athwagate/R10048772")
!3 = !DISubroutineType(types: !4)
!4 = !{null}
@@ -62,7 +62,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!27 = distinct !DILexicalBlock(line: 11, column: 107, file: !2, scope: !1)
!28 = !DILocation(line: 13, column: 5, scope: !27)
!29 = !DILocation(line: 14, column: 1, scope: !27)
-!30 = !{!1}
!31 = !{!5, !13, !14, !17, !18, !19}
!32 = !DIFile(filename: "one.c", directory: "/Volumes/Athwagate/R10048772")
!33 = !{i32 1, !"Debug Info Version", i32 3}
diff --git a/test/CodeGen/ARM/debug-info-blocks.ll b/test/CodeGen/ARM/debug-info-blocks.ll
index c628c5e9038d..1e9d890e9333 100644
--- a/test/CodeGen/ARM/debug-info-blocks.ll
+++ b/test/CodeGen/ARM/debug-info-blocks.ll
@@ -111,7 +111,7 @@ define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %load
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!162}
-!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "Apple clang version 2.1", isOptimized: false, runtimeVersion: 2, emissionKind: 1, file: !153, enums: !147, retainedTypes: !{}, subprograms: !148)
+!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "Apple clang version 2.1", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, file: !153, enums: !147, retainedTypes: !{})
!1 = !DICompositeType(tag: DW_TAG_enumeration_type, line: 248, size: 32, align: 32, file: !160, scope: !0, elements: !3)
!2 = !DIFile(filename: "header.h", directory: "/Volumes/Sandbox/llvm")
!3 = !{!4}
@@ -134,7 +134,7 @@ define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %load
!20 = !DIFile(filename: "header4.h", directory: "/Volumes/Sandbox/llvm")
!21 = !{!22}
!22 = !DIEnumerator(name: "Eleven", value: 0) ; [ DW_TAG_enumerator ]
-!23 = distinct !DISubprogram(name: "foobar_func_block_invoke_0", line: 609, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 609, file: !152, scope: !24, type: !25)
+!23 = distinct !DISubprogram(name: "foobar_func_block_invoke_0", line: 609, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 609, file: !152, scope: !24, type: !25)
!24 = !DIFile(filename: "MyLibrary.m", directory: "/Volumes/Sandbox/llvm")
!25 = !DISubroutineType(types: !26)
!26 = !{null}
@@ -259,7 +259,6 @@ define hidden void @foobar_func_block_invoke_0(i8* %.block_descriptor, %0* %load
!145 = !DILocation(line: 613, column: 17, scope: !142)
!146 = !DILocation(line: 615, column: 13, scope: !142)
!147 = !{!1, !1, !5, !5, !9, !14, !19, !19, !14, !14, !14, !19, !19, !19}
-!148 = !{!23}
!149 = !DIFile(filename: "header3.h", directory: "/Volumes/Sandbox/llvm")
!150 = !DIFile(filename: "Private.h", directory: "/Volumes/Sandbox/llvm")
!151 = !DIFile(filename: "header4.h", directory: "/Volumes/Sandbox/llvm")
diff --git a/test/CodeGen/ARM/debug-info-branch-folding.ll b/test/CodeGen/ARM/debug-info-branch-folding.ll
index b9d110e42cd4..b4e48c4c423e 100644
--- a/test/CodeGen/ARM/debug-info-branch-folding.ll
+++ b/test/CodeGen/ARM/debug-info-branch-folding.ll
@@ -42,9 +42,9 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.module.flags = !{!56}
!llvm.dbg.cu = !{!2}
-!0 = distinct !DISubprogram(name: "test0001", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, file: !54, scope: null, type: !3, variables: !51)
+!0 = distinct !DISubprogram(name: "test0001", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, file: !54, scope: null, type: !3, variables: !51)
!1 = !DIFile(filename: "build2.c", directory: "/private/tmp")
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: 1, file: !54, enums: !{}, retainedTypes: !{}, subprograms: !50, imports: null)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: FullDebug, file: !54, enums: !{}, retainedTypes: !{}, imports: null)
!3 = !DISubroutineType(types: !4)
!4 = !{!5}
!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "v4f32", line: 14, file: !54, scope: !2, baseType: !6)
@@ -52,11 +52,11 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!7 = !DIBasicType(tag: DW_TAG_base_type, name: "float", size: 32, align: 32, encoding: DW_ATE_float)
!8 = !{!9}
!9 = !DISubrange(count: 4)
-!10 = distinct !DISubprogram(name: "main", line: 59, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, file: !54, scope: null, type: !11, variables: !52)
+!10 = distinct !DISubprogram(name: "main", line: 59, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, file: !54, scope: null, type: !11, variables: !52)
!11 = !DISubroutineType(types: !12)
!12 = !{!13}
!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!14 = distinct !DISubprogram(name: "printFV", line: 41, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, file: !55, scope: null, type: !16, variables: !53)
+!14 = distinct !DISubprogram(name: "printFV", line: 41, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, file: !55, scope: null, type: !16, variables: !53)
!15 = !DIFile(filename: "/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", directory: "/private/tmp")
!16 = !DISubroutineType(types: !17)
!17 = !{null}
@@ -92,7 +92,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!47 = distinct !DILexicalBlock(line: 41, column: 28, file: !15, scope: !14)
!48 = !DILocation(line: 95, column: 3, scope: !25)
!49 = !DILocation(line: 99, column: 3, scope: !25)
-!50 = !{!0, !10, !14}
!51 = !{!18}
!52 = !{!19, !20, !24, !26, !27, !28, !29}
!53 = !{!30}
diff --git a/test/CodeGen/ARM/debug-info-d16-reg.ll b/test/CodeGen/ARM/debug-info-d16-reg.ll
index 0d457d3a7371..46146c7b8bf5 100644
--- a/test/CodeGen/ARM/debug-info-d16-reg.ll
+++ b/test/CodeGen/ARM/debug-info-d16-reg.ll
@@ -59,17 +59,17 @@ declare i32 @puts(i8* nocapture) nounwind
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!48}
-!0 = distinct !DISubprogram(name: "printer", linkageName: "printer", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 12, file: !46, scope: !1, type: !3, variables: !43)
+!0 = distinct !DISubprogram(name: "printer", linkageName: "printer", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 12, file: !46, scope: !1, type: !3, variables: !43)
!1 = !DIFile(filename: "a.c", directory: "/tmp/")
-!2 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "(LLVM build 00)", isOptimized: true, emissionKind: 1, file: !46, enums: !47, retainedTypes: !47, subprograms: !42, imports: null)
+!2 = distinct !DICompileUnit(language: DW_LANG_C89, producer: "(LLVM build 00)", isOptimized: true, emissionKind: FullDebug, file: !46, enums: !47, retainedTypes: !47, imports: null)
!3 = !DISubroutineType(types: !4)
!4 = !{!5, !6, !7, !8}
!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !46, scope: !1, baseType: null)
!7 = !DIBasicType(tag: DW_TAG_base_type, name: "double", size: 64, align: 32, encoding: DW_ATE_float)
!8 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned char", size: 8, align: 8, encoding: DW_ATE_unsigned_char)
-!9 = distinct !DISubprogram(name: "inlineprinter", linkageName: "inlineprinter", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !46, scope: !1, type: !3, variables: !44)
-!10 = distinct !DISubprogram(name: "main", linkageName: "main", line: 18, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 18, file: !46, scope: !1, type: !11, variables: !45)
+!9 = distinct !DISubprogram(name: "inlineprinter", linkageName: "inlineprinter", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 5, file: !46, scope: !1, type: !3, variables: !44)
+!10 = distinct !DISubprogram(name: "main", linkageName: "main", line: 18, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 18, file: !46, scope: !1, type: !11, variables: !45)
!11 = !DISubroutineType(types: !12)
!12 = !{!5, !5, !13}
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, file: !46, scope: !1, baseType: !14)
@@ -106,7 +106,6 @@ declare i32 @puts(i8* nocapture) nounwind
!39 = !DILocation(line: 6, scope: !28, inlinedAt: !37)
!40 = !DILocation(line: 22, scope: !25)
!41 = !DILocation(line: 23, scope: !25)
-!42 = !{!0, !9, !10}
!43 = !{!16, !17, !18}
!44 = !{!19, !20, !21}
!45 = !{!22, !23, !24}
diff --git a/test/CodeGen/ARM/debug-info-no-frame.ll b/test/CodeGen/ARM/debug-info-no-frame.ll
index d77a195b9528..861c4ecefa98 100644
--- a/test/CodeGen/ARM/debug-info-no-frame.ll
+++ b/test/CodeGen/ARM/debug-info-no-frame.ll
@@ -21,10 +21,10 @@ attributes #1 = { nounwind readnone }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!7, !8}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, subprograms: !{!3})
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, emissionKind: FullDebug)
!1 = !DIFile(filename: "file.c", directory: "/dir")
!2 = !{}
-!3 = distinct !DISubprogram(name: "need_cfi_def_cfa_offset", scope: !1, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, variables: !2)
+!3 = distinct !DISubprogram(name: "need_cfi_def_cfa_offset", scope: !1, file: !1, line: 1, type: !4, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !2)
!4 = !DISubroutineType(types: !5)
!5 = !{null}
!6 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/test/CodeGen/ARM/debug-info-qreg.ll b/test/CodeGen/ARM/debug-info-qreg.ll
index 1cd90d433640..581b3e915ef1 100644
--- a/test/CodeGen/ARM/debug-info-qreg.ll
+++ b/test/CodeGen/ARM/debug-info-qreg.ll
@@ -38,9 +38,9 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!56}
-!0 = distinct !DISubprogram(name: "test0001", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !54, scope: !1, type: !3, variables: !51)
+!0 = distinct !DISubprogram(name: "test0001", line: 3, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 3, file: !54, scope: !1, type: !3, variables: !51)
!1 = !DIFile(filename: "build2.c", directory: "/private/tmp")
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: 1, file: !54, enums: !{}, retainedTypes: !{}, subprograms: !50, imports: null)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: FullDebug, file: !54, enums: !{}, retainedTypes: !{}, imports: null)
!3 = !DISubroutineType(types: !4)
!4 = !{!5}
!5 = !DIDerivedType(tag: DW_TAG_typedef, name: "v4f32", line: 14, file: !54, scope: !2, baseType: !6)
@@ -48,11 +48,11 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!7 = !DIBasicType(tag: DW_TAG_base_type, name: "float", size: 32, align: 32, encoding: DW_ATE_float)
!8 = !{!9}
!9 = !DISubrange(count: 4)
-!10 = distinct !DISubprogram(name: "main", line: 59, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 59, file: !54, scope: !1, type: !11, variables: !52)
+!10 = distinct !DISubprogram(name: "main", line: 59, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 59, file: !54, scope: !1, type: !11, variables: !52)
!11 = !DISubroutineType(types: !12)
!12 = !{!13}
!13 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!14 = distinct !DISubprogram(name: "printFV", line: 41, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 41, file: !55, scope: !15, type: !16, variables: !53)
+!14 = distinct !DISubprogram(name: "printFV", line: 41, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 41, file: !55, scope: !15, type: !16, variables: !53)
!15 = !DIFile(filename: "/Volumes/Lalgate/work/llvm/projects/llvm-test/SingleSource/UnitTests/Vector/helpers.h", directory: "/private/tmp")
!16 = !DISubroutineType(types: !17)
!17 = !{null}
@@ -88,7 +88,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!47 = distinct !DILexicalBlock(line: 41, column: 28, file: !55, scope: !14)
!48 = !DILocation(line: 95, column: 3, scope: !25)
!49 = !DILocation(line: 99, column: 3, scope: !25)
-!50 = !{!0, !10, !14}
!51 = !{!18}
!52 = !{!19, !20, !24, !26, !27, !28, !29}
!53 = !{!30}
diff --git a/test/CodeGen/ARM/debug-info-s16-reg.ll b/test/CodeGen/ARM/debug-info-s16-reg.ll
index 654aa4545ca4..2987b9a2105a 100644
--- a/test/CodeGen/ARM/debug-info-s16-reg.ll
+++ b/test/CodeGen/ARM/debug-info-s16-reg.ll
@@ -65,14 +65,14 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!2}
!llvm.module.flags = !{!53}
-!0 = distinct !DISubprogram(name: "inlineprinter", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !51, scope: !1, type: !3, variables: !48)
+!0 = distinct !DISubprogram(name: "inlineprinter", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 5, file: !51, scope: !1, type: !3, variables: !48)
!1 = !DIFile(filename: "a.c", directory: "/private/tmp")
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: 1, file: !51, enums: !52, retainedTypes: !52, subprograms: !47, imports: null)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.0 (trunk 129915)", isOptimized: true, emissionKind: FullDebug, file: !51, enums: !52, retainedTypes: !52, imports: null)
!3 = !DISubroutineType(types: !4)
!4 = !{!5}
!5 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!6 = distinct !DISubprogram(name: "printer", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 12, file: !51, scope: !1, type: !3, variables: !49)
-!7 = distinct !DISubprogram(name: "main", line: 18, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 18, file: !51, scope: !1, type: !3, variables: !50)
+!6 = distinct !DISubprogram(name: "printer", line: 12, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 12, file: !51, scope: !1, type: !3, variables: !49)
+!7 = distinct !DISubprogram(name: "main", line: 18, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, scopeLine: 18, file: !51, scope: !1, type: !3, variables: !50)
!8 = !DILocalVariable(name: "ptr", line: 4, arg: 1, scope: !0, file: !1, type: !9)
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 32, align: 32, scope: !2, baseType: null)
!10 = !DILocalVariable(name: "val", line: 4, arg: 2, scope: !0, file: !1, type: !11)
@@ -117,7 +117,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!44 = !DILocation(line: 6, column: 3, scope: !28, inlinedAt: !40)
!45 = !DILocation(line: 22, column: 3, scope: !23)
!46 = !DILocation(line: 23, column: 1, scope: !23)
-!47 = !{!0, !6, !7}
!48 = !{!8, !10, !12}
!49 = !{!14, !15, !16}
!50 = !{!17, !18, !22}
diff --git a/test/CodeGen/ARM/debug-info-sreg2.ll b/test/CodeGen/ARM/debug-info-sreg2.ll
index eadf1b48156b..b31d1b7bed4f 100644
--- a/test/CodeGen/ARM/debug-info-sreg2.ll
+++ b/test/CodeGen/ARM/debug-info-sreg2.ll
@@ -43,8 +43,8 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!20}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.0 (trunk 130845)", isOptimized: true, emissionKind: 1, file: !18, enums: !19, retainedTypes: !19, subprograms: !16, imports: null)
-!1 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 5, file: !18, scope: !2, type: !3, variables: !17)
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.0 (trunk 130845)", isOptimized: true, emissionKind: FullDebug, file: !18, enums: !19, retainedTypes: !19, imports: null)
+!1 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 5, file: !18, scope: !2, type: !3, variables: !17)
!2 = !DIFile(filename: "k.cc", directory: "/private/tmp")
!3 = !DISubroutineType(types: !4)
!4 = !{null}
@@ -59,7 +59,6 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnon
!13 = !DILocation(line: 8, column: 20, scope: !9)
!14 = !DILocation(line: 7, column: 20, scope: !10)
!15 = !DILocation(line: 10, column: 1, scope: !6)
-!16 = !{!1}
!17 = !{!5, !8}
!18 = !DIFile(filename: "k.cc", directory: "/private/tmp")
!19 = !{}
diff --git a/test/CodeGen/ARM/debug-segmented-stacks.ll b/test/CodeGen/ARM/debug-segmented-stacks.ll
index bd0abedc4133..3aa33f754118 100644
--- a/test/CodeGen/ARM/debug-segmented-stacks.ll
+++ b/test/CodeGen/ARM/debug-segmented-stacks.ll
@@ -39,11 +39,10 @@ define void @test_basic() #0 !dbg !4 {
; ARM-linux .cfi_same_value r5
}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: 0, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "var.c", directory: "/tmp")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "test_basic", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
+!4 = distinct !DISubprogram(name: "test_basic", line: 5, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 5, file: !1, scope: !5, type: !6, variables: !2)
!5 = !DIFile(filename: "var.c", directory: "/tmp")
!6 = !DISubroutineType(types: !7)
!7 = !{!8, !8}
diff --git a/test/CodeGen/ARM/debugtrap.ll b/test/CodeGen/ARM/debugtrap.ll
index 3d8cdea6cdae..5064a4ec2ca9 100644
--- a/test/CodeGen/ARM/debugtrap.ll
+++ b/test/CodeGen/ARM/debugtrap.ll
@@ -10,7 +10,7 @@ define void @test() nounwind {
entry:
; CHECK: bl foo
; CHECK-NEXT: pop
- ; CHECK-NEXT: trap
+ ; CHECK-NEXT: .inst 0xe7ffdefe
call void @foo()
call void @llvm.debugtrap()
ret void
diff --git a/test/CodeGen/ARM/default-float-abi.ll b/test/CodeGen/ARM/default-float-abi.ll
index 1b26bbdd9259..78d79def82cf 100644
--- a/test/CodeGen/ARM/default-float-abi.ll
+++ b/test/CodeGen/ARM/default-float-abi.ll
@@ -1,7 +1,10 @@
; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s --check-prefix=CHECK-HARD
+; RUN: llc -mtriple=armv7-linux-musleabihf %s -o - | FileCheck %s --check-prefix=CHECK-HARD
; RUN: llc -mtriple=armv7-linux-eabihf %s -o - | FileCheck %s --check-prefix=CHECK-HARD
; RUN: llc -mtriple=armv7-linux-gnueabihf -float-abi=soft %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
+; RUN: llc -mtriple=armv7-linux-musleabihf -float-abi=soft %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
; RUN: llc -mtriple=armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
+; RUN: llc -mtriple=armv7-linux-musleabi %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
; RUN: llc -mtriple=armv7-linux-eabi -float-abi=hard %s -o - | FileCheck %s --check-prefix=CHECK-HARD
; RUN: llc -mtriple=thumbv7-apple-ios6.0 %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
diff --git a/test/CodeGen/ARM/default-reloc.ll b/test/CodeGen/ARM/default-reloc.ll
new file mode 100644
index 000000000000..0b80b73061bc
--- /dev/null
+++ b/test/CodeGen/ARM/default-reloc.ll
@@ -0,0 +1,5 @@
+; RUN: llc -mtriple=armv7-linux-gnu -O0 < %s
+@a = external global i32
+define i32* @get() {
+ ret i32* @a
+}
diff --git a/test/CodeGen/ARM/divmod-eabi.ll b/test/CodeGen/ARM/divmod-eabi.ll
index 4178af397e66..1e4c8fc336da 100644
--- a/test/CodeGen/ARM/divmod-eabi.ll
+++ b/test/CodeGen/ARM/divmod-eabi.ll
@@ -1,16 +1,33 @@
+; We run the tests with both the default optimization level and O0, to make sure
+; we don't have any ABI differences between them. In principle, the ABI checks
+; should be the same for both optimization levels (there could be exceptions
+; from this when a div and a mod with the same operands are not coallesced into
+; the same divmod, but luckily this doesn't occur in practice even at O0).
+; Sometimes the checks that the correct registers are used after the libcalls
+; are different between optimization levels, so we have to separate them.
; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-none-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI
-; Both "none-eabi" and "androideabi" must lower SREM/UREM to __aeabi_{u,i}divmod
+; RUN: llc -mtriple armv7-none-eabihf %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
+; All "eabi" (Bare, GNU and Android) must lower SREM/UREM to __aeabi_{u,i}divmod
; RUN: llc -mtriple armv7-linux-androideabi %s -o - | FileCheck %s --check-prefix=EABI
-; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=GNU
-; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN
+; RUN: llc -mtriple armv7-linux-androideabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-linux-gnueabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-linux-musleabi %s -o - | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-linux-musleabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefixes=DARWIN,DARWIN-DEFAULT
+; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0
; FIXME: long-term, we will use "-apple-macho" and won't need this exception:
-; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefix=DARWIN
+; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefixes=DARWIN,DARWIN-DEFAULT
+; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=DARWIN,DARWIN-O0
+; RUN: llc -mtriple thumbv7-windows %s -o - | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-DEFAULT
+; RUN: llc -mtriple thumbv7-windows %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefixes=WINDOWS,WINDOWS-O0
define signext i16 @f16(i16 signext %a, i16 signext %b) {
; EABI-LABEL: f16:
-; GNU-LABEL: f16:
; DARWIN-LABEL: f16:
+; WINDOWS-LABEL: f16:
entry:
%conv = sext i16 %a to i32
%conv1 = sext i16 %b to i32
@@ -19,189 +36,238 @@ entry:
; EABI: __aeabi_idivmod
; EABI: mov [[div:r[0-9]+]], r0
; EABI: mov [[rem:r[0-9]+]], r1
-; GNU: __aeabi_idiv
-; GNU: mov [[sum:r[0-9]+]], r0
-; GNU: __modsi3
-; GNU: add [[sum]]{{.*}}r0
; DARWIN: ___divsi3
-; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: mov [[div:r[0-9]+]], r0
; DARWIN: __modsi3
-; DARWIN: add [[sum]]{{.*}}r0
+; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
+; DARWIN-O0: mov [[rem:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS-DEFAULT: mls [[rem:r[0-9]+]], r0,
+; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[rem]], r0
+; WINDOWS-O0: mov [[div:r[0-9]+]], r0
+; WINDOWS-O0: mls [[rem:r[0-9]+]], [[div]],
%rem8 = srem i32 %conv1, %conv
; EABI: __aeabi_idivmod
-; GNU: __modsi3
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem1:r[0-9]+]], r0,
%add = add nsw i32 %rem, %div
%add13 = add nsw i32 %add, %rem8
%conv14 = trunc i32 %add13 to i16
; EABI: add r0{{.*}}r1
; EABI: sxth r0, r0
-; GNU: add r0{{.*}}[[sum]]
-; GNU: sxth r0, r0
-; DARWIN: add r0{{.*}}[[sum]]
-; DARWIN: sxth r0, r0
+; DARWIN-DEFAULT: add [[res:r[0-9]+]], [[sum]], r0
+; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
+; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
+; DARWIN: sxth r0, [[res]]
+; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
+; WINDOWS: add [[rem1]], [[sum]]
+; WINDOWS: sxth [[res:r[0-9]+]], [[rem1]]
ret i16 %conv14
}
define i32 @f32(i32 %a, i32 %b) {
; EABI-LABEL: f32:
-; GNU-LABEL: f32:
; DARWIN-LABEL: f32:
+; WINDOWS-LABEL: f32:
entry:
%div = sdiv i32 %a, %b
%rem = srem i32 %a, %b
; EABI: __aeabi_idivmod
; EABI: mov [[div:r[0-9]+]], r0
; EABI: mov [[rem:r[0-9]+]], r1
-; GNU: __aeabi_idiv
-; GNU: mov [[sum:r[0-9]+]], r0
-; GNU: __modsi3
-; GNU: add [[sum]]{{.*}}r0
; DARWIN: ___divsi3
-; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: mov [[div:r[0-9]+]], r0
; DARWIN: __modsi3
-; DARWIN: add [[sum]]{{.*}}r0
+; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
+; DARWIN-O0: mov [[rem:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mov [[div:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
+; WINDOWS-DEFAULT: add [[div]], [[rem]]
%rem1 = srem i32 %b, %a
; EABI: __aeabi_idivmod
-; GNU: __modsi3
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem1:r[0-9]+]], r0,
%add = add nsw i32 %rem, %div
%add2 = add nsw i32 %add, %rem1
; EABI: add r0{{.*}}r1
-; GNU: add r0{{.*}}[[sum]]
-; DARWIN: add r0{{.*}}[[sum]]
+; DARWIN-DEFAULT: add r0, [[sum]], r0
+; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
+; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
+; WINDOWS-DEFAULT: add [[rem1]], [[div]]
+; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
+; WINDOWS-O0: add [[rem1]], [[sum]]
ret i32 %add2
}
define i32 @uf(i32 %a, i32 %b) {
; EABI-LABEL: uf:
-; GNU-LABEL: uf:
; DARWIN-LABEL: uf:
+; WINDOWS-LABEL: uf:
entry:
%div = udiv i32 %a, %b
%rem = urem i32 %a, %b
; EABI: __aeabi_uidivmod
-; GNU: __aeabi_uidiv
-; GNU: mov [[sum:r[0-9]+]], r0
-; GNU: __umodsi3
-; GNU: add [[sum]]{{.*}}r0
; DARWIN: ___udivsi3
-; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: mov [[div:r[0-9]+]], r0
; DARWIN: __umodsi3
-; DARWIN: add [[sum]]{{.*}}r0
+; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
+; DARWIN-O0: mov [[rem:r[0-9]+]], r0
+; WINDOWS: __rt_udiv
+; WINDOWS: mov [[div:r[0-9]+]], r0
+; WINDOWS: __rt_udiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
+; WINDOWS-DEFAULT: add [[div]], [[rem]]
%rem1 = urem i32 %b, %a
; EABI: __aeabi_uidivmod
-; GNU: __umodsi3
; DARWIN: __umodsi3
+; WINDOWS: __rt_udiv
+; WINDOWS: mls [[rem1:r[0-9]+]], r0,
%add = add nuw i32 %rem, %div
%add2 = add nuw i32 %add, %rem1
; EABI: add r0{{.*}}r1
-; GNU: add r0{{.*}}[[sum]]
-; DARWIN: add r0{{.*}}[[sum]]
+; DARWIN-DEFAULT: add r0, [[sum]], r0
+; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
+; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
+; WINDOWS-DEFAULT: add [[rem1]], [[div]]
+; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
+; WINDOWS-O0: add [[rem1]], [[sum]]
ret i32 %add2
}
-; FIXME: AEABI is not lowering long u/srem into u/ldivmod
define i64 @longf(i64 %a, i64 %b) {
; EABI-LABEL: longf:
-; GNU-LABEL: longf:
; DARWIN-LABEL: longf:
+; WINDOWS-LABEL: longf:
entry:
%div = sdiv i64 %a, %b
%rem = srem i64 %a, %b
; EABI: __aeabi_ldivmod
-; GNU: __aeabi_ldivmod
-; GNU: mov [[div1:r[0-9]+]], r0
-; GNU: mov [[div2:r[0-9]+]], r1
+; EABI-NEXT: adds r0
+; EABI-NEXT: adc r1
+; EABI-NOT: __aeabi_ldivmod
; DARWIN: ___divdi3
; DARWIN: mov [[div1:r[0-9]+]], r0
; DARWIN: mov [[div2:r[0-9]+]], r1
; DARWIN: __moddi3
+; WINDOWS: __rt_sdiv64
+; WINDOWS: mov [[div1:r[0-9]+]], r0
+; WINDOWS: mov [[div2:r[0-9]+]], r1
+; WINDOWS: __moddi3
%add = add nsw i64 %rem, %div
-; GNU: adds r0{{.*}}[[div1]]
-; GNU: adc r1{{.*}}[[div2]]
; DARWIN: adds r0{{.*}}[[div1]]
; DARWIN: adc r1{{.*}}[[div2]]
+; WINDOWS: adds.w r0, r0, [[div1]]
+; WINDOWS: adc.w r1, r1, [[div2]]
ret i64 %add
}
+define i16 @shortf(i16 %a, i16 %b) {
+; EABI-LABEL: shortf:
+; DARWIN-LABEL: shortf:
+; WINDOWS-LABEL: shortf:
+entry:
+ %div = sdiv i16 %a, %b
+ %rem = srem i16 %a, %b
+; EABI: __aeabi_idivmod
+; DARWIN: ___divsi3
+; DARWIN: mov [[div1:r[0-9]+]], r0
+; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mov [[div:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
+ %add = add nsw i16 %rem, %div
+; EABI: add r0, r1
+; DARWIN: add r0{{.*}}[[div1]]
+; WINDOWS: add [[rem]], [[div]]
+ ret i16 %add
+}
+
define i32 @g1(i32 %a, i32 %b) {
; EABI-LABEL: g1:
-; GNU-LABEL: g1:
; DARWIN-LABEL: g1:
+; WINDOWS-LABEL: g1:
entry:
%div = sdiv i32 %a, %b
%rem = srem i32 %a, %b
; EABI: __aeabi_idivmod
-; GNU: __aeabi_idiv
-; GNU: mov [[sum:r[0-9]+]], r0
-; GNU: __modsi3
; DARWIN: ___divsi3
; DARWIN: mov [[sum:r[0-9]+]], r0
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mov [[div:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
%add = add nsw i32 %rem, %div
; EABI: add r0{{.*}}r1
-; GNU: add r0{{.*}}[[sum]]
; DARWIN: add r0{{.*}}[[sum]]
+; WINDOWS: add [[rem]], [[div]]
ret i32 %add
}
; On both Darwin and Gnu, this is just a call to __modsi3
define i32 @g2(i32 %a, i32 %b) {
; EABI-LABEL: g2:
-; GNU-LABEL: g2:
; DARWIN-LABEL: g2:
+; WINDOWS-LABEL: g2:
entry:
%rem = srem i32 %a, %b
; EABI: __aeabi_idivmod
-; GNU: __modsi3
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
ret i32 %rem
; EABI: mov r0, r1
+; WINDOWS: mls r0, r0,
}
define i32 @g3(i32 %a, i32 %b) {
; EABI-LABEL: g3:
-; GNU-LABEL: g3:
; DARWIN-LABEL: g3:
+; WINDOWS-LABEL: g3:
entry:
%rem = srem i32 %a, %b
; EABI: __aeabi_idivmod
; EABI: mov [[mod:r[0-9]+]], r1
-; GNU: __modsi3
-; GNU: mov [[sum:r[0-9]+]], r0
; DARWIN: __modsi3
; DARWIN: mov [[sum:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
%rem1 = srem i32 %b, %rem
; EABI: __aeabi_idivmod
-; GNU: __modsi3
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem1:r[0-9]+]], r0,
%add = add nsw i32 %rem1, %rem
; EABI: add r0, r1, [[mod]]
-; GNU: add r0{{.*}}[[sum]]
; DARWIN: add r0{{.*}}[[sum]]
+; WINDOWS: add [[rem1]], [[rem]]
ret i32 %add
}
define i32 @g4(i32 %a, i32 %b) {
; EABI-LABEL: g4:
-; GNU-LABEL: g4:
; DARWIN-LABEL: g4:
+; WINDOWS-LABEL: g4:
entry:
%div = sdiv i32 %a, %b
; EABI: __aeabi_idiv{{$}}
; EABI: mov [[div:r[0-9]+]], r0
-; GNU: __aeabi_idiv
-; GNU: mov [[sum:r[0-9]+]], r0
; DARWIN: ___divsi3
; DARWIN: mov [[sum:r[0-9]+]], r0
+; WINDOWS: __rt_sdiv
+; WINDOWS: mov [[div:r[0-9]+]], r0
%rem = srem i32 %b, %div
; EABI: __aeabi_idivmod
-; GNU: __modsi3
; DARWIN: __modsi3
+; WINDOWS: __rt_sdiv
+; WINDOWS: mls [[rem:r[0-9]+]], r0,
%add = add nsw i32 %rem, %div
; EABI: add r0, r1, [[div]]
-; GNU: add r0{{.*}}[[sum]]
; DARWIN: add r0{{.*}}[[sum]]
+; WINDOWS: add [[rem]], [[div]]
ret i32 %add
}
diff --git a/test/CodeGen/ARM/eh-resume-darwin.ll b/test/CodeGen/ARM/eh-resume-darwin.ll
index d3a8481275f3..6c2716bffa6d 100644
--- a/test/CodeGen/ARM/eh-resume-darwin.ll
+++ b/test/CodeGen/ARM/eh-resume-darwin.ll
@@ -1,6 +1,7 @@
; RUN: llc < %s -mtriple=armv7-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
-; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
-; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHOS
+; RUN: llc < %s -mtriple=armv7-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=IOS
+; RUN: llc < %s -mtriple=armv7k-apple-ios -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
+; RUN: llc < %s -mtriple=armv7k-apple-watchos -arm-atomic-cfg-tidy=0 | FileCheck %s -check-prefix=WATCHABI
declare void @func()
@@ -21,4 +22,4 @@ lpad:
}
; IOS: __Unwind_SjLj_Resume
-; WATCHOS: __Unwind_Resume
+; WATCHABI: __Unwind_Resume
diff --git a/test/CodeGen/ARM/ehabi-handlerdata-nounwind.ll b/test/CodeGen/ARM/ehabi-handlerdata-nounwind.ll
index 3d380bf8f22a..517d5597bb28 100644
--- a/test/CodeGen/ARM/ehabi-handlerdata-nounwind.ll
+++ b/test/CodeGen/ARM/ehabi-handlerdata-nounwind.ll
@@ -42,7 +42,7 @@ try.cont:
}
; CHECK: .globl test1
-; CHECK: .align 2
+; CHECK: .p2align 2
; CHECK: .type test1,%function
; CHECK-LABEL: test1:
; CHECK: .fnstart
@@ -51,7 +51,7 @@ try.cont:
; CHECK: .personality __gxx_personality_v0
; CHECK: .handlerdata
-; CHECK: .align 2
+; CHECK: .p2align 2
; CHECK-LABEL: GCC_except_table0:
; CHECK-LABEL: .Lexception0:
; CHECK: .byte 255 @ @LPStart Encoding = omit
diff --git a/test/CodeGen/ARM/ehabi-handlerdata.ll b/test/CodeGen/ARM/ehabi-handlerdata.ll
index c53b36ffe18f..ecb23c3424e2 100644
--- a/test/CodeGen/ARM/ehabi-handlerdata.ll
+++ b/test/CodeGen/ARM/ehabi-handlerdata.ll
@@ -40,13 +40,13 @@ try.cont:
}
; CHECK: .globl test1
-; CHECK: .align 2
+; CHECK: .p2align 2
; CHECK: .type test1,%function
; CHECK-LABEL: test1:
; CHECK: .fnstart
; CHECK: .personality __gxx_personality_v0
; CHECK: .handlerdata
-; CHECK: .align 2
+; CHECK: .p2align 2
; CHECK-LABEL: GCC_except_table0:
; CHECK-LABEL: .Lexception0:
; CHECK: .byte 255 @ @LPStart Encoding = omit
diff --git a/test/CodeGen/ARM/ehabi.ll b/test/CodeGen/ARM/ehabi.ll
index 923cffcf6532..e2984de9ce4d 100644
--- a/test/CodeGen/ARM/ehabi.ll
+++ b/test/CodeGen/ARM/ehabi.ll
@@ -34,6 +34,22 @@
; RUN: -filetype=asm -o - %s \
; RUN: | FileCheck %s --check-prefix=CHECK-V7-FP-ELIM
+; RUN: llc -mtriple arm-unknown-linux-musleabi \
+; RUN: -disable-fp-elim -filetype=asm -o - %s \
+; RUN: | FileCheck %s --check-prefix=CHECK-FP
+
+; RUN: llc -mtriple arm-unknown-linux-musleabi \
+; RUN: -filetype=asm -o - %s \
+; RUN: | FileCheck %s --check-prefix=CHECK-FP-ELIM
+
+; RUN: llc -mtriple armv7-unknown-linux-musleabi \
+; RUN: -disable-fp-elim -filetype=asm -o - %s \
+; RUN: | FileCheck %s --check-prefix=CHECK-V7-FP
+
+; RUN: llc -mtriple armv7-unknown-linux-musleabi \
+; RUN: -filetype=asm -o - %s \
+; RUN: | FileCheck %s --check-prefix=CHECK-V7-FP-ELIM
+
; RUN: llc -mtriple arm-unknown-linux-androideabi \
; RUN: -disable-fp-elim -filetype=asm -o - %s \
; RUN: | FileCheck %s --check-prefix=CHECK-FP
diff --git a/test/CodeGen/ARM/emutls.ll b/test/CodeGen/ARM/emutls.ll
index 7ba50dd249bb..e66d93ebcb89 100644
--- a/test/CodeGen/ARM/emutls.ll
+++ b/test/CodeGen/ARM/emutls.ll
@@ -11,8 +11,9 @@ define i32 @my_get_xyz() {
; ARM32-LABEL: my_get_xyz:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl my_emutls_get_address(PLT)
+; ARM32-NEXT: bl my_emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
+; ARM32: .long my_emutls_v_xyz(GOT_PREL)
entry:
%call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))
@@ -33,8 +34,9 @@ define i32 @f1() {
; ARM32-LABEL: f1:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
+; ARM32: .long __emutls_v.i1(GOT_PREL)
entry:
%tmp1 = load i32, i32* @i1
@@ -45,8 +47,9 @@ define i32* @f2() {
; ARM32-LABEL: f2:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: pop
+; ARM32: .long __emutls_v.i1(GOT_PREL)
entry:
ret i32* @i1
@@ -56,8 +59,9 @@ define i32 @f3() nounwind {
; ARM32-LABEL: f3:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
+; ARM32: .long __emutls_v.i2(GOT_PREL)
entry:
%tmp1 = load i32, i32* @i2
@@ -68,8 +72,9 @@ define i32* @f4() {
; ARM32-LABEL: f4:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: pop
+; ARM32: .long __emutls_v.i2(GOT_PREL)
entry:
ret i32* @i2
@@ -78,9 +83,10 @@ entry:
define i32 @f5() nounwind {
; ARM32-LABEL: f5:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
+; ARM32: .long __emutls_v.i3-
entry:
%tmp1 = load i32, i32* @i3
@@ -90,9 +96,10 @@ entry:
define i32* @f6() {
; ARM32-LABEL: f6:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: pop
+; ARM32: .long __emutls_v.i3-
entry:
ret i32* @i3
@@ -101,9 +108,10 @@ entry:
define i32 @f7() {
; ARM32-LABEL: f7:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
+; ARM32: .long __emutls_v.i4-(.LPC
entry:
%tmp1 = load i32, i32* @i4
@@ -113,9 +121,10 @@ entry:
define i32* @f8() {
; ARM32-LABEL: f8:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: pop
+; ARM32: .long __emutls_v.i4-(.LPC
entry:
ret i32* @i4
@@ -124,8 +133,8 @@ entry:
define i32 @f9() {
; ARM32-LABEL: f9:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldr r0, [r0]
entry:
@@ -136,8 +145,8 @@ entry:
define i32* @f10() {
; ARM32-LABEL: f10:
; ARM32: ldr r0,
-; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32: add r0, pc, r0
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: pop
entry:
@@ -148,7 +157,7 @@ define i16 @f11() {
; ARM32-LABEL: f11:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldrh r0, [r0]
entry:
@@ -160,7 +169,7 @@ define i32 @f12() {
; ARM32-LABEL: f12:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldrsh r0, [r0]
entry:
@@ -173,7 +182,7 @@ define i8 @f13() {
; ARM32-LABEL: f13:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldrb r0, [r0]
; ARM32-NEXT: pop
@@ -186,7 +195,7 @@ define i32 @f14() {
; ARM32-LABEL: f14:
; ARM32: ldr r0,
; ARM32: ldr r0, [pc, r0]
-; ARM32-NEXT: bl __emutls_get_address(PLT)
+; ARM32-NEXT: bl __emutls_get_address
; ARM32-NEXT: ldrsb r0, [r0]
; ARM32-NEXT: pop
@@ -198,46 +207,50 @@ entry:
;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t.
-; ARM32 .section .data.rel.local,
+; ARM32: .data{{$}}
+; ARM32: .globl __emutls_v.i1
; ARM32-LABEL: __emutls_v.i1:
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 0
; ARM32-NEXT: .long __emutls_t.i1
-; ARM32 .section .rodata,
+; ARM32: .section .rodata,
; ARM32-LABEL: __emutls_t.i1:
; ARM32-NEXT: .long 15
; ARM32-NOT: __emutls_v.i2
-; ARM32 .section .data.rel.local,
+; ARM32: .data{{$}}
+; ARM32-NOT: .globl
; ARM32-LABEL: __emutls_v.i3:
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 0
; ARM32-NEXT: .long __emutls_t.i3
-; ARM32 .section .rodata,
+; ARM32: .section .rodata,
; ARM32-LABEL: __emutls_t.i3:
; ARM32-NEXT: .long 15
-; ARM32 .section .data.rel.local,
+; ARM32: .data{{$}}
+; ARM32: .globl __emutls_v.i4
; ARM32-LABEL: __emutls_v.i4:
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 4
; ARM32-NEXT: .long 0
; ARM32-NEXT: .long __emutls_t.i4
-; ARM32 .section .rodata,
+; ARM32: .section .rodata,
; ARM32-LABEL: __emutls_t.i4:
; ARM32-NEXT: .long 15
; ARM32-NOT: __emutls_v.i5:
-; ARM32 .hidden __emutls_v.i5
+; ARM32: .hidden __emutls_v.i5
; ARM32-NOT: __emutls_v.i5:
-; ARM32 .section .data.rel.local,
+; ARM32: .data{{$}}
+; ARM32: .globl __emutls_v.s1
; ARM32-LABEL: __emutls_v.s1:
; ARM32-NEXT: .long 2
; ARM32-NEXT: .long 2
@@ -248,7 +261,8 @@ entry:
; ARM32-LABEL: __emutls_t.s1:
; ARM32-NEXT: .short 15
-; ARM32 .section .data.rel.local,
+; ARM32: .data{{$}}
+; ARM32: .globl __emutls_v.b1
; ARM32-LABEL: __emutls_v.b1:
; ARM32-NEXT: .long 1
; ARM32-NEXT: .long 1
diff --git a/test/CodeGen/ARM/emutls_generic.ll b/test/CodeGen/ARM/emutls_generic.ll
index 0fada88fb5d9..f5633dc23bcd 100644
--- a/test/CodeGen/ARM/emutls_generic.ll
+++ b/test/CodeGen/ARM/emutls_generic.ll
@@ -35,12 +35,13 @@ entry:
; ARM_32: bl __emutls_get_address
; ARM_32: .long __emutls_v.external_y
; ARM_32-LABEL: get_internal_y:
-; ARM_32: bl __emutls_get_address
-; ARM_32: .long __emutls_v.internal_y
-; ARM_32-NOT: __emutls_t.external_x
-; ARM_32-NOT: __emutls_v.external_x:
-; ARM_32: .data
-; ARM_32: .align 2
+; ARM_32: bl __emutls_get_address
+; ARM_32: .long __emutls_v.internal_y
+; ARM_32-NOT: __emutls_t.external_x
+; ARM_32-NOT: __emutls_v.external_x:
+; ARM_32: .data{{$}}
+; ARM_32: .globl __emutls_v.external_y
+; ARM_32: .p2align 2
; ARM_32-LABEL: __emutls_v.external_y:
; ARM_32-NEXT: .long 1
; ARM_32-NEXT: .long 2
@@ -49,8 +50,9 @@ entry:
; ARM_32: .section .rodata,
; ARM_32-LABEL: __emutls_t.external_y:
; ARM_32-NEXT: .byte 7
-; ARM_32: .data
-; ARM_32: .align 2
+; ARM_32: .data{{$}}
+; ARM_32-NOT: .globl
+; ARM_32: .p2align 2
; ARM_32-LABEL: __emutls_v.internal_y:
; ARM_32-NEXT: .long 8
; ARM_32-NEXT: .long 16
diff --git a/test/CodeGen/ARM/fast-isel-call.ll b/test/CodeGen/ARM/fast-isel-call.ll
index e382e78a9950..1122867356b3 100644
--- a/test/CodeGen/ARM/fast-isel-call.ll
+++ b/test/CodeGen/ARM/fast-isel-call.ll
@@ -1,8 +1,8 @@
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi | FileCheck %s --check-prefix=ARM
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-MACHO
+; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-ELF
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=THUMB-LONG
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
@@ -111,9 +111,14 @@ entry:
; ARM: str [[R4]], [sp, #4]
; ARM: bl {{_?}}bar
; ARM-LONG: @t10
-; ARM-LONG: {{(movw)|(ldr)}} [[R:l?r[0-9]*]], {{(:lower16:L_bar\$non_lazy_ptr)|(.LCPI)}}
-; ARM-LONG: {{(movt [[R]], :upper16:L_bar\$non_lazy_ptr)?}}
-; ARM-LONG: ldr [[R]], {{\[}}[[R]]{{\]}}
+
+; ARM-LONG-MACHO: {{(movw)|(ldr)}} [[R:l?r[0-9]*]], {{(:lower16:L_bar\$non_lazy_ptr)|(.LCPI)}}
+; ARM-LONG-MACHO: {{(movt [[R]], :upper16:L_bar\$non_lazy_ptr)?}}
+; ARM-LONG-MACHO: ldr [[R]], {{\[}}[[R]]{{\]}}
+
+; ARM-LONG-ELF: movw [[R:l?r[0-9]*]], :lower16:bar
+; ARM-LONG-ELF: {{(movt [[R]], :upper16:L_bar\$non_lazy_ptr)?}}
+
; ARM-LONG: blx [[R]]
; THUMB: @t10
; THUMB: movs [[R0:l?r[0-9]*]], #0
@@ -167,9 +172,14 @@ entry:
; ARM: LibCall
; ARM: bl {{___udivsi3|__aeabi_uidiv}}
; ARM-LONG: LibCall
-; ARM-LONG: {{(movw r2, :lower16:L___udivsi3\$non_lazy_ptr)|(ldr r2, .LCPI)}}
-; ARM-LONG: {{(movt r2, :upper16:L___udivsi3\$non_lazy_ptr)?}}
-; ARM-LONG: ldr r2, [r2]
+
+; ARM-LONG-MACHO: {{(movw r2, :lower16:L___udivsi3\$non_lazy_ptr)|(ldr r2, .LCPI)}}
+; ARM-LONG-MACHO: {{(movt r2, :upper16:L___udivsi3\$non_lazy_ptr)?}}
+; ARM-LONG-MACHO: ldr r2, [r2]
+
+; ARM-LONG-ELF: movw r2, :lower16:__aeabi_uidiv
+; ARM-LONG-ELF: movt r2, :upper16:__aeabi_uidiv
+
; ARM-LONG: blx r2
; THUMB: LibCall
; THUMB: bl {{___udivsi3|__aeabi_uidiv}}
diff --git a/test/CodeGen/ARM/fast-isel-deadcode.ll b/test/CodeGen/ARM/fast-isel-deadcode.ll
index e584c54b48a2..d66a81c7cdb2 100644
--- a/test/CodeGen/ARM/fast-isel-deadcode.ll
+++ b/test/CodeGen/ARM/fast-isel-deadcode.ll
@@ -7,7 +7,7 @@ define i32 @main(i32 %argc, i8** %argv) nounwind {
entry:
; THUMB: main
call void @printArgsNoRet(i32 1, float 0x4000CCCCC0000000, i8 signext 99, double 4.100000e+00)
-; THUMB: blx _printArgsNoRet
+; THUMB: bl _printArgsNoRet
; THUMB-NOT: ldr
; THUMB-NOT: vldr
; THUMB-NOT: vmov
diff --git a/test/CodeGen/ARM/fast-isel-intrinsic.ll b/test/CodeGen/ARM/fast-isel-intrinsic.ll
index 1c7ff6879386..277461aa566b 100644
--- a/test/CodeGen/ARM/fast-isel-intrinsic.ll
+++ b/test/CodeGen/ARM/fast-isel-intrinsic.ll
@@ -1,8 +1,8 @@
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-MACHO
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-ELF
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-MACHO
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-ELF
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls -verify-machineinstrs | FileCheck %s --check-prefix=THUMB-LONG
; Note that some of these tests assume that relocations are either
@@ -22,9 +22,14 @@ define void @t1() nounwind ssp {
; ARM: and r1, r1, #255
; ARM: bl {{_?}}memset
; ARM-LONG-LABEL: t1:
-; ARM-LONG: {{(movw r3, :lower16:L_memset\$non_lazy_ptr)|(ldr r3, .LCPI)}}
-; ARM-LONG: {{(movt r3, :upper16:L_memset\$non_lazy_ptr)?}}
-; ARM-LONG: ldr r3, [r3]
+
+; ARM-LONG-MACHO: {{(movw r3, :lower16:L_memset\$non_lazy_ptr)|(ldr r3, .LCPI)}}
+; ARM-LONG-MACHO: {{(movt r3, :upper16:L_memset\$non_lazy_ptr)?}}
+; ARM-LONG-MACHO: ldr r3, [r3]
+
+; ARM-LONG-ELF: movw r3, :lower16:memset
+; ARM-LONG-ELF: movt r3, :upper16:memset
+
; ARM-LONG: blx r3
; THUMB-LABEL: t1:
; THUMB: {{(movw r0, :lower16:_?message1)|(ldr.n r0, .LCPI)}}
@@ -47,9 +52,14 @@ declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) nounwind
define void @t2() nounwind ssp {
; ARM-LABEL: t2:
-; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+
+; ARM-MACHO: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:temp
+; ARM-ELF: movt r0, :upper16:temp
+
; ARM: add r1, r0, #4
; ARM: add r0, r0, #16
; ARM: movw r2, #17
@@ -58,9 +68,14 @@ define void @t2() nounwind ssp {
; ARM: ldr r1, [sp[[SLOT]]] @ 4-byte Reload
; ARM: bl {{_?}}memcpy
; ARM-LONG-LABEL: t2:
-; ARM-LONG: {{(movw r3, :lower16:L_memcpy\$non_lazy_ptr)|(ldr r3, .LCPI)}}
-; ARM-LONG: {{(movt r3, :upper16:L_memcpy\$non_lazy_ptr)?}}
-; ARM-LONG: ldr r3, [r3]
+
+; ARM-LONG-MACHO: {{(movw r3, :lower16:L_memcpy\$non_lazy_ptr)|(ldr r3, .LCPI)}}
+; ARM-LONG-MACHO: {{(movt r3, :upper16:L_memcpy\$non_lazy_ptr)?}}
+; ARM-LONG-MACHO: ldr r3, [r3]
+
+; ARM-LONG-ELF: movw r3, :lower16:memcpy
+; ARM-LONG-ELF: movt r3, :upper16:memcpy
+
; ARM-LONG: blx r3
; THUMB-LABEL: t2:
; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
@@ -86,18 +101,29 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32,
define void @t3() nounwind ssp {
; ARM-LABEL: t3:
-; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+
+; ARM-MACHO: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:temp
+; ARM-ELF: movt r0, :upper16:temp
+
+
; ARM: add r1, r0, #4
; ARM: add r0, r0, #16
; ARM: movw r2, #10
; ARM: mov r0, r1
; ARM: bl {{_?}}memmove
; ARM-LONG-LABEL: t3:
-; ARM-LONG: {{(movw r3, :lower16:L_memmove\$non_lazy_ptr)|(ldr r3, .LCPI)}}
-; ARM-LONG: {{(movt r3, :upper16:L_memmove\$non_lazy_ptr)?}}
-; ARM-LONG: ldr r3, [r3]
+
+; ARM-LONG-MACHO: {{(movw r3, :lower16:L_memmove\$non_lazy_ptr)|(ldr r3, .LCPI)}}
+; ARM-LONG-MACHO: {{(movt r3, :upper16:L_memmove\$non_lazy_ptr)?}}
+; ARM-LONG-MACHO: ldr r3, [r3]
+
+; ARM-LONG-ELF: movw r3, :lower16:memmove
+; ARM-LONG-ELF: movt r3, :upper16:memmove
+
; ARM-LONG: blx r3
; THUMB-LABEL: t3:
; THUMB: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
@@ -121,9 +147,14 @@ define void @t3() nounwind ssp {
define void @t4() nounwind ssp {
; ARM-LABEL: t4:
-; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+
+; ARM-MACHO: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:temp
+; ARM-ELF: movt r0, :upper16:temp
+
; ARM: ldr r1, [r0, #16]
; ARM: str r1, [r0, #4]
; ARM: ldr r1, [r0, #20]
@@ -150,9 +181,14 @@ declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32,
define void @t5() nounwind ssp {
; ARM-LABEL: t5:
-; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+
+; ARM-MACHO: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:temp
+; ARM-ELF: movt r0, :upper16:temp
+
; ARM: ldrh r1, [r0, #16]
; ARM: strh r1, [r0, #4]
; ARM: ldrh r1, [r0, #18]
@@ -185,9 +221,14 @@ define void @t5() nounwind ssp {
define void @t6() nounwind ssp {
; ARM-LABEL: t6:
-; ARM: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+
+; ARM-MACHO: {{(movw r0, :lower16:L_temp\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_temp\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:temp
+; ARM-ELF: movt r0, :upper16:temp
+
; ARM: ldrb r1, [r0, #16]
; ARM: strb r1, [r0, #4]
; ARM: ldrb r1, [r0, #17]
diff --git a/test/CodeGen/ARM/fast-isel-pie.ll b/test/CodeGen/ARM/fast-isel-pie.ll
new file mode 100644
index 000000000000..23a88bdaa22e
--- /dev/null
+++ b/test/CodeGen/ARM/fast-isel-pie.ll
@@ -0,0 +1,19 @@
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=pic -mtriple=armv7-pc-linux-gnueabi | FileCheck %s
+
+@var = global i32 42
+
+define i32* @foo() {
+; CHECK: foo:
+; CHECK: ldr r0, .L[[POOL:.*]]
+; CHECK-NEXT: .L[[ADDR:.*]]:
+; CHECK-NEXT: add r0, pc, r0
+; CHECK-NEXT: bx lr
+
+; CHECK: .L[[POOL]]:
+; CHECK-NEXT: .long var-(.L[[ADDR]]+8)
+
+ ret i32* @var
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 1, !"PIE Level", i32 2}
diff --git a/test/CodeGen/ARM/fast-isel.ll b/test/CodeGen/ARM/fast-isel.ll
index 49460220c47c..502285e85dfd 100644
--- a/test/CodeGen/ARM/fast-isel.ll
+++ b/test/CodeGen/ARM/fast-isel.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
-; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-MACHO
+; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-ELF
; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
; Very basic fast-isel functionality.
@@ -154,9 +154,13 @@ define void @test4() {
; THUMB: adds r1, #1
; THUMB: str r1, [r0]
-; ARM: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr r0, .LCPI)}}
-; ARM: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}
-; ARM: ldr r0, [r0]
+; ARM-MACHO: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr r0, .LCPI)}}
+; ARM-MACHO: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}
+; ARM-MACHO: ldr r0, [r0]
+
+; ARM-ELF: movw r0, :lower16:test4g
+; ARM-ELF: movt r0, :upper16:test4g
+
; ARM: ldr r1, [r0]
; ARM: add r1, r1, #1
; ARM: str r1, [r0]
diff --git a/test/CodeGen/ARM/fast-tail-call.ll b/test/CodeGen/ARM/fast-tail-call.ll
index 6472016c0572..c93028bad50c 100644
--- a/test/CodeGen/ARM/fast-tail-call.ll
+++ b/test/CodeGen/ARM/fast-tail-call.ll
@@ -1,4 +1,5 @@
; RUN: llc -mtriple=thumbv7-linux-gnueabi -O0 < %s | FileCheck %s
+; RUN: llc -mtriple=thumbv8m.base-arm-none-eabi -filetype=obj < %s
; Primarily a non-crash test: Thumbv7 Linux does not have FastISel support,
; which led (via a convoluted route) to DAG nodes after a TC_RETURN that
diff --git a/test/CodeGen/ARM/fp16-promote.ll b/test/CodeGen/ARM/fp16-promote.ll
index 2a2eb8d2b6ba..ebc5934df022 100644
--- a/test/CodeGen/ARM/fp16-promote.ll
+++ b/test/CodeGen/ARM/fp16-promote.ll
@@ -642,6 +642,40 @@ define void @test_maxnum(half* %p, half* %q) #0 {
ret void
}
+; CHECK-ALL-LABEL: test_minnan:
+; CHECK-FP16: vcvtb.f32.f16
+; CHECK-FP16: vcvtb.f32.f16
+; CHECK-LIBCALL: bl __aeabi_h2f
+; CHECK-LIBCALL: bl __aeabi_h2f
+; CHECK-VFP: vmin.f32
+; CHECK-NOVFP: bl __aeabi_fcmpge
+; CHECK-FP16: vcvtb.f16.f32
+; CHECK-LIBCALL: bl __aeabi_f2h
+define void @test_minnan(half* %p) #0 {
+ %a = load half, half* %p, align 2
+ %c = fcmp ult half %a, 1.0
+ %r = select i1 %c, half %a, half 1.0
+ store half %r, half* %p
+ ret void
+}
+
+; CHECK-ALL-LABEL: test_maxnan:
+; CHECK-FP16: vcvtb.f32.f16
+; CHECK-FP16: vcvtb.f32.f16
+; CHECK-LIBCALL: bl __aeabi_h2f
+; CHECK-LIBCALL: bl __aeabi_h2f
+; CHECK-VFP: vmax.f32
+; CHECK-NOVFP: bl __aeabi_fcmple
+; CHECK-FP16: vcvtb.f16.f32
+; CHECK-LIBCALL: bl __aeabi_f2h
+define void @test_maxnan(half* %p) #0 {
+ %a = load half, half* %p, align 2
+ %c = fcmp ugt half %a, 1.0
+ %r = select i1 %c, half %a, half 1.0
+ store half %r, half* %p
+ ret void
+}
+
; CHECK-FP16-LABEL: test_copysign:
; CHECK-FP16: vcvtb.f32.f16
; CHECK-FP16: vcvtb.f32.f16
@@ -889,4 +923,44 @@ define half @test_struct_arg(%struct.dummy %p) {
ret half %a
}
+; CHECK-LABEL: test_uitofp_i32_fadd:
+; CHECK-VFP-DAG: vcvt.f32.u32
+; CHECK-NOVFP-DAG: bl __aeabi_ui2f
+
+; CHECK-FP16-DAG: vcvtb.f16.f32
+; CHECK-FP16-DAG: vcvtb.f32.f16
+; CHECK-LIBCALL-DAG: bl __aeabi_h2f
+; CHECK-LIBCALL-DAG: bl __aeabi_h2f
+
+; CHECK-VFP-DAG: vadd.f32
+; CHECK-NOVFP-DAG: bl __aeabi_fadd
+
+; CHECK-FP16-DAG: vcvtb.f16.f32
+; CHECK-LIBCALL-DAG: bl __aeabi_f2h
+define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 {
+ %c = uitofp i32 %a to half
+ %r = fadd half %b, %c
+ ret half %r
+}
+
+; CHECK-LABEL: test_sitofp_i32_fadd:
+; CHECK-VFP-DAG: vcvt.f32.s32
+; CHECK-NOVFP-DAG: bl __aeabi_i2f
+
+; CHECK-FP16-DAG: vcvtb.f16.f32
+; CHECK-FP16-DAG: vcvtb.f32.f16
+; CHECK-LIBCALL-DAG: bl __aeabi_h2f
+; CHECK-LIBCALL-DAG: bl __aeabi_h2f
+
+; CHECK-VFP-DAG: vadd.f32
+; CHECK-NOVFP-DAG: bl __aeabi_fadd
+
+; CHECK-FP16-DAG: vcvtb.f16.f32
+; CHECK-LIBCALL-DAG: bl __aeabi_f2h
+define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {
+ %c = sitofp i32 %a to half
+ %r = fadd half %b, %c
+ ret half %r
+}
+
attributes #0 = { nounwind }
diff --git a/test/CodeGen/ARM/fp16-v3.ll b/test/CodeGen/ARM/fp16-v3.ll
index 6ed9c9d22c9d..e26455e61e7f 100644
--- a/test/CodeGen/ARM/fp16-v3.ll
+++ b/test/CodeGen/ARM/fp16-v3.ll
@@ -1,14 +1,16 @@
-; RUN: llc -mattr=+fp16 < %s | FileCheck %s --check-prefix=CHECK
+; RUN: llc -mattr=+fp16 < %s | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv7a--none-eabi"
; CHECK-LABEL: test_vec3:
-; CHECK: vcvtb.f32.f16
-; CHECK: vcvt.f32.s32
-; CHECK: vadd.f32
-; CHECK-NEXT: vcvtb.f16.f32 [[SREG:s[0-9]+]], {{.*}}
-; CHECK-NEXT: vmov [[RREG1:r[0-9]+]], [[SREG]]
+; CHECK-DAG: vcvtb.f32.f16 [[SREG1:s[0-9]+]],
+; CHECK-DAG: vcvt.f32.s32 [[SREG2:s[0-9]+]],
+; CHECK-DAG: vcvtb.f16.f32 [[SREG3:s[0-9]+]], [[SREG2]]
+; CHECK-DAG: vcvtb.f32.f16 [[SREG4:s[0-9]+]], [[SREG3]]
+; CHECK: vadd.f32 [[SREG5:s[0-9]+]], [[SREG4]], [[SREG1]]
+; CHECK-NEXT: vcvtb.f16.f32 [[SREG6:s[0-9]+]], [[SREG5]]
+; CHECK-NEXT: vmov [[RREG1:r[0-9]+]], [[SREG6]]
; CHECK-NEXT: uxth [[RREG2:r[0-9]+]], [[RREG1]]
; CHECK-NEXT: pkhbt [[RREG3:r[0-9]+]], [[RREG1]], [[RREG1]], lsl #16
; CHECK-DAG: strh [[RREG1]], [r0, #4]
@@ -25,4 +27,16 @@ define void @test_vec3(<3 x half>* %arr, i32 %i) #0 {
ret void
}
+; CHECK-LABEL: test_bitcast:
+; CHECK: vcvtb.f16.f32
+; CHECK: vcvtb.f16.f32
+; CHECK: vcvtb.f16.f32
+; CHECK: pkhbt
+; CHECK: uxth
+define void @test_bitcast(<3 x half> %inp, <3 x i16>* %arr) #0 {
+ %bc = bitcast <3 x half> %inp to <3 x i16>
+ store <3 x i16> %bc, <3 x i16>* %arr, align 8
+ ret void
+}
+
attributes #0 = { nounwind }
diff --git a/test/CodeGen/ARM/fp16.ll b/test/CodeGen/ARM/fp16.ll
index 73d5c36a9c2f..b2cccd832198 100644
--- a/test/CodeGen/ARM/fp16.ll
+++ b/test/CodeGen/ARM/fp16.ll
@@ -1,9 +1,17 @@
; RUN: llc -mtriple=armv7a--none-eabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-HARDFLOAT-EABI %s
; RUN: llc -mtriple=armv7a--none-gnueabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-HARDFLOAT-GNU %s
-; RUN: llc -mattr=+vfp3,+fp16 < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-FP16 %s
+; RUN: llc -mtriple=armv7a--none-musleabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-HARDFLOAT-GNU %s
; RUN: llc -mtriple=armv8-eabihf < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-ARMV8 %s
; RUN: llc -mtriple=thumbv7m-eabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-SOFTFLOAT-EABI %s
; RUN: llc -mtriple=thumbv7m-gnueabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-SOFTFLOAT-GNU %s
+; RUN: llc -mtriple=thumbv7m-musleabi < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-SOFTFLOAT-GNU %s
+
+;; +fp16 is special: it has f32->f16 (unlike v7), but not f64->f16 (unlike v8).
+;; This exposes unsafe-fp-math optimization opportunities; test that.
+; RUN: llc -mattr=+vfp3,+fp16 < %s |\
+; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-FP16 --check-prefix=CHECK-FP16-SAFE %s
+; RUN: llc -mattr=+vfp3,+fp16 < %s -enable-unsafe-fp-math |\
+; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-FP16 --check-prefix=CHECK-FP16-UNSAFE %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32"
target triple = "armv7---eabihf"
@@ -76,7 +84,10 @@ define i16 @test_to_fp16(double %in) {
; CHECK-HARDFLOAT-GNU: bl __aeabi_d2h
-; CHECK-FP16: bl __aeabi_d2h
+; CHECK-FP16-SAFE: bl __aeabi_d2h
+
+; CHECK-FP16-UNSAFE: vcvt.f32.f64 s0, d0
+; CHECK-FP16-UNSAFE-NEXT: vcvtb.f16.f32 s0, s0
; CHECK-ARMV8: vcvtb.f16.f64 [[TMP:s[0-9]+]], d0
; CHECK-ARMV8: vmov r0, [[TMP]]
diff --git a/test/CodeGen/ARM/globals.ll b/test/CodeGen/ARM/globals.ll
index e6aa2db744d5..399d5208ae2c 100644
--- a/test/CodeGen/ARM/globals.ll
+++ b/test/CodeGen/ARM/globals.ll
@@ -15,7 +15,7 @@ define i32 @test1() {
; DarwinStatic: ldr r0, [r0]
; DarwinStatic: bx lr
-; DarwinStatic: .align 2
+; DarwinStatic: .p2align 2
; DarwinStatic: LCPI0_0:
; DarwinStatic: .long {{_G$}}
@@ -26,12 +26,12 @@ define i32 @test1() {
; DarwinDynamic: ldr r0, [r0]
; DarwinDynamic: bx lr
-; DarwinDynamic: .align 2
+; DarwinDynamic: .p2align 2
; DarwinDynamic: LCPI0_0:
; DarwinDynamic: .long L_G$non_lazy_ptr
; DarwinDynamic: .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
-; DarwinDynamic: .align 2
+; DarwinDynamic: .p2align 2
; DarwinDynamic: L_G$non_lazy_ptr:
; DarwinDynamic: .indirect_symbol _G
; DarwinDynamic: .long 0
@@ -46,12 +46,12 @@ define i32 @test1() {
; DarwinPIC-NOT: ldr
; DarwinPIC: bx lr
-; DarwinPIC: .align 2
+; DarwinPIC: .p2align 2
; DarwinPIC: LCPI0_0:
; DarwinPIC: .long L_G$non_lazy_ptr-(LPC0_0+8)
; DarwinPIC: .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers
-; DarwinPIC: .align 2
+; DarwinPIC: .p2align 2
; DarwinPIC: L_G$non_lazy_ptr:
; DarwinPIC: .indirect_symbol _G
; DarwinPIC: .long 0
@@ -66,7 +66,7 @@ define i32 @test1() {
; LinuxPIC: ldr r0, [r0]
; LinuxPIC: bx lr
-; LinuxPIC: .align 2
+; LinuxPIC: .p2align 2
; LinuxPIC: .LCPI0_0:
; LinuxPIC: .Ltmp0:
; LinuxPIC: .long G(GOT_PREL)-((.LPC0_0+8)-.Ltmp0)
diff --git a/test/CodeGen/ARM/half.ll b/test/CodeGen/ARM/half.ll
index b40eaf638519..ad039b9d6865 100644
--- a/test/CodeGen/ARM/half.ll
+++ b/test/CodeGen/ARM/half.ll
@@ -41,7 +41,7 @@ define float @test_extend32(half* %addr) {
define double @test_extend64(half* %addr) {
; CHECK-LABEL: test_extend64:
-; CHECK-OLD: blx ___extendhfsf2
+; CHECK-OLD: bl ___extendhfsf2
; CHECK-OLD: vcvt.f64.f32
; CHECK-F16: vcvtb.f32.f16
; CHECK-F16: vcvt.f64.f32
@@ -54,7 +54,7 @@ define double @test_extend64(half* %addr) {
define void @test_trunc32(float %in, half* %addr) {
; CHECK-LABEL: test_trunc32:
-; CHECK-OLD: blx ___truncsfhf2
+; CHECK-OLD: bl ___truncsfhf2
; CHECK-F16: vcvtb.f16.f32
; CHECK-V8: vcvtb.f16.f32
%val16 = fptrunc float %in to half
@@ -65,8 +65,8 @@ define void @test_trunc32(float %in, half* %addr) {
define void @test_trunc64(double %in, half* %addr) {
; CHECK-LABEL: test_trunc64:
-; CHECK-OLD: blx ___truncdfhf2
-; CHECK-F16: blx ___truncdfhf2
+; CHECK-OLD: bl ___truncdfhf2
+; CHECK-F16: bl ___truncdfhf2
; CHECK-V8: vcvtb.f16.f64
%val16 = fptrunc double %in to half
store half %val16, half* %addr
diff --git a/test/CodeGen/ARM/hello.ll b/test/CodeGen/ARM/hello.ll
index 08e6104bbcf6..b03a60ab60c9 100644
--- a/test/CodeGen/ARM/hello.ll
+++ b/test/CodeGen/ARM/hello.ll
@@ -16,9 +16,11 @@ define i32 @main() {
declare i32 @puts(i8*)
+; CHECK-LABEL: main
; CHECK: mov
; CHECK-NOT: mov
+; CHECK-FP-ELIM-LABEL: main
; CHECK-FP-ELIM: mov
; CHECK-FP-ELIM: mov
; CHECK-FP-ELIM-NOT: mov
diff --git a/test/CodeGen/ARM/ifcvt-iter-indbr.ll b/test/CodeGen/ARM/ifcvt-iter-indbr.ll
index a96b6e8a1e83..967d6ebce277 100644
--- a/test/CodeGen/ARM/ifcvt-iter-indbr.ll
+++ b/test/CodeGen/ARM/ifcvt-iter-indbr.ll
@@ -27,7 +27,7 @@ declare i8* @bar(i32, i8*, i8*)
; CHECK-NEXT: LBB{{[0-9_]+}}:
; CHECK-NEXT: movw r0, #4567
; CHECK-NEXT: [[FOOCALL]]:
-; CHECK-NEXT: blx _foo
+; CHECK-NEXT: bl _foo
;
; CHECK-PROB: BB#0:
; CHECK-PROB: Successors according to CFG: BB#1({{[0-9a-fx/= ]+}}50.00%) BB#2({{[0-9a-fx/= ]+}}25.00%) BB#4({{[0-9a-fx/= ]+}}25.00%)
diff --git a/test/CodeGen/ARM/inlineasm-X-allocation.ll b/test/CodeGen/ARM/inlineasm-X-allocation.ll
new file mode 100644
index 000000000000..e88d668f5ccf
--- /dev/null
+++ b/test/CodeGen/ARM/inlineasm-X-allocation.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=armv7-none-eabi -mattr=-neon,-vfpv2 %s -o - | FileCheck %s -check-prefix=novfp
+; RUN: llc -mtriple=armv7-none-eabi -mattr=+neon %s -float-abi=hard -o - | FileCheck %s -check-prefix=vfp
+
+; vfp-LABEL: f1
+; vfp-CHECK: vadd.f32 s0, s0, s0
+
+; In the novfp case, the compiler is forced to assign a core register.
+; Although this register class can't be used with the vadd.f32 instruction,
+; the compiler behaved as expected since it is allowed to emit anything.
+
+; novfp-LABEL: f1
+; novfp-CHECK: vadd.f32 r0, r0, r0
+
+; This can be generated by a function such as:
+; void f1(float f) {asm volatile ("add.f32 $0, $0, $0" : : "X" (f));}
+
+define arm_aapcs_vfpcc void @f1(float %f) {
+entry:
+ call void asm sideeffect "vadd.f32 $0, $0, $0", "X" (float %f) nounwind
+ ret void
+}
diff --git a/test/CodeGen/ARM/inlineasm-X-constraint.ll b/test/CodeGen/ARM/inlineasm-X-constraint.ll
new file mode 100644
index 000000000000..d3d53df11b56
--- /dev/null
+++ b/test/CodeGen/ARM/inlineasm-X-constraint.ll
@@ -0,0 +1,157 @@
+; RUN: llc -mtriple=armv7-none-eabi -mattr=+neon < %s -o - | FileCheck %s
+
+; The following functions test the use case where an X constraint is used to
+; add a dependency between an assembly instruction (vmsr in this case) and
+; another instruction. In each function, we use a different type for the
+; X constraint argument.
+;
+; We can something similar from the following C code:
+; double f1(double f, int pscr_value) {
+; asm volatile("vmsr fpscr,%0" : "=X" ((f)): "r" (pscr_value));
+; return f+f;
+; }
+
+; CHECK-LABEL: f1
+; CHECK: vmsr fpscr
+; CHECK: vadd.f64
+
+define arm_aapcs_vfpcc double @f1(double %f, i32 %pscr_value) {
+entry:
+ %f.addr = alloca double, align 8
+ store double %f, double* %f.addr, align 8
+ call void asm sideeffect "vmsr fpscr,$1", "=*X,r"(double* nonnull %f.addr, i32 %pscr_value) nounwind
+ %0 = load double, double* %f.addr, align 8
+ %add = fadd double %0, %0
+ ret double %add
+}
+
+; int f2(int f, int pscr_value) {
+; asm volatile("vmsr fpscr,%0" : "=X" ((f)): "r" (pscr_value));
+; return f+f;
+; }
+
+; CHECK-LABEL: f2
+; CHECK: vmsr fpscr
+; CHECK: mul
+define arm_aapcs_vfpcc i32 @f2(i32 %f, i32 %pscr_value) {
+entry:
+ %f.addr = alloca i32, align 4
+ store i32 %f, i32* %f.addr, align 4
+ call void asm sideeffect "vmsr fpscr,$1", "=*X,r"(i32* nonnull %f.addr, i32 %pscr_value) nounwind
+ %0 = load i32, i32* %f.addr, align 4
+ %mul = mul i32 %0, %0
+ ret i32 %mul
+}
+
+
+; int f3(int f, int pscr_value) {
+; asm volatile("vmsr fpscr,%0" : "=X" ((f)): "r" (pscr_value));
+; return f+f;
+; }
+
+; typedef signed char int8_t;
+; typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t;
+; void f3 (void)
+; {
+; int8x8_t vector_res_int8x8;
+; unsigned int fpscr;
+; asm volatile ("vmsr fpscr,%1" : "=X" ((vector_res_int8x8)) : "r" (fpscr));
+; return vector_res_int8x8 * vector_res_int8x8;
+; }
+
+; CHECK-LABEL: f3
+; CHECK: vmsr fpscr
+; CHECK: vmul.i8
+define arm_aapcs_vfpcc <8 x i8> @f3() {
+entry:
+ %vector_res_int8x8 = alloca <8 x i8>, align 8
+ %0 = getelementptr inbounds <8 x i8>, <8 x i8>* %vector_res_int8x8, i32 0, i32 0
+ call void asm sideeffect "vmsr fpscr,$1", "=*X,r"(<8 x i8>* nonnull %vector_res_int8x8, i32 undef) nounwind
+ %1 = load <8 x i8>, <8 x i8>* %vector_res_int8x8, align 8
+ %mul = mul <8 x i8> %1, %1
+ ret <8 x i8> %mul
+}
+
+; We can emit integer constants.
+; We can get this from:
+; void f() {
+; int x = 2;
+; asm volatile ("add r0, r0, %0" : : "X" (x));
+; }
+;
+; CHECK-LABEL: f4
+; CHECK: add r0, r0, #2
+define void @f4() {
+entry:
+ tail call void asm sideeffect "add r0, r0, $0", "X"(i32 2)
+ ret void
+}
+
+; We can emit function labels. This is equivalent to the following C code:
+; void f(void) {
+; void (*x)(void) = &foo;
+; asm volatile ("bl %0" : : "X" (x));
+; }
+; CHECK-LABEL: f5
+; CHECK: bl f4
+define void @f5() {
+entry:
+ tail call void asm sideeffect "bl $0", "X"(void ()* nonnull @f4)
+ ret void
+}
+
+declare void @foo(...)
+
+; This tests the behavior of the X constraint when used on functions pointers,
+; or functions with a cast. In the first asm call we figure out that this
+; is a function pointer and emit the label. However, in the second asm call
+; we can't see through the bitcast and we end up having to lower this constraint
+; to something else. This is not ideal, but it is a correct behaviour according
+; to the definition of the X constraint.
+;
+; In this case (and other cases where we could have emitted something else),
+; what we're doing with the X constraint is not particularly useful either,
+; since the user could have used "r" in this situation for the same effect.
+
+; CHECK-LABEL: f6
+; CHECK: bl foo
+; CHECK: bl r
+
+define void @f6() nounwind {
+entry:
+ tail call void asm sideeffect "bl $0", "X"(void (...)* @foo) nounwind
+ tail call void asm sideeffect "bl $0", "X"(void (...)* bitcast (void ()* @f4 to void (...)*)) nounwind
+ ret void
+}
+
+; The following IR can be generated from C code with a function like:
+; void a() {
+; void* a = &&A;
+; asm volatile ("bl %0" : : "X" (a));
+; A:
+; return;
+; }
+;
+; Ideally this would give the block address of bb, but it requires us to see
+; through blockaddress, which we can't do at the moment. This might break some
+; existing use cases where a user would expect to get a block label and instead
+; gets the block address in a register. However, note that according to the
+; "no constraints" definition this behaviour is correct (although not very nice).
+
+; CHECK-LABEL: f7
+; CHECK: bl
+define void @f7() {
+ call void asm sideeffect "bl $0", "X"( i8* blockaddress(@f7, %bb) )
+ br label %bb
+bb:
+ ret void
+}
+
+; If we use a constraint "=*X", we should get a store back to *%x (in r0).
+; CHECK-LABEL: f8
+; CHECK: str r{{.*}}, [r0]
+define void @f8(i32 *%x) {
+entry:
+ tail call void asm sideeffect "add $0, r0, r0", "=*X"(i32 *%x)
+ ret void
+}
diff --git a/test/CodeGen/ARM/inlineasm-ldr-pseudo.ll b/test/CodeGen/ARM/inlineasm-ldr-pseudo.ll
index f63e4b0b3a17..98665f056a21 100644
--- a/test/CodeGen/ARM/inlineasm-ldr-pseudo.ll
+++ b/test/CodeGen/ARM/inlineasm-ldr-pseudo.ll
@@ -9,9 +9,9 @@
; CHECK: 0: 00 00 9f e5 ldr r0, [pc]
; CHECK: 4: 0e f0 a0 e1 mov pc, lr
; Make sure the constant pool entry comes after the return
-; CHECK: 8: 01 00 00 00
+; CHECK: 8: 78 56 34 12
define i32 @foo() nounwind {
entry:
- %0 = tail call i32 asm sideeffect "ldr $0,=1", "=r"() nounwind
+ %0 = tail call i32 asm sideeffect "ldr $0,=0x12345678", "=r"() nounwind
ret i32 %0
}
diff --git a/test/CodeGen/ARM/inlineasm3.ll b/test/CodeGen/ARM/inlineasm3.ll
index eb7ba59b69bf..f725f534c73d 100644
--- a/test/CodeGen/ARM/inlineasm3.ll
+++ b/test/CodeGen/ARM/inlineasm3.ll
@@ -6,6 +6,7 @@
define void @t() nounwind {
entry:
+; CHECK-LABEL: t
; CHECK: vmov.I64 q15, #0
; CHECK: vmov.32 d30[0],
; CHECK: vmov q8, q15
@@ -19,6 +20,7 @@ entry:
define void @t2() nounwind {
entry:
+; CHECK-LABEL: t2
; CHECK: vmov d30, d16
; CHECK: vmov.32 r0, d30[0]
%asmtmp2 = tail call i32 asm sideeffect "vmov d30, $1\0Avmov.32 $0, d30[0]\0A", "=r,w,~{d30}"(<2 x i32> undef) nounwind
@@ -64,7 +66,7 @@ ret i32 0
define float @t6(float %y) nounwind {
entry:
-; CHECK: t6
+; CHECK-LABEL: t6
; CHECK: flds s15, s0
%0 = tail call float asm "flds s15, $0", "=x"() nounwind
ret float %0
@@ -74,7 +76,7 @@ entry:
define double @t7(double %y) nounwind {
entry:
-; CHECK: t7
+; CHECK-LABEL: t7
; CHECK: flds s15, d0
%0 = tail call double asm "flds s15, $0", "=x"() nounwind
ret double %0
@@ -84,7 +86,7 @@ entry:
define float @t8(float %y) nounwind {
entry:
-; CHECK: t8
+; CHECK-LABEL: t8
; CHECK: flds s15, s0
%0 = tail call float asm "flds s15, $0", "=t"() nounwind
ret float %0
@@ -94,7 +96,7 @@ entry:
define i32 @t9(i32 %r0) nounwind {
entry:
-; CHECK: t9
+; CHECK-LABEL: t9
; CHECK: movw r0, #27182
%0 = tail call i32 asm "movw $0, $1", "=r,j"(i32 27182) nounwind
ret i32 %0
@@ -104,7 +106,7 @@ entry:
define void @t10(i8* %f, i32 %g) nounwind {
entry:
-; CHECK: t10
+; CHECK-LABEL: t10
; CHECK: str r1, [r0]
%f.addr = alloca i8*, align 4
store i8* %f, i8** %f.addr, align 4
@@ -116,8 +118,19 @@ entry:
define <4 x i32> @t11(i32* %p) nounwind {
entry:
-; CHECK: t11
+; CHECK-LABEL: t11
; CHECK: vld1.s32 {d16[], d17[]}, [r0]
%0 = tail call <4 x i32> asm "vld1.s32 {${0:e}[], ${0:f}[]}, [$1]", "=w,r"(i32* %p) nounwind
ret <4 x i32> %0
}
+
+; Bugzilla PR26038
+
+define i32 @fn1() local_unnamed_addr nounwind {
+; CHECK-LABEL: fn1
+entry:
+; CHECK: mov [[addr:r[0-9]+]], #5
+; CHECK: ldrh {{.*}}[[addr]]
+ %0 = tail call i32 asm "ldrh $0, $1", "=r,*Q"(i8* inttoptr (i32 5 to i8*)) nounwind
+ ret i32 %0
+}
diff --git a/test/CodeGen/ARM/interrupt-attr.ll b/test/CodeGen/ARM/interrupt-attr.ll
index 43bd5815a558..794f672534dc 100644
--- a/test/CodeGen/ARM/interrupt-attr.ll
+++ b/test/CodeGen/ARM/interrupt-attr.ll
@@ -35,15 +35,15 @@ define arm_aapcscc void @irq_fn() alignstack(8) "interrupt"="IRQ" {
; Normal AAPCS function (r0-r3 pushed onto stack by hardware, lr set to
; appropriate sentinel so no special return needed).
; CHECK-M-LABEL: irq_fn:
-; CHECK-M: push.w {r4, r7, r11, lr}
-; CHECK-M: add.w r11, sp, #8
+; CHECK-M: push {r4, r6, r7, lr}
+; CHECK-M: add r7, sp, #8
; CHECK-M: mov r4, sp
; CHECK-M: bfc r4, #0, #3
; CHECK-M: mov sp, r4
; CHECK-M: bl _bar
-; CHECK-M: sub.w r4, r11, #8
+; CHECK-M: sub.w r4, r7, #8
; CHECK-M: mov sp, r4
-; CHECK-M: pop.w {r4, r7, r11, pc}
+; CHECK-M: pop {r4, r6, r7, pc}
call arm_aapcscc void @bar()
ret void
diff --git a/test/CodeGen/ARM/interval-update-remat.ll b/test/CodeGen/ARM/interval-update-remat.ll
new file mode 100644
index 000000000000..6391d4c29604
--- /dev/null
+++ b/test/CodeGen/ARM/interval-update-remat.ll
@@ -0,0 +1,162 @@
+; RUN: llc -verify-regalloc < %s
+; PR27275: When enabling remat for vreg defined by PHIs, make sure the update
+; of the live range removes dead phi. Otherwise, we may end up with PHIs with
+; incorrect operands and that will trigger assertions or verifier failures
+; in later passes.
+
+target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+target triple = "thumbv7-apple-ios9.0.0"
+
+%class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326 = type { %class.MockTransportClientSocketPool.0.225.275.1300.2325, i32 }
+%class.MockTransportClientSocketPool.0.225.275.1300.2325 = type { i8 }
+%class.StaticSocketDataProvider.6.231.281.1306.2331 = type { i8, %struct.MockConnect.5.230.280.1305.2330 }
+%struct.MockConnect.5.230.280.1305.2330 = type { %class.IPEndPoint.4.229.279.1304.2329 }
+%class.IPEndPoint.4.229.279.1304.2329 = type { %class.IPAddress.3.228.278.1303.2328 }
+%class.IPAddress.3.228.278.1303.2328 = type { %"class.(anonymous namespace)::vector.2.227.277.1302.2327" }
+%"class.(anonymous namespace)::vector.2.227.277.1302.2327" = type { i8 }
+%class.TestCompletionCallback.9.234.284.1309.2334 = type { %class.TestCompletionCallbackTemplate.8.233.283.1308.2333, i32 }
+%class.TestCompletionCallbackTemplate.8.233.283.1308.2333 = type { i32 }
+%class.AssertionResult.24.249.299.1324.2349 = type { i8, %class.scoped_ptr.23.248.298.1323.2348 }
+%class.scoped_ptr.23.248.298.1323.2348 = type { %class.Trans_NS___1_basic_string.18.243.293.1318.2343* }
+%class.Trans_NS___1_basic_string.18.243.293.1318.2343 = type { %class.Trans_NS___1___libcpp_compressed_pair_imp.17.242.292.1317.2342 }
+%class.Trans_NS___1___libcpp_compressed_pair_imp.17.242.292.1317.2342 = type { %"struct.Trans_NS___1_basic_string<char, int, int>::__rep.16.241.291.1316.2341" }
+%"struct.Trans_NS___1_basic_string<char, int, int>::__rep.16.241.291.1316.2341" = type { %"struct.Trans_NS___1_basic_string<char, int, int>::__long.15.240.290.1315.2340" }
+%"struct.Trans_NS___1_basic_string<char, int, int>::__long.15.240.290.1315.2340" = type { i64, i32 }
+%class.AssertHelper.10.235.285.1310.2335 = type { i8 }
+%class.Message.13.238.288.1313.2338 = type { %class.scoped_ptr.0.12.237.287.1312.2337 }
+%class.scoped_ptr.0.12.237.287.1312.2337 = type { %"class.(anonymous namespace)::basic_stringstream.11.236.286.1311.2336"* }
+%"class.(anonymous namespace)::basic_stringstream.11.236.286.1311.2336" = type { i8 }
+%class.scoped_refptr.19.244.294.1319.2344 = type { i8 }
+%class.BoundNetLog.20.245.295.1320.2345 = type { i32 }
+%struct.MockReadWrite.7.232.282.1307.2332 = type { i32 }
+%"class.(anonymous namespace)::basic_iostream.22.247.297.1322.2347" = type { i8 }
+%class.ClientSocketHandle.14.239.289.1314.2339 = type { i8 }
+%"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346" = type { i8 }
+
+@.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1
+
+define void @_ZN53SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test6m_fn10Ev(%class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326* %this) align 2 {
+entry:
+ %socket_data = alloca %class.StaticSocketDataProvider.6.231.281.1306.2331, align 1
+ %agg.tmp = alloca %struct.MockConnect.5.230.280.1305.2330, align 1
+ %callback = alloca %class.TestCompletionCallback.9.234.284.1309.2334, align 4
+ %gtest_ar = alloca %class.AssertionResult.24.249.299.1324.2349, align 4
+ %temp.lvalue = alloca %class.AssertHelper.10.235.285.1310.2335, align 1
+ %agg.tmp10 = alloca %class.Message.13.238.288.1313.2338, align 4
+ %ref.tmp = alloca %class.Trans_NS___1_basic_string.18.243.293.1318.2343, align 4
+ %agg.tmp16 = alloca %class.scoped_refptr.19.244.294.1319.2344, align 1
+ %agg.tmp18 = alloca %class.BoundNetLog.20.245.295.1320.2345, align 4
+ %call2 = call %class.StaticSocketDataProvider.6.231.281.1306.2331* @_ZN24StaticSocketDataProviderC1EP13MockReadWritejS1_j(%class.StaticSocketDataProvider.6.231.281.1306.2331* nonnull %socket_data, %struct.MockReadWrite.7.232.282.1307.2332* undef, i32 1, %struct.MockReadWrite.7.232.282.1307.2332* null, i32 0)
+ %call3 = call %struct.MockConnect.5.230.280.1305.2330* @_ZN11MockConnectC1Ev(%struct.MockConnect.5.230.280.1305.2330* nonnull %agg.tmp)
+ call void @_ZN24StaticSocketDataProvider5m_fn8E11MockConnect(%class.StaticSocketDataProvider.6.231.281.1306.2331* nonnull %socket_data, %struct.MockConnect.5.230.280.1305.2330* nonnull %agg.tmp)
+ %call5 = call %class.TestCompletionCallback.9.234.284.1309.2334* @_ZN22TestCompletionCallbackC1Ev(%class.TestCompletionCallback.9.234.284.1309.2334* nonnull %callback)
+ %transport_socket_pool_ = getelementptr inbounds %class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326, %class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326* %this, i32 0, i32 0
+ %call6 = call i32 @_ZN29MockTransportClientSocketPool5m_fn9Ev(%class.MockTransportClientSocketPool.0.225.275.1300.2325* %transport_socket_pool_)
+ call void @_Z11CmpHelperEQPcS_xx(%class.AssertionResult.24.249.299.1324.2349* nonnull sret %gtest_ar, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i64 0, i64 undef)
+ %tmp = load i8, i8* undef, align 4
+ %tobool.i = icmp eq i8 %tmp, 0
+ br i1 %tobool.i, label %if.else, label %if.end
+
+if.else: ; preds = %entry
+ br i1 undef, label %_ZN15AssertionResult5m_fn6Ev.exit, label %cond.true.i
+
+cond.true.i: ; preds = %if.else
+ %call4.i = call i8* @_ZN25Trans_NS___1_basic_stringIciiE5m_fn1Ev(%class.Trans_NS___1_basic_string.18.243.293.1318.2343* nonnull undef)
+ br label %_ZN15AssertionResult5m_fn6Ev.exit
+
+_ZN15AssertionResult5m_fn6Ev.exit: ; preds = %cond.true.i, %if.else
+ %cond.i = phi i8* [ %call4.i, %cond.true.i ], [ getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), %if.else ]
+ %call9 = call %class.AssertHelper.10.235.285.1310.2335* @_ZN12AssertHelperC1EPKc(%class.AssertHelper.10.235.285.1310.2335* nonnull %temp.lvalue, i8* %cond.i)
+ %call11 = call %class.Message.13.238.288.1313.2338* @_ZN7MessageC1Ev(%class.Message.13.238.288.1313.2338* nonnull %agg.tmp10)
+ call void @_ZN12AssertHelperaSE7Message(%class.AssertHelper.10.235.285.1310.2335* nonnull %temp.lvalue, %class.Message.13.238.288.1313.2338* nonnull %agg.tmp10)
+ %call.i.i.i.i27 = call zeroext i1 @_Z6IsTruev()
+ %brmerge = or i1 false, undef
+ br i1 %brmerge, label %_ZN7MessageD1Ev.exit33, label %delete.notnull.i.i.i.i32
+
+delete.notnull.i.i.i.i32: ; preds = %_ZN15AssertionResult5m_fn6Ev.exit
+ %call.i.i.i.i.i.i31 = call %"class.(anonymous namespace)::basic_iostream.22.247.297.1322.2347"* @_ZN12_GLOBAL__N_114basic_iostreamD2Ev(%"class.(anonymous namespace)::basic_iostream.22.247.297.1322.2347"* undef)
+ call void @_ZdlPv(i8* undef)
+ br label %_ZN7MessageD1Ev.exit33
+
+_ZN7MessageD1Ev.exit33: ; preds = %delete.notnull.i.i.i.i32, %_ZN15AssertionResult5m_fn6Ev.exit
+ %call13 = call %class.AssertHelper.10.235.285.1310.2335* @_ZN12AssertHelperD1Ev(%class.AssertHelper.10.235.285.1310.2335* nonnull %temp.lvalue)
+ br label %if.end
+
+if.end: ; preds = %_ZN7MessageD1Ev.exit33, %entry
+ %message_.i.i = getelementptr inbounds %class.AssertionResult.24.249.299.1324.2349, %class.AssertionResult.24.249.299.1324.2349* %gtest_ar, i32 0, i32 1
+ %call.i.i.i = call %class.scoped_ptr.23.248.298.1323.2348* @_ZN10scoped_ptrI25Trans_NS___1_basic_stringIciiEED2Ev(%class.scoped_ptr.23.248.298.1323.2348* %message_.i.i)
+ call void @llvm.memset.p0i8.i32(i8* null, i8 0, i32 12, i32 4, i1 false)
+ call void @_ZN25Trans_NS___1_basic_stringIciiE5m_fn2Ev(%class.Trans_NS___1_basic_string.18.243.293.1318.2343* nonnull %ref.tmp)
+ call void @_Z19CreateSOCKSv5Paramsv(%class.scoped_refptr.19.244.294.1319.2344* nonnull sret %agg.tmp16)
+ %callback_.i = getelementptr inbounds %class.TestCompletionCallback.9.234.284.1309.2334, %class.TestCompletionCallback.9.234.284.1309.2334* %callback, i32 0, i32 1
+ %pool_ = getelementptr inbounds %class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326, %class.SOCKSClientSocketPoolTest_AsyncSOCKSConnectError_Test.1.226.276.1301.2326* %this, i32 0, i32 1
+ %tmp1 = getelementptr inbounds %class.BoundNetLog.20.245.295.1320.2345, %class.BoundNetLog.20.245.295.1320.2345* %agg.tmp18, i32 0, i32 0
+ store i32 0, i32* %tmp1, align 4
+ call void @_ZN18ClientSocketHandle5m_fn3IPiEEvRK25Trans_NS___1_basic_stringIciiE13scoped_refptr15RequestPriorityN16ClientSocketPool13RespectLimitsERiT_11BoundNetLog(%class.ClientSocketHandle.14.239.289.1314.2339* nonnull undef, %class.Trans_NS___1_basic_string.18.243.293.1318.2343* nonnull dereferenceable(12) %ref.tmp, %class.scoped_refptr.19.244.294.1319.2344* nonnull %agg.tmp16, i32 0, i32 1, i32* nonnull dereferenceable(4) %callback_.i, i32* %pool_, %class.BoundNetLog.20.245.295.1320.2345* nonnull %agg.tmp18)
+ %call19 = call %class.BoundNetLog.20.245.295.1320.2345* @_ZN11BoundNetLogD1Ev(%class.BoundNetLog.20.245.295.1320.2345* nonnull %agg.tmp18)
+ call void @_Z11CmpHelperEQPcS_xx(%class.AssertionResult.24.249.299.1324.2349* nonnull sret undef, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i32 0, i32 0), i64 -1, i64 0)
+ br i1 undef, label %if.then.i.i.i.i, label %_ZN7MessageD1Ev.exit
+
+if.then.i.i.i.i: ; preds = %if.end
+ %tmp2 = load %"class.(anonymous namespace)::basic_stringstream.11.236.286.1311.2336"*, %"class.(anonymous namespace)::basic_stringstream.11.236.286.1311.2336"** undef, align 4
+ br label %_ZN7MessageD1Ev.exit
+
+_ZN7MessageD1Ev.exit: ; preds = %if.then.i.i.i.i, %if.end
+ %connect_.i.i = getelementptr inbounds %class.StaticSocketDataProvider.6.231.281.1306.2331, %class.StaticSocketDataProvider.6.231.281.1306.2331* %socket_data, i32 0, i32 1
+ %tmp3 = bitcast %struct.MockConnect.5.230.280.1305.2330* %connect_.i.i to %"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346"*
+ %call.i.i.i.i.i.i.i.i.i.i = call %"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346"* @_ZN12_GLOBAL__N_113__vector_baseD2Ev(%"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346"* %tmp3)
+ ret void
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start(i64, i8* nocapture) #0
+
+declare %class.StaticSocketDataProvider.6.231.281.1306.2331* @_ZN24StaticSocketDataProviderC1EP13MockReadWritejS1_j(%class.StaticSocketDataProvider.6.231.281.1306.2331* returned, %struct.MockReadWrite.7.232.282.1307.2332*, i32, %struct.MockReadWrite.7.232.282.1307.2332*, i32) unnamed_addr
+
+declare void @_ZN24StaticSocketDataProvider5m_fn8E11MockConnect(%class.StaticSocketDataProvider.6.231.281.1306.2331*, %struct.MockConnect.5.230.280.1305.2330*)
+
+declare %struct.MockConnect.5.230.280.1305.2330* @_ZN11MockConnectC1Ev(%struct.MockConnect.5.230.280.1305.2330* returned) unnamed_addr
+
+declare %class.TestCompletionCallback.9.234.284.1309.2334* @_ZN22TestCompletionCallbackC1Ev(%class.TestCompletionCallback.9.234.284.1309.2334* returned) unnamed_addr
+
+declare i32 @_ZN29MockTransportClientSocketPool5m_fn9Ev(%class.MockTransportClientSocketPool.0.225.275.1300.2325*)
+
+declare %class.AssertHelper.10.235.285.1310.2335* @_ZN12AssertHelperC1EPKc(%class.AssertHelper.10.235.285.1310.2335* returned, i8*) unnamed_addr
+
+declare void @_ZN12AssertHelperaSE7Message(%class.AssertHelper.10.235.285.1310.2335*, %class.Message.13.238.288.1313.2338*)
+
+declare %class.Message.13.238.288.1313.2338* @_ZN7MessageC1Ev(%class.Message.13.238.288.1313.2338* returned) unnamed_addr
+
+declare %class.AssertHelper.10.235.285.1310.2335* @_ZN12AssertHelperD1Ev(%class.AssertHelper.10.235.285.1310.2335* returned) unnamed_addr
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end(i64, i8* nocapture) #0
+
+declare void @_ZN18ClientSocketHandle5m_fn3IPiEEvRK25Trans_NS___1_basic_stringIciiE13scoped_refptr15RequestPriorityN16ClientSocketPool13RespectLimitsERiT_11BoundNetLog(%class.ClientSocketHandle.14.239.289.1314.2339*, %class.Trans_NS___1_basic_string.18.243.293.1318.2343* dereferenceable(12), %class.scoped_refptr.19.244.294.1319.2344*, i32, i32, i32* dereferenceable(4), i32*, %class.BoundNetLog.20.245.295.1320.2345*)
+
+declare void @_Z19CreateSOCKSv5Paramsv(%class.scoped_refptr.19.244.294.1319.2344* sret)
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0
+
+declare %class.BoundNetLog.20.245.295.1320.2345* @_ZN11BoundNetLogD1Ev(%class.BoundNetLog.20.245.295.1320.2345* returned) unnamed_addr
+
+declare %class.scoped_refptr.19.244.294.1319.2344* @_ZN13scoped_refptrD1Ev(%class.scoped_refptr.19.244.294.1319.2344* returned) unnamed_addr
+
+declare %"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346"* @_ZN12_GLOBAL__N_113__vector_baseD2Ev(%"class.(anonymous namespace)::__vector_base.21.246.296.1321.2346"* returned) unnamed_addr
+
+declare i8* @_ZN25Trans_NS___1_basic_stringIciiE5m_fn1Ev(%class.Trans_NS___1_basic_string.18.243.293.1318.2343*)
+
+declare zeroext i1 @_Z6IsTruev()
+
+declare void @_ZdlPv(i8*)
+
+declare %"class.(anonymous namespace)::basic_iostream.22.247.297.1322.2347"* @_ZN12_GLOBAL__N_114basic_iostreamD2Ev(%"class.(anonymous namespace)::basic_iostream.22.247.297.1322.2347"* returned) unnamed_addr
+
+declare %class.scoped_ptr.23.248.298.1323.2348* @_ZN10scoped_ptrI25Trans_NS___1_basic_stringIciiEED2Ev(%class.scoped_ptr.23.248.298.1323.2348* readonly returned) unnamed_addr align 2
+
+declare void @_Z11CmpHelperEQPcS_xx(%class.AssertionResult.24.249.299.1324.2349* sret, i8*, i8*, i64, i64)
+
+declare void @_ZN25Trans_NS___1_basic_stringIciiE5m_fn2Ev(%class.Trans_NS___1_basic_string.18.243.293.1318.2343*)
+
+attributes #0 = { argmemonly nounwind }
diff --git a/test/CodeGen/ARM/intrinsics-coprocessor.ll b/test/CodeGen/ARM/intrinsics-coprocessor.ll
new file mode 100644
index 000000000000..8fea49b39fb6
--- /dev/null
+++ b/test/CodeGen/ARM/intrinsics-coprocessor.ll
@@ -0,0 +1,79 @@
+; RUN: llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 | FileCheck %s
+; RUN: llc < %s -march=thumb -mtriple=thumbv7-eabi -mcpu=cortex-a8 | FileCheck %s
+
+define void @coproc(i8* %i) nounwind {
+entry:
+ ; CHECK: mrc p7, #1, r{{[0-9]+}}, c1, c1, #4
+ %0 = tail call i32 @llvm.arm.mrc(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
+ ; CHECK: mcr p7, #1, r{{[0-9]+}}, c1, c1, #4
+ tail call void @llvm.arm.mcr(i32 7, i32 1, i32 %0, i32 1, i32 1, i32 4) nounwind
+ ; CHECK: mrc2 p7, #1, r{{[0-9]+}}, c1, c1, #4
+ %1 = tail call i32 @llvm.arm.mrc2(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
+ ; CHECK: mcr2 p7, #1, r{{[0-9]+}}, c1, c1, #4
+ tail call void @llvm.arm.mcr2(i32 7, i32 1, i32 %1, i32 1, i32 1, i32 4) nounwind
+ ; CHECK: mcrr p7, #1, r{{[0-9]+}}, r{{[0-9]+}}, c1
+ tail call void @llvm.arm.mcrr(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
+ ; CHECK: mcrr2 p7, #1, r{{[0-9]+}}, r{{[0-9]+}}, c1
+ tail call void @llvm.arm.mcrr2(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
+ ; CHECK: cdp p7, #3, c1, c1, c1, #5
+ tail call void @llvm.arm.cdp(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
+ ; CHECK: cdp2 p7, #3, c1, c1, c1, #5
+ tail call void @llvm.arm.cdp2(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
+ ; CHECK: ldc p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.ldc(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: ldcl p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.ldcl(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: ldc2 p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.ldc2(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: ldc2l p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.ldc2l(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: stc p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.stc(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: stcl p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.stcl(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: stc2 p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.stc2(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: stc2l p7, c3, [r{{[0-9]+}}]
+ tail call void @llvm.arm.stc2l(i32 7, i32 3, i8* %i) nounwind
+ ; CHECK: mrrc p1, #2, r{{[0-9]+}}, r{{[0-9]+}}, c3
+ %2 = tail call { i32, i32 } @llvm.arm.mrrc(i32 1, i32 2, i32 3) nounwind
+ ; CHECK: mrrc2 p1, #2, r{{[0-9]+}}, r{{[0-9]+}}, c3
+ %3 = tail call { i32, i32 } @llvm.arm.mrrc2(i32 1, i32 2, i32 3) nounwind
+ ret void
+}
+
+declare void @llvm.arm.ldc(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.ldcl(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.ldc2(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.ldc2l(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.stc(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.stcl(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.stc2(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.stc2l(i32, i32, i8*) nounwind
+
+declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind
+
+declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind
+
+declare void @llvm.arm.mcrr2(i32, i32, i32, i32, i32) nounwind
+
+declare void @llvm.arm.mcrr(i32, i32, i32, i32, i32) nounwind
+
+declare void @llvm.arm.mcr2(i32, i32, i32, i32, i32, i32) nounwind
+
+declare i32 @llvm.arm.mrc2(i32, i32, i32, i32, i32) nounwind
+
+declare void @llvm.arm.mcr(i32, i32, i32, i32, i32, i32) nounwind
+
+declare i32 @llvm.arm.mrc(i32, i32, i32, i32, i32) nounwind
+
+declare { i32, i32 } @llvm.arm.mrrc(i32, i32, i32) nounwind
+
+declare { i32, i32 } @llvm.arm.mrrc2(i32, i32, i32) nounwind
diff --git a/test/CodeGen/ARM/intrinsics.ll b/test/CodeGen/ARM/intrinsics.ll
deleted file mode 100644
index 54cc3e0a027c..000000000000
--- a/test/CodeGen/ARM/intrinsics.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; RUN: llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 | FileCheck %s
-; RUN: llc < %s -march=thumb -mtriple=thumbv7-eabi -mcpu=cortex-a8 | FileCheck %s
-
-define void @coproc() nounwind {
-entry:
- ; CHECK: mrc
- %0 = tail call i32 @llvm.arm.mrc(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
- ; CHECK: mcr
- tail call void @llvm.arm.mcr(i32 7, i32 1, i32 %0, i32 1, i32 1, i32 4) nounwind
- ; CHECK: mrc2
- %1 = tail call i32 @llvm.arm.mrc2(i32 7, i32 1, i32 1, i32 1, i32 4) nounwind
- ; CHECK: mcr2
- tail call void @llvm.arm.mcr2(i32 7, i32 1, i32 %1, i32 1, i32 1, i32 4) nounwind
- ; CHECK: mcrr
- tail call void @llvm.arm.mcrr(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
- ; CHECK: mcrr2
- tail call void @llvm.arm.mcrr2(i32 7, i32 1, i32 %0, i32 %1, i32 1) nounwind
- ; CHECK: cdp
- tail call void @llvm.arm.cdp(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
- ; CHECK: cdp2
- tail call void @llvm.arm.cdp2(i32 7, i32 3, i32 1, i32 1, i32 1, i32 5) nounwind
- ret void
-}
-
-declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind
-
-declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind
-
-declare void @llvm.arm.mcrr2(i32, i32, i32, i32, i32) nounwind
-
-declare void @llvm.arm.mcrr(i32, i32, i32, i32, i32) nounwind
-
-declare void @llvm.arm.mcr2(i32, i32, i32, i32, i32, i32) nounwind
-
-declare i32 @llvm.arm.mrc2(i32, i32, i32, i32, i32) nounwind
-
-declare void @llvm.arm.mcr(i32, i32, i32, i32, i32, i32) nounwind
-
-declare i32 @llvm.arm.mrc(i32, i32, i32, i32, i32) nounwind
diff --git a/test/CodeGen/ARM/invalidated-save-point.ll b/test/CodeGen/ARM/invalidated-save-point.ll
new file mode 100644
index 000000000000..0ff153b6799d
--- /dev/null
+++ b/test/CodeGen/ARM/invalidated-save-point.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple thumbv7 -stop-after=if-converter < %s 2>&1 | FileCheck %s
+
+; Make sure the save point and restore point are dropped from MFI at
+; this point. Notably, if it isn't is will be invalid and reference a
+; deleted block (%bb.-1.if.end)
+
+; CHECK-NOT: savePoint:
+; CHECK-NOT: restorePoint:
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv7"
+
+define i32 @f(i32 %n) {
+entry:
+ %cmp = icmp ult i32 %n, 4
+ br i1 %cmp, label %return, label %if.end
+
+if.end:
+ tail call void @g(i32 %n)
+ br label %return
+
+return:
+ %retval.0 = phi i32 [ 0, %if.end ], [ -1, %entry ]
+ ret i32 %retval.0
+}
+
+declare void @g(i32)
diff --git a/test/CodeGen/ARM/ldc2l.ll b/test/CodeGen/ARM/ldc2l.ll
new file mode 100644
index 000000000000..58d9509b1672
--- /dev/null
+++ b/test/CodeGen/ARM/ldc2l.ll
@@ -0,0 +1,11 @@
+; RUN: not llc < %s -mtriple=armv8-eabi 2>&1 | FileCheck %s
+; RUN: not llc < %s -mtriple=thumbv8-eabi 2>&1 | FileCheck %s
+
+; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.ldc2l
+define void @ldc2l(i8* %i) nounwind {
+entry:
+ call void @llvm.arm.ldc2l(i32 1, i32 2, i8* %i) nounwind
+ ret void
+}
+
+declare void @llvm.arm.ldc2l(i32, i32, i8*) nounwind
diff --git a/test/CodeGen/ARM/ldm-base-writeback.ll b/test/CodeGen/ARM/ldm-base-writeback.ll
new file mode 100644
index 000000000000..375f58a24a19
--- /dev/null
+++ b/test/CodeGen/ARM/ldm-base-writeback.ll
@@ -0,0 +1,21 @@
+; RUN: llc -O3 < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+target triple = "armv7--linux-gnu"
+
+@a = global i32 0, align 4
+@b = global i32 0, align 4
+@c = global i32 0, align 4
+
+; CHECK-LABEL: bar:
+; CHECK: ldm r{{[0-9]}}!, {r0, r{{[0-9]}}, r{{[0-9]}}}
+define void @bar(i32 %a1, i32 %b1, i32 %c1) minsize optsize {
+ %1 = load i32, i32* @a, align 4
+ %2 = load i32, i32* @b, align 4
+ %3 = load i32, i32* @c, align 4
+ %4 = tail call i32 @baz(i32 %1, i32 %3) minsize optsize
+ %5 = tail call i32 @baz(i32 %2, i32 %3) minsize optsize
+ ret void
+}
+
+declare i32 @baz(i32,i32) minsize optsize
diff --git a/test/CodeGen/ARM/ldr_frame.ll b/test/CodeGen/ARM/ldr_frame.ll
index 01b18bccc337..24c10b42a445 100644
--- a/test/CodeGen/ARM/ldr_frame.ll
+++ b/test/CodeGen/ARM/ldr_frame.ll
@@ -1,5 +1,7 @@
; RUN: llc -mtriple=arm-eabi -mattr=+v4t %s -o - | FileCheck %s
+; CHECK-LABEL: f1
+; CHECK-NOT: mov
define i32 @f1() {
%buf = alloca [32 x i32], align 4
%tmp = getelementptr [32 x i32], [32 x i32]* %buf, i32 0, i32 0
@@ -7,6 +9,8 @@ define i32 @f1() {
ret i32 %tmp1
}
+; CHECK-LABEL: f2
+; CHECK-NOT: mov
define i32 @f2() {
%buf = alloca [32 x i8], align 4
%tmp = getelementptr [32 x i8], [32 x i8]* %buf, i32 0, i32 0
@@ -15,6 +19,8 @@ define i32 @f2() {
ret i32 %tmp2
}
+; CHECK-LABEL: f3
+; CHECK-NOT: mov
define i32 @f3() {
%buf = alloca [32 x i32], align 4
%tmp = getelementptr [32 x i32], [32 x i32]* %buf, i32 0, i32 32
@@ -22,6 +28,8 @@ define i32 @f3() {
ret i32 %tmp1
}
+; CHECK-LABEL: f4
+; CHECK-NOT: mov
define i32 @f4() {
%buf = alloca [32 x i8], align 4
%tmp = getelementptr [32 x i8], [32 x i8]* %buf, i32 0, i32 2
@@ -29,6 +37,3 @@ define i32 @f4() {
%tmp2 = zext i8 %tmp1 to i32
ret i32 %tmp2
}
-
-; CHECK-NOT: mov
-
diff --git a/test/CodeGen/ARM/ldrd.ll b/test/CodeGen/ARM/ldrd.ll
index b2596346bfa1..dd97fbfd6404 100644
--- a/test/CodeGen/ARM/ldrd.ll
+++ b/test/CodeGen/ARM/ldrd.ll
@@ -1,9 +1,11 @@
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=fast -optimize-regalloc=0 -verify-machineinstrs | FileCheck %s -check-prefix=A8 -check-prefix=CHECK
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-m3 -regalloc=fast -optimize-regalloc=0 | FileCheck %s -check-prefix=M3 -check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=fast -optimize-regalloc=0 -verify-machineinstrs | FileCheck %s -check-prefix=A8 -check-prefix=CHECK -check-prefix=NORMAL
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-m3 -regalloc=fast -optimize-regalloc=0 | FileCheck %s -check-prefix=M3 -check-prefix=CHECK -check-prefix=NORMAL
; rdar://6949835
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=basic | FileCheck %s -check-prefix=BASIC -check-prefix=CHECK
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=greedy | FileCheck %s -check-prefix=GREEDY -check-prefix=CHECK
-; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT -check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=basic | FileCheck %s -check-prefix=BASIC -check-prefix=CHECK -check-prefix=NORMAL
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 -regalloc=greedy | FileCheck %s -check-prefix=GREEDY -check-prefix=CHECK -check-prefix=NORMAL
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=swift | FileCheck %s -check-prefix=SWIFT -check-prefix=CHECK -check-prefix=NORMAL
+
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -arm-assume-misaligned-load-store | FileCheck %s -check-prefix=CHECK -check-prefix=CONSERVATIVE
; Magic ARM pair hints works best with linearscan / fast.
@@ -15,12 +17,13 @@ declare void @use_i64(i64 %v)
define void @test_ldrd(i64 %a) nounwind readonly {
; CHECK-LABEL: test_ldrd:
-; CHECK: bl{{x?}} _get_ptr
+; NORMAL: bl{{x?}} _get_ptr
; A8: ldrd r0, r1, [r0]
; Cortex-M3 errata 602117: LDRD with base in list may result in incorrect base
; register when interrupted or faulted.
; M3-NOT: ldrd r[[REGNUM:[0-9]+]], {{r[0-9]+}}, [r[[REGNUM]]]
-; CHECK: bl{{x?}} _use_i64
+; CONSERVATIVE-NOT: ldrd
+; NORMAL: bl{{x?}} _use_i64
%ptr = call i64* @get_ptr()
%v = load i64, i64* %ptr, align 8
call void @use_i64(i64 %v)
@@ -39,11 +42,10 @@ define void @test_ldrd(i64 %a) nounwind readonly {
; evict another live range or use callee saved regs. Sorry if the test
; is sensitive to Regalloc changes, but it is an interesting case.
;
-; BASIC: @f
+; CHECK-LABEL: f:
; BASIC: %bb
; BASIC: ldrd
; BASIC: str
-; GREEDY: @f
; GREEDY: %bb
; GREEDY: ldrd
; GREEDY: str
@@ -76,14 +78,15 @@ return: ; preds = %bb, %entry
@TestVar = external global %struct.Test
+; CHECK-LABEL: Func1:
define void @Func1() nounwind ssp {
-; CHECK: @Func1
entry:
; A8: movw [[BASE:r[0-9]+]], :lower16:{{.*}}TestVar{{.*}}
; A8: movt [[BASE]], :upper16:{{.*}}TestVar{{.*}}
; A8: ldrd [[FIELD1:r[0-9]+]], [[FIELD2:r[0-9]+]], {{\[}}[[BASE]], #4]
; A8-NEXT: add [[FIELD1]], [[FIELD2]]
; A8-NEXT: str [[FIELD1]], {{\[}}[[BASE]]{{\]}}
+; CONSERVATIVE-NOT: ldrd
%orig_blocks = alloca [256 x i16], align 2
%0 = bitcast [256 x i16]* %orig_blocks to i8*call void @llvm.lifetime.start(i64 512, i8* %0) nounwind
%tmp1 = load i32, i32* getelementptr inbounds (%struct.Test, %struct.Test* @TestVar, i32 0, i32 1), align 4
@@ -97,8 +100,9 @@ entry:
declare void @extfunc(i32, i32, i32, i32)
; CHECK-LABEL: Func2:
+; CONSERVATIVE-NOT: ldrd
; A8: ldrd
-; A8: blx
+; CHECK: bl{{x?}} _extfunc
; A8: pop
define void @Func2(i32* %p) {
entry:
@@ -116,12 +120,14 @@ entry:
; M3: strd r1, r0, [sp, #-8]!
; BASIC: strd r1, r0, [sp, #-8]!
; GREEDY: strd r0, r1, [sp, #-8]!
-; CHECK: @ InlineAsm Start
-; CHECK: @ InlineAsm End
+; CONSERVATIVE: strd r0, r1, [sp, #-8]!
+; NORMAL: @ InlineAsm Start
+; NORMAL: @ InlineAsm End
; A8: ldrd r2, r1, [sp]
; M3: ldrd r2, r1, [sp]
; BASIC: ldrd r2, r1, [sp]
; GREEDY: ldrd r1, r2, [sp]
+; CONSERVATIVE: ldrd r1, r2, [sp]
; CHECK: bl{{x?}} _extfunc
define void @strd_spill_ldrd_reload(i32 %v0, i32 %v1) {
; force %v0 and %v1 to be spilled
@@ -134,8 +140,9 @@ define void @strd_spill_ldrd_reload(i32 %v0, i32 %v1) {
declare void @extfunc2(i32*, i32, i32)
; CHECK-LABEL: ldrd_postupdate_dec:
-; CHECK: ldrd r1, r2, [r0], #-8
-; CHECK-NEXT: bl{{x?}} _extfunc
+; NORMAL: ldrd r1, r2, [r0], #-8
+; CONSERVATIVE-NOT: ldrd
+; CHECK: bl{{x?}} _extfunc
define void @ldrd_postupdate_dec(i32* %p0) {
%p0.1 = getelementptr i32, i32* %p0, i32 1
%v0 = load i32, i32* %p0
@@ -146,8 +153,9 @@ define void @ldrd_postupdate_dec(i32* %p0) {
}
; CHECK-LABEL: ldrd_postupdate_inc:
-; CHECK: ldrd r1, r2, [r0], #8
-; CHECK-NEXT: bl{{x?}} _extfunc
+; NORMAL: ldrd r1, r2, [r0], #8
+; CONSERVATIVE-NOT: ldrd
+; CHECK: bl{{x?}} _extfunc
define void @ldrd_postupdate_inc(i32* %p0) {
%p0.1 = getelementptr i32, i32* %p0, i32 1
%v0 = load i32, i32* %p0
@@ -158,8 +166,9 @@ define void @ldrd_postupdate_inc(i32* %p0) {
}
; CHECK-LABEL: strd_postupdate_dec:
-; CHECK: strd r1, r2, [r0], #-8
-; CHECK-NEXT: bx lr
+; NORMAL: strd r1, r2, [r0], #-8
+; CONSERVATIVE-NOT: strd
+; CHECK: bx lr
define i32* @strd_postupdate_dec(i32* %p0, i32 %v0, i32 %v1) {
%p0.1 = getelementptr i32, i32* %p0, i32 1
store i32 %v0, i32* %p0
@@ -169,8 +178,9 @@ define i32* @strd_postupdate_dec(i32* %p0, i32 %v0, i32 %v1) {
}
; CHECK-LABEL: strd_postupdate_inc:
-; CHECK: strd r1, r2, [r0], #8
-; CHECK-NEXT: bx lr
+; NORMAL: strd r1, r2, [r0], #8
+; CONSERVATIVE-NOT: strd
+; CHECK: bx lr
define i32* @strd_postupdate_inc(i32* %p0, i32 %v0, i32 %v1) {
%p0.1 = getelementptr i32, i32* %p0, i32 1
store i32 %v0, i32* %p0
diff --git a/test/CodeGen/ARM/ldstrex-m.ll b/test/CodeGen/ARM/ldstrex-m.ll
index 3d83a9d78e35..5b717f7f1ae9 100644
--- a/test/CodeGen/ARM/ldstrex-m.ll
+++ b/test/CodeGen/ARM/ldstrex-m.ll
@@ -1,4 +1,6 @@
; RUN: llc < %s -mtriple=thumbv7m-none-eabi -mcpu=cortex-m4 | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv8m.main-none-eabi | FileCheck %s
+; RUN: llc < %s -mtriple=thumbv8m.base-none-eabi | FileCheck %s
; CHECK-LABEL: f0:
; CHECK-NOT: ldrexd
diff --git a/test/CodeGen/ARM/legalize-unaligned-load.ll b/test/CodeGen/ARM/legalize-unaligned-load.ll
index fa5b21aa4a23..eb4e942f0742 100644
--- a/test/CodeGen/ARM/legalize-unaligned-load.ll
+++ b/test/CodeGen/ARM/legalize-unaligned-load.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O3 -code-model=default -relocation-model=default -mtriple=armv7l-unknown-linux-gnueabihf -mcpu=generic %s -o - | FileCheck %s
+; RUN: llc -O3 -code-model=default -mtriple=armv7l-unknown-linux-gnueabihf -mcpu=generic %s -o - | FileCheck %s
; Check that we respect the existing chain between loads and stores when we
; legalize unaligned loads.
; Test case from PR24669.
diff --git a/test/CodeGen/ARM/litpool-licm.ll b/test/CodeGen/ARM/litpool-licm.ll
new file mode 100644
index 000000000000..dc6b37feaf05
--- /dev/null
+++ b/test/CodeGen/ARM/litpool-licm.ll
@@ -0,0 +1,46 @@
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf -relocation-model=pic %s -o - | FileCheck %s
+
+@var = thread_local global i32 0, align 4
+
+define void @func(i32 %n) {
+; CHECK-LABEL: func:
+; CHECK: ldr [[REF1:r[0-9]+]], [[CP1:.LCPI[0-9]+_[0-9]+]]
+; CHECK: ldr [[REF2:r[0-9]+]], [[CP2:.LCPI[0-9]+_[0-9]+]]
+
+; CHECK: [[PCPOS1:.LPC[0-9]+_[0-9]+]]:
+; CHECK-NEXT: add [[REF1]], pc
+
+; CHECK: [[PCPOS2:.LPC[0-9]+_[0-9]+]]:
+; CHECK-NEXT: add [[REF2]], pc
+
+; CHECK: [[CP1]]:
+; CHECK-NEXT: [[CP1_TMP:.Ltmp[0-9]+]]:
+; CHECK-NEXT: .long var(TLSGD)-(([[PCPOS1]]+4)-[[CP1_TMP]])
+
+; CHECK: [[CP2]]:
+; CHECK-NEXT: [[CP2_TMP:.Ltmp[0-9]+]]:
+; CHECK-NEXT: .long var(TLSGD)-(([[PCPOS2]]+4)-[[CP2_TMP]])
+
+entry:
+ br label %loop
+
+loop:
+ %i = phi i32 [ %inc, %next ], [ 0, %entry ]
+ %val = load i32, i32* @var
+ %tst = icmp eq i32 %val, 0
+ br i1 %tst, label %next, label %call
+
+call:
+ tail call void @foo(i32* nonnull @var) #2
+ br label %next
+
+next:
+ %inc = add i32 %i, 1
+ %stop = icmp eq i32 %inc, %n
+ br i1 %stop, label %done, label %loop
+
+done:
+ ret void
+}
+
+declare void @foo(i32*) \ No newline at end of file
diff --git a/test/CodeGen/ARM/local-call.ll b/test/CodeGen/ARM/local-call.ll
new file mode 100644
index 000000000000..a38df62ff905
--- /dev/null
+++ b/test/CodeGen/ARM/local-call.ll
@@ -0,0 +1,20 @@
+; RUN: llc -mtriple=thumbv7-apple-ios -filetype=obj %s -o %t
+; RUN: llvm-objdump -macho -d %t | FileCheck %s
+
+; This function just messes up the offsets enough to make the libcall in
+; test_local_call unencodable with a blx.
+define void @thing() {
+ ret void
+}
+
+define i64 @__udivdi3(i64 %a, i64 %b) {
+ ret i64 %b
+}
+
+define i64 @test_local_call(i64 %a, i64 %b) {
+; CHECK-LABEL: test_local_call:
+; CHECK: bl ___udivdi3
+
+%res = udiv i64 %a, %b
+ ret i64 %res
+} \ No newline at end of file
diff --git a/test/CodeGen/ARM/longMAC.ll b/test/CodeGen/ARM/longMAC.ll
index 3f30fd40b7e7..cc2d745aae8e 100644
--- a/test/CodeGen/ARM/longMAC.ll
+++ b/test/CodeGen/ARM/longMAC.ll
@@ -116,3 +116,32 @@ define i64 @MACLongTest8(i64 %acc, i32 %lhs, i32 %rhs) {
ret i64 %add
}
+define i64 @MACLongTest9(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) {
+;CHECK-LABEL: MACLongTest9:
+;CHECK-V7-LE:umaal
+;CHECK-V7-BE:umaal
+;CHECK-NOT:umaal
+ %conv = zext i32 %lhs to i64
+ %conv1 = zext i32 %rhs to i64
+ %mul = mul nuw i64 %conv1, %conv
+ %conv2 = zext i32 %lo to i64
+ %add = add i64 %mul, %conv2
+ %conv3 = zext i32 %hi to i64
+ %add2 = add i64 %add, %conv3
+ ret i64 %add2
+}
+
+define i64 @MACLongTest10(i32 %lhs, i32 %rhs, i32 %lo, i32 %hi) {
+;CHECK-LABEL: MACLongTest10:
+;CHECK-V7-LE:umaal
+;CHECK-V7-BE:umaal
+;CHECK-NOT:umaal
+ %conv = zext i32 %lhs to i64
+ %conv1 = zext i32 %rhs to i64
+ %mul = mul nuw i64 %conv1, %conv
+ %conv2 = zext i32 %lo to i64
+ %conv3 = zext i32 %hi to i64
+ %add = add i64 %conv2, %conv3
+ %add2 = add i64 %add, %mul
+ ret i64 %add2
+}
diff --git a/test/CodeGen/ARM/lsr-code-insertion.ll b/test/CodeGen/ARM/lsr-code-insertion.ll
index aa2b2d26d121..766710fd1d64 100644
--- a/test/CodeGen/ARM/lsr-code-insertion.ll
+++ b/test/CodeGen/ARM/lsr-code-insertion.ll
@@ -9,8 +9,8 @@
;
; CHECK: ldr [[R6:r[0-9*]+]], LCP
; CHECK: cmp {{.*}}, [[R6]]
-; CHECK: ldrle
-; CHECK-NEXT: strle
+; CHECK-NOT: lt
+; CHECK: strlt
target triple = "arm-apple-darwin8"
diff --git a/test/CodeGen/ARM/macho-frame-offset.ll b/test/CodeGen/ARM/macho-frame-offset.ll
new file mode 100644
index 000000000000..f3dacf66b6c3
--- /dev/null
+++ b/test/CodeGen/ARM/macho-frame-offset.ll
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple thumbv7m-apple-macho -disable-fp-elim -o - %s | FileCheck %s
+
+define void @func() {
+; CHECK-LABEL: func:
+; CHECK: push {r6, r7, lr}
+; CHECK: add r7, sp, #4
+ call void @bar()
+ call void asm sideeffect "", "~{r11}"()
+ ret void
+}
+
+declare void @bar()
diff --git a/test/CodeGen/ARM/memcpy-no-inline.ll b/test/CodeGen/ARM/memcpy-no-inline.ll
new file mode 100644
index 000000000000..126546095e1f
--- /dev/null
+++ b/test/CodeGen/ARM/memcpy-no-inline.ll
@@ -0,0 +1,33 @@
+; RUN: llc -mtriple=thumbv7m-arm-none-eabi -mcpu=cortex-m3 < %s | FileCheck %s
+
+%struct.mystruct = type { [31 x i8] }
+
+@.str = private unnamed_addr constant [31 x i8] c"012345678901234567890123456789\00", align 1
+@.str.1 = private unnamed_addr constant [21 x i8] c"01234567890123456789\00", align 1
+
+@myglobal = common global %struct.mystruct zeroinitializer, align 1
+
+define void @foo() #0 {
+entry:
+; CHECK-LABEL: foo:
+; CHECK: __aeabi_memcpy
+; CHECK-NOT: ldm
+ %mystring = alloca [31 x i8], align 1
+ %0 = getelementptr inbounds [31 x i8], [31 x i8]* %mystring, i32 0, i32 0
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* getelementptr inbounds ([31 x i8], [31 x i8]* @.str, i32 0, i32 0), i32 31, i32 1, i1 false)
+ ret void
+}
+
+define void @bar() #0 {
+entry:
+; CHECK-LABEL: bar:
+; CHECK-NOT: __aeabi_memcpy
+ %mystring = alloca [31 x i8], align 1
+ %0 = getelementptr inbounds [31 x i8], [31 x i8]* %mystring, i32 0, i32 0
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.1, i32 0, i32 0), i32 21, i32 1, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1) #1
+
+attributes #0 = { minsize noinline nounwind optsize }
diff --git a/test/CodeGen/ARM/memfunc.ll b/test/CodeGen/ARM/memfunc.ll
index 46fef7629cc4..bc60d8e4f0ec 100644
--- a/test/CodeGen/ARM/memfunc.ll
+++ b/test/CodeGen/ARM/memfunc.ll
@@ -5,6 +5,8 @@
; RUN: llc < %s -mtriple=arm-none-androideabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-EABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-gnueabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
; RUN: llc < %s -mtriple=arm-none-gnueabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=arm-none-musleabi -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
+; RUN: llc < %s -mtriple=arm-none-musleabihf -disable-post-ra -o - | FileCheck %s --check-prefix=CHECK-GNUEABI --check-prefix=CHECK
define void @f1(i8* %dest, i8* %src) {
entry:
@@ -384,6 +386,8 @@ entry:
@arr5 = weak global [7 x i8] c"\01\02\03\04\05\06\07", align 1
@arr6 = weak_odr global [7 x i8] c"\01\02\03\04\05\06\07", align 1
@arr7 = external global [7 x i8], align 1
+@arr8 = internal global [128 x i8] undef
+@arr9 = weak_odr global [128 x i8] undef
define void @f9(i8* %dest, i32 %n) {
entry:
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr1, i32 0, i32 0), i32 %n, i32 1, i1 false)
@@ -393,28 +397,35 @@ entry:
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr5, i32 0, i32 0), i32 %n, i32 1, i1 false)
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr6, i32 0, i32 0), i32 %n, i32 1, i1 false)
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @arr7, i32 0, i32 0), i32 %n, i32 1, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @arr8, i32 0, i32 0), i32 %n, i32 1, i1 false)
+ call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* getelementptr inbounds ([128 x i8], [128 x i8]* @arr9, i32 0, i32 0), i32 %n, i32 1, i1 false)
unreachable
}
; CHECK: {{\.data|\.section.+data}}
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
; CHECK: arr1:
-; CHECK-IOS: .align 3
-; CHECK-DARWIN: .align 2
-; CHECK-EABI-NOT: .align
-; CHECK-GNUEABI-NOT: .align
+; CHECK-IOS: .p2align 3
+; CHECK-DARWIN: .p2align 2
+; CHECK-EABI-NOT: .p2align
+; CHECK-GNUEABI-NOT: .p2align
; CHECK: arr2:
; CHECK: {{\.section.+foo,bar}}
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
; CHECK: arr3:
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
; CHECK: arr4:
; CHECK: {{\.data|\.section.+data}}
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
; CHECK: arr5:
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
; CHECK: arr6:
+; CHECK: .p2align 4
+; CHECK: arr8:
+; CHECK: .p2align 4
+; CHECK: arr9:
+
; CHECK-NOT: arr7:
declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
diff --git a/test/CodeGen/ARM/minsize-call-cse.ll b/test/CodeGen/ARM/minsize-call-cse.ll
new file mode 100644
index 000000000000..072b76f03ba3
--- /dev/null
+++ b/test/CodeGen/ARM/minsize-call-cse.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv7m-arm-none-eabi"
+
+; CHECK-LABEL: f:
+; CHECK: blx r
+; CHECK: blx r
+; CHECK: blx r
+define void @f() minsize optsize {
+entry:
+ call void @g(i32 45, i32 66)
+ call void @g(i32 88, i32 32)
+ call void @g(i32 55, i32 33)
+ ret void
+}
+
+; CHECK-LABEL: h:
+; CHECK: bl g
+; CHECK: bl g
+define void @h() minsize optsize {
+entry:
+ call void @g(i32 45, i32 66)
+ call void @g(i32 88, i32 32)
+ ret void
+}
+
+declare void @g(i32,i32)
diff --git a/test/CodeGen/ARM/movt.ll b/test/CodeGen/ARM/movt.ll
index 94c022ee2712..da9b698f2099 100644
--- a/test/CodeGen/ARM/movt.ll
+++ b/test/CodeGen/ARM/movt.ll
@@ -1,9 +1,11 @@
; RUN: llc -mtriple=arm-eabi -mcpu=arm1156t2-s -mattr=+thumb2 %s -o - | FileCheck %s
; rdar://7317664
+; RUN: llc -mtriple=thumbv8m.base %s -o - | FileCheck %s
+
define i32 @t(i32 %X) nounwind {
; CHECK-LABEL: t:
-; CHECK: movt r0, #65535
+; CHECK: movt r{{[0-9]}}, #65535
entry:
%0 = or i32 %X, -65536
ret i32 %0
@@ -11,7 +13,7 @@ entry:
define i32 @t2(i32 %X) nounwind {
; CHECK-LABEL: t2:
-; CHECK: movt r0, #65534
+; CHECK: movt r{{[0-9]}}, #65534
entry:
%0 = or i32 %X, -131072
%1 = and i32 %0, -65537
diff --git a/test/CodeGen/ARM/msr-it-block.ll b/test/CodeGen/ARM/msr-it-block.ll
new file mode 100644
index 000000000000..0f9ff6b29d79
--- /dev/null
+++ b/test/CodeGen/ARM/msr-it-block.ll
@@ -0,0 +1,55 @@
+; RUN: llc < %s -mtriple=thumbv6m-none-eabi | FileCheck %s --check-prefix=V6M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7m-none-eabi | FileCheck %s --check-prefix=V7M --check-prefix=CHECK
+; RUN: llc < %s -mtriple=thumbv7a-none-eabi | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+; RUN: llc < %s -mtriple=armv7a-none-eabi | FileCheck %s --check-prefix=V7A --check-prefix=CHECK
+
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7a-arm-none-eabi"
+
+define void @test_const(i32 %val) {
+; CHECK-LABEL: test_const:
+entry:
+ %cmp = icmp eq i32 %val, 0
+ br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+ tail call void @llvm.write_register.i32(metadata !0, i32 0)
+ tail call void @llvm.write_register.i32(metadata !0, i32 0)
+; V6M: msr apsr, {{r[0-9]+}}
+; V6M: msr apsr, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @test_var(i32 %val, i32 %apsr) {
+; CHECK-LABEL: test_var:
+entry:
+ %cmp = icmp eq i32 %val, 0
+ br i1 %cmp, label %write_reg, label %exit
+
+write_reg:
+ tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+ tail call void @llvm.write_register.i32(metadata !0, i32 %apsr)
+; V6M: msr apsr, {{r[0-9]+}}
+; V6M: msr apsr, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7M: msr apsr_nzcvq, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+; V7A: msr APSR_nzcvqg, {{r[0-9]+}}
+ br label %exit
+
+exit:
+ ret void
+}
+
+
+declare void @llvm.write_register.i32(metadata, i32)
+
+!0 = !{!"apsr"}
diff --git a/test/CodeGen/ARM/none-macho.ll b/test/CodeGen/ARM/none-macho.ll
index 733ba4ba2d2c..fee459f4f5e1 100644
--- a/test/CodeGen/ARM/none-macho.ll
+++ b/test/CodeGen/ARM/none-macho.ll
@@ -43,8 +43,8 @@ define i32 @test_frame_ptr() {
; CHECK-LABEL: test_frame_ptr:
call void @test_trap()
- ; Frame pointer is r11.
-; CHECK: mov r11, sp
+ ; Frame pointer is r7.
+; CHECK: mov r7, sp
ret i32 42
}
@@ -58,9 +58,11 @@ define void @test_two_areas(%big_arr* %addr) {
; This goes with the choice of r7 as FP (largely). FP and LR have to be stored
; consecutively on the stack for the frame record to be valid, which means we
; need the 2 register-save areas employed by iOS.
-; CHECK-NON-FAST: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}
+; CHECK-NON-FAST: push {r4, r5, r6, r7, lr}
+; CHECK-NON-FAST: push.w {r8, r9, r10, r11}
; ...
-; CHECK-NON-FAST: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}
+; CHECK-NON-FAST: pop.w {r8, r9, r10, r11}
+; CHECK-NON-FAST: pop {r4, r5, r6, r7, pc}
ret void
}
diff --git a/test/CodeGen/ARM/pic.ll b/test/CodeGen/ARM/pic.ll
index 9fc7a63bd687..d12addb69d77 100644
--- a/test/CodeGen/ARM/pic.ll
+++ b/test/CodeGen/ARM/pic.ll
@@ -11,10 +11,10 @@ define void @test() {
entry:
%0 = call i32 @get()
-; CHECK: bl get(PLT)
+; CHECK: bl get
call void @put(i32 %0)
-; CHECK: bl put(PLT)
+; CHECK: bl put
ret void
}
diff --git a/test/CodeGen/ARM/pie.ll b/test/CodeGen/ARM/pie.ll
new file mode 100644
index 000000000000..1b1e6e62fda5
--- /dev/null
+++ b/test/CodeGen/ARM/pie.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple=armv7-pc-linux-gnueabi -relocation-model=pic < %s | FileCheck %s
+
+@foo = global i32 42
+
+define i32* @get_foo() {
+ ret i32* @foo
+}
+
+; Test that we only use one load. Even that is only needed because there
+; doesn't seem to be pc relative relocations for movw movt.
+; CHECK: ldr r0, .LCPI0_0
+; CHECK-NEXT: .L{{.*}}:
+; CHECK-NEXT: add r0, pc, r0
+; CHECK-NEXT: bx lr
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"PIE Level", i32 2}
diff --git a/test/CodeGen/ARM/plt-relative-reloc.ll b/test/CodeGen/ARM/plt-relative-reloc.ll
new file mode 100644
index 000000000000..08dcfdf1298f
--- /dev/null
+++ b/test/CodeGen/ARM/plt-relative-reloc.ll
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=armv7-unknown-linux -o - %s | FileCheck %s
+
+@vtable = constant [4 x i32] [i32 0,
+ i32 sub (i32 ptrtoint (void ()* @fn1 to i32), i32 ptrtoint (i32* getelementptr ([4 x i32], [4 x i32]* @vtable, i32 0, i32 1) to i32)),
+ i32 sub (i32 ptrtoint (void ()* @fn2 to i32), i32 ptrtoint (i32* getelementptr ([4 x i32], [4 x i32]* @vtable, i32 0, i32 1) to i32)),
+ i32 sub (i32 ptrtoint (void ()* @fn3 to i32), i32 ptrtoint (i32* getelementptr ([4 x i32], [4 x i32]* @vtable, i32 0, i32 1) to i32))
+]
+
+declare void @fn1() unnamed_addr
+declare void @fn2() unnamed_addr
+declare void @fn3()
+
+; CHECK: .long 0
+; CHECK-NEXT: .long (fn1(prel31)-vtable)-4
+; CHECK-NEXT: .long (fn2(prel31)-vtable)-4
+; CHECK-NEXT: .long (fn3-vtable)-4
diff --git a/test/CodeGen/ARM/popcnt.ll b/test/CodeGen/ARM/popcnt.ll
index 74f90640ca6e..fd61811f49cf 100644
--- a/test/CodeGen/ARM/popcnt.ll
+++ b/test/CodeGen/ARM/popcnt.ll
@@ -71,12 +71,28 @@ define <4 x i32> @vcntQ32(<4 x i32>* %A) nounwind {
ret <4 x i32> %tmp2
}
+define <1 x i64> @vcnt64(<1 x i64>* %A) nounwind {
+; CHECK-LABEL: vcnt64:
+ %tmp1 = load <1 x i64>, <1 x i64>* %A
+ %tmp2 = call <1 x i64> @llvm.ctpop.v1i64(<1 x i64> %tmp1)
+ ret <1 x i64> %tmp2
+}
+
+define <2 x i64> @vcntQ64(<2 x i64>* %A) nounwind {
+; CHECK-LABEL: vcntQ64:
+ %tmp1 = load <2 x i64>, <2 x i64>* %A
+ %tmp2 = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %tmp1)
+ ret <2 x i64> %tmp2
+}
+
declare <8 x i8> @llvm.ctpop.v8i8(<8 x i8>) nounwind readnone
declare <16 x i8> @llvm.ctpop.v16i8(<16 x i8>) nounwind readnone
declare <4 x i16> @llvm.ctpop.v4i16(<4 x i16>) nounwind readnone
declare <8 x i16> @llvm.ctpop.v8i16(<8 x i16>) nounwind readnone
declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) nounwind readnone
declare <4 x i32> @llvm.ctpop.v4i32(<4 x i32>) nounwind readnone
+declare <1 x i64> @llvm.ctpop.v1i64(<1 x i64>) nounwind readnone
+declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) nounwind readnone
define <8 x i8> @vclz8(<8 x i8>* %A) nounwind {
;CHECK-LABEL: vclz8:
diff --git a/test/CodeGen/ARM/pr26669.ll b/test/CodeGen/ARM/pr26669.ll
new file mode 100644
index 000000000000..6c28ddd2d848
--- /dev/null
+++ b/test/CodeGen/ARM/pr26669.ll
@@ -0,0 +1,31 @@
+; RUN: opt -S -globaldce -sjljehprepare < %s | FileCheck %s
+target datalayout = "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+target triple = "thumbv7--ios5.0.0"
+
+define void @g() personality i32 (...)* @__gxx_personality_sj0 {
+entry:
+ %exn.slot = alloca i8*
+ %ehselector.slot = alloca i32
+ invoke void @f()
+ to label %try.cont unwind label %lpad
+
+lpad: ; preds = %entry
+ %0 = landingpad { i8*, i32 }
+ cleanup
+ br label %try.cont
+
+try.cont: ; preds = %catch, %invoke.cont
+ ret void
+}
+
+declare void @f()
+
+declare i32 @__gxx_personality_sj0(...)
+
+; CHECK-LABEL: define void @g(
+; CHECK: call void @llvm.eh.sjlj.callsite(
+; CHECK: call void @_Unwind_SjLj_Register(
+; CHECK: invoke void @f(
+; CHECK: landingpad
+; CHECK-NEXT: cleanup
+; CHECK: call void @_Unwind_SjLj_Unregister(
diff --git a/test/CodeGen/ARM/preferred-align.ll b/test/CodeGen/ARM/preferred-align.ll
index 8cd4ef615468..a9a17229e064 100644
--- a/test/CodeGen/ARM/preferred-align.ll
+++ b/test/CodeGen/ARM/preferred-align.ll
@@ -3,19 +3,19 @@
@var_agg = global {i8, i8} zeroinitializer
; CHECK: .globl var_agg
-; CHECK-NEXT: .align 2
+; CHECK-NEXT: .p2align 2
@var1 = global i1 zeroinitializer
; CHECK: .globl var1
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
@var8 = global i8 zeroinitializer
; CHECK: .globl var8
-; CHECK-NOT: .align
+; CHECK-NOT: .p2align
@var16 = global i16 zeroinitializer
; CHECK: .globl var16
-; CHECK-NEXT: .align 1 \ No newline at end of file
+; CHECK-NEXT: .p2align 1 \ No newline at end of file
diff --git a/test/CodeGen/ARM/rem_crash.ll b/test/CodeGen/ARM/rem_crash.ll
new file mode 100644
index 000000000000..bce597c030d2
--- /dev/null
+++ b/test/CodeGen/ARM/rem_crash.ll
@@ -0,0 +1,257 @@
+; RUN: llc < %s -mtriple=arm-unknown-unknown
+
+define i8 @test_minsize_uu8(i8 %x) minsize optsize {
+entry:
+ %0 = udiv i8 %x, 10
+ %1 = urem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_minsize_ss8(i8 %x) minsize optsize {
+entry:
+ %0 = sdiv i8 %x, 10
+ %1 = srem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_minsize_us8(i8 %x) minsize optsize {
+entry:
+ %0 = udiv i8 %x, 10
+ %1 = srem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_minsize_su8(i8 %x) minsize optsize {
+entry:
+ %0 = sdiv i8 %x, 10
+ %1 = urem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i16 @test_minsize_uu16(i16 %x) minsize optsize {
+entry:
+ %0 = udiv i16 %x, 10
+ %1 = urem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_minsize_ss16(i16 %x) minsize optsize {
+entry:
+ %0 = sdiv i16 %x, 10
+ %1 = srem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_minsize_us16(i16 %x) minsize optsize {
+entry:
+ %0 = udiv i16 %x, 10
+ %1 = srem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_minsize_su16(i16 %x) minsize optsize {
+entry:
+ %0 = sdiv i16 %x, 10
+ %1 = urem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i32 @test_minsize_uu32(i32 %x) minsize optsize {
+entry:
+ %0 = udiv i32 %x, 10
+ %1 = urem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_minsize_ss32(i32 %x) minsize optsize {
+entry:
+ %0 = sdiv i32 %x, 10
+ %1 = srem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_minsize_us32(i32 %x) minsize optsize {
+entry:
+ %0 = udiv i32 %x, 10
+ %1 = srem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_minsize_su32(i32 %x) minsize optsize {
+entry:
+ %0 = sdiv i32 %x, 10
+ %1 = urem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i64 @test_minsize_uu64(i64 %x) minsize optsize {
+entry:
+ %0 = udiv i64 %x, 10
+ %1 = urem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_minsize_ss64(i64 %x) minsize optsize {
+entry:
+ %0 = sdiv i64 %x, 10
+ %1 = srem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_minsize_us64(i64 %x) minsize optsize {
+entry:
+ %0 = udiv i64 %x, 10
+ %1 = srem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_minsize_su64(i64 %x) minsize optsize {
+entry:
+ %0 = sdiv i64 %x, 10
+ %1 = urem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i8 @test_uu8(i8 %x) optsize {
+entry:
+ %0 = udiv i8 %x, 10
+ %1 = urem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_ss8(i8 %x) optsize {
+entry:
+ %0 = sdiv i8 %x, 10
+ %1 = srem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_us8(i8 %x) optsize {
+entry:
+ %0 = udiv i8 %x, 10
+ %1 = srem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i8 @test_su8(i8 %x) optsize {
+entry:
+ %0 = sdiv i8 %x, 10
+ %1 = urem i8 %x, 10
+ %res = add i8 %0, %1
+ ret i8 %res
+}
+
+define i16 @test_uu16(i16 %x) optsize {
+entry:
+ %0 = udiv i16 %x, 10
+ %1 = urem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_ss16(i16 %x) optsize {
+entry:
+ %0 = sdiv i16 %x, 10
+ %1 = srem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_us16(i16 %x) optsize {
+entry:
+ %0 = udiv i16 %x, 10
+ %1 = srem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i16 @test_su16(i16 %x) optsize {
+entry:
+ %0 = sdiv i16 %x, 10
+ %1 = urem i16 %x, 10
+ %res = add i16 %0, %1
+ ret i16 %res
+}
+
+define i32 @test_uu32(i32 %x) optsize {
+entry:
+ %0 = udiv i32 %x, 10
+ %1 = urem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_ss32(i32 %x) optsize {
+entry:
+ %0 = sdiv i32 %x, 10
+ %1 = srem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_us32(i32 %x) optsize {
+entry:
+ %0 = udiv i32 %x, 10
+ %1 = srem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i32 @test_su32(i32 %x) optsize {
+entry:
+ %0 = sdiv i32 %x, 10
+ %1 = urem i32 %x, 10
+ %res = add i32 %0, %1
+ ret i32 %res
+}
+
+define i64 @test_uu64(i64 %x) optsize {
+entry:
+ %0 = udiv i64 %x, 10
+ %1 = urem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_ss64(i64 %x) optsize {
+entry:
+ %0 = sdiv i64 %x, 10
+ %1 = srem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_us64(i64 %x) optsize {
+entry:
+ %0 = udiv i64 %x, 10
+ %1 = srem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
+
+define i64 @test_su64(i64 %x) optsize {
+entry:
+ %0 = sdiv i64 %x, 10
+ %1 = urem i64 %x, 10
+ %res = add i64 %0, %1
+ ret i64 %res
+}
diff --git a/test/CodeGen/ARM/returned-ext.ll b/test/CodeGen/ARM/returned-ext.ll
index 925e9e729f44..f592d0aec5f7 100644
--- a/test/CodeGen/ARM/returned-ext.ll
+++ b/test/CodeGen/ARM/returned-ext.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s -check-prefix=CHECKELF
-; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D
+; RUN: llc < %s -mtriple=armv6-linux-gnueabi -arm-this-return-forwarding | FileCheck %s -check-prefix=CHECKELF
+; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 -arm-this-return-forwarding | FileCheck %s -check-prefix=CHECKT2D
declare i16 @identity16(i16 returned %x)
declare i32 @identity32(i32 returned %x)
@@ -18,9 +18,9 @@ entry:
; CHECKELF: mov r0, [[SAVEX]]
; CHECKT2D-LABEL: test_identity:
; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
-; CHECKT2D: blx _identity16
+; CHECKT2D: bl _identity16
; CHECKT2D: uxth r0, r0
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
; CHECKT2D: mov r0, [[SAVEX]]
%call = tail call i16 @identity16(i16 %x)
%b = zext i16 %call to i32
@@ -49,9 +49,9 @@ entry:
; This shouldn't be required
; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
-; CHECKT2D: blx _retzext16
+; CHECKT2D: bl _retzext16
; CHECKT2D-NOT: uxth r0, {{r[0-9]+}}
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
; This shouldn't be required
; CHECKT2D: mov r0, [[SAVEX]]
@@ -72,9 +72,9 @@ entry:
; CHECKELF: mov r0, [[SAVEX]]
; CHECKT2D-LABEL: test_mismatched_ret:
; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
-; CHECKT2D: blx _retzext16
+; CHECKT2D: bl _retzext16
; CHECKT2D: sxth r0, {{r[0-9]+}}
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
; CHECKT2D: mov r0, [[SAVEX]]
%call = tail call i16 @retzext16(i16 %x)
%b = sext i16 %call to i32
@@ -92,9 +92,9 @@ entry:
; CHECKELF: b paramzext16
; CHECKT2D-LABEL: test_matched_paramext:
; CHECKT2D: uxth r0, r0
-; CHECKT2D: blx _paramzext16
+; CHECKT2D: bl _paramzext16
; CHECKT2D: uxth r0, r0
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
; CHECKT2D: b.w _paramzext16
%call = tail call i16 @paramzext16(i16 %x)
%b = zext i16 %call to i32
@@ -118,8 +118,8 @@ entry:
; CHECKELF: bl identity32
; CHECKELF: b paramzext16
; CHECKT2D-LABEL: test_matched_paramext2:
-; CHECKT2D: blx _paramzext16
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _paramzext16
+; CHECKT2D: bl _identity32
; CHECKT2D: b.w _paramzext16
%call = tail call i16 @paramzext16(i16 %x)
@@ -143,11 +143,11 @@ entry:
; CHECKT2D-LABEL: test_matched_bothext:
; CHECKT2D: uxth r0, r0
-; CHECKT2D: blx _bothzext16
+; CHECKT2D: bl _bothzext16
; CHECKT2D-NOT: uxth r0, r0
; FIXME: Tail call should be OK here
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
%call = tail call i16 @bothzext16(i16 %x)
%b = zext i16 %x to i32
@@ -167,9 +167,9 @@ entry:
; CHECKT2D-LABEL: test_mismatched_bothext:
; CHECKT2D: mov [[SAVEX:r[0-9]+]], r0
; CHECKT2D: uxth r0, {{r[0-9]+}}
-; CHECKT2D: blx _bothzext16
+; CHECKT2D: bl _bothzext16
; CHECKT2D: sxth r0, [[SAVEX]]
-; CHECKT2D: blx _identity32
+; CHECKT2D: bl _identity32
; CHECKT2D: mov r0, [[SAVEX]]
%call = tail call i16 @bothzext16(i16 %x)
%b = sext i16 %x to i32
diff --git a/test/CodeGen/ARM/sincos.ll b/test/CodeGen/ARM/sincos.ll
index 30b2664e3726..5be0044ddbd3 100644
--- a/test/CodeGen/ARM/sincos.ll
+++ b/test/CodeGen/ARM/sincos.ll
@@ -1,5 +1,8 @@
; RUN: llc < %s -mtriple=armv7-apple-ios6 -mcpu=cortex-a8 | FileCheck %s --check-prefix=NOOPT
; RUN: llc < %s -mtriple=armv7-apple-ios7 -mcpu=cortex-a8 | FileCheck %s --check-prefix=SINCOS
+; RUN: llc < %s -mtriple=armv7-linux-gnu -mcpu=cortex-a8 | FileCheck %s --check-prefix=NOOPT-GNU
+; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 \
+; RUN: --enable-unsafe-fp-math | FileCheck %s --check-prefix=SINCOS-GNU
; Combine sin / cos into a single call.
; rdar://12856873
@@ -9,9 +12,17 @@ entry:
; SINCOS-LABEL: test1:
; SINCOS: bl ___sincosf_stret
+; SINCOS-GNU-LABEL: test1:
+; SINCOS-GNU: bl sincosf
+
; NOOPT-LABEL: test1:
; NOOPT: bl _sinf
; NOOPT: bl _cosf
+
+; NOOPT-GNU-LABEL: test1:
+; NOOPT-GNU: bl sinf
+; NOOPT-GNU: bl cosf
+
%call = tail call float @sinf(float %x) nounwind readnone
%call1 = tail call float @cosf(float %x) nounwind readnone
%add = fadd float %call, %call1
@@ -23,9 +34,16 @@ entry:
; SINCOS-LABEL: test2:
; SINCOS: bl ___sincos_stret
+; SINCOS-GNU-LABEL: test2:
+; SINCOS-GNU: bl sincos
+
; NOOPT-LABEL: test2:
; NOOPT: bl _sin
; NOOPT: bl _cos
+
+; NOOPT-GNU-LABEL: test2:
+; NOOPT-GNU: bl sin
+; NOOPT-GNU: bl cos
%call = tail call double @sin(double %x) nounwind readnone
%call1 = tail call double @cos(double %x) nounwind readnone
%add = fadd double %call, %call1
diff --git a/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll b/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll
index a1abef9605ca..17393e44b12e 100644
--- a/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll
+++ b/test/CodeGen/ARM/sjlj-prepare-critical-edge.ll
@@ -74,8 +74,8 @@ declare void @terminatev()
; %do.body.i.i.i.
; CHECK-LABEL: __Z4foo1c:
-; CHECK: blx __Znwm
-; CHECK: {{.*}}@ %entry.do.body.i.i.i_crit_edge
+; CHECK: bl __Znwm
+; CHECK: {{.*}}@ %do.body.i.i.i.preheader
; CHECK: str r0, [sp, [[OFFSET:#[0-9]+]]]
; CHECK: {{.*}}@ %do.body.i.i.i
; CHECK: ldr [[R0:r[0-9]+]], [sp, [[OFFSET]]]
diff --git a/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll b/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
index b44b447b3dff..323d5037138e 100644
--- a/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
+++ b/test/CodeGen/ARM/sjljehprepare-lower-empty-struct.ll
@@ -2,7 +2,8 @@
; RUN: llc -mtriple=armv7-apple-ios -O1 < %s | FileCheck %s
; RUN: llc -mtriple=armv7-apple-ios -O2 < %s | FileCheck %s
; RUN: llc -mtriple=armv7-apple-ios -O3 < %s | FileCheck %s
-; RUN: llc -mtriple=armv7k-apple-ios < %s | FileCheck %s
+; RUN: llc -mtriple=armv7-apple-watchos -O3 < %s | FileCheck %s
+; RUN: llc -mtriple=armv7k-apple-ios < %s | FileCheck %s --check-prefix=CHECK-WATCH
; SjLjEHPrepare shouldn't crash when lowering empty structs.
;
@@ -16,6 +17,9 @@ entry:
; CHECK: bl __Unwind_SjLj_Register
; CHECK-NEXT: {{[A-Z][a-zA-Z0-9]*}}:
; CHECK-NEXT: bl _bar
+
+; CHECK-WATCH-NOT: bl __Unwind_SjLj_Register
+
invoke void @bar ()
to label %unreachable unwind label %handler
diff --git a/test/CodeGen/ARM/smul.ll b/test/CodeGen/ARM/smul.ll
index 13873f511e1f..4e6f7d5c67b0 100644
--- a/test/CodeGen/ARM/smul.ll
+++ b/test/CodeGen/ARM/smul.ll
@@ -1,11 +1,12 @@
; RUN: llc -mtriple=arm-eabi -mcpu=generic %s -o /dev/null
; RUN: llc -mtriple=arm-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumb--none-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
@x = weak global i16 0 ; <i16*> [#uses=1]
@y = weak global i16 0 ; <i16*> [#uses=0]
define i32 @f1(i32 %y) {
-; CHECK: f1
+; CHECK-LABEL: f1:
; CHECK: smulbt
%tmp = load i16, i16* @x ; <i16> [#uses=1]
%tmp1 = add i16 %tmp, 2 ; <i16> [#uses=1]
@@ -16,7 +17,7 @@ define i32 @f1(i32 %y) {
}
define i32 @f2(i32 %x, i32 %y) {
-; CHECK: f2
+; CHECK-LABEL: f2:
; CHECK: smultt
%tmp1 = ashr i32 %x, 16 ; <i32> [#uses=1]
%tmp3 = ashr i32 %y, 16 ; <i32> [#uses=1]
@@ -25,7 +26,7 @@ define i32 @f2(i32 %x, i32 %y) {
}
define i32 @f3(i32 %a, i16 %x, i32 %y) {
-; CHECK: f3
+; CHECK-LABEL: f3:
; CHECK: smlabt
%tmp = sext i16 %x to i32 ; <i32> [#uses=1]
%tmp2 = ashr i32 %y, 16 ; <i32> [#uses=1]
@@ -34,3 +35,107 @@ define i32 @f3(i32 %a, i16 %x, i32 %y) {
ret i32 %tmp5
}
+define i32 @f4(i32 %a, i32 %x, i32 %y) {
+; CHECK-LABEL: f4:
+; CHECK: smlatt
+ %tmp1 = ashr i32 %x, 16
+ %tmp3 = ashr i32 %y, 16
+ %tmp4 = mul i32 %tmp3, %tmp1
+ %tmp5 = add i32 %tmp4, %a
+ ret i32 %tmp5
+}
+
+define i32 @f5(i32 %a, i16 %x, i16 %y) {
+; CHECK-LABEL: f5:
+; CHECK: smlabb
+ %tmp1 = sext i16 %x to i32
+ %tmp3 = sext i16 %y to i32
+ %tmp4 = mul i32 %tmp3, %tmp1
+ %tmp5 = add i32 %tmp4, %a
+ ret i32 %tmp5
+}
+
+define i32 @f6(i32 %a, i16 %x, i32 %y) {
+; CHECK-LABEL: f6:
+; CHECK: smlabt
+ %tmp1 = sext i16 %x to i32
+ %tmp3 = ashr i32 %y, 16
+ %tmp4 = mul i32 %tmp3, %tmp1
+ %tmp5 = add i32 %tmp4, %a
+ ret i32 %tmp5
+}
+
+define i32 @f7(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: f7:
+; CHECK: smlawb
+ %shl = shl i32 %b, 16
+ %shr = ashr exact i32 %shl, 16
+ %conv = sext i32 %a to i64
+ %conv2 = sext i32 %shr to i64
+ %mul = mul nsw i64 %conv2, %conv
+ %shr49 = lshr i64 %mul, 16
+ %conv5 = trunc i64 %shr49 to i32
+ %add = add nsw i32 %conv5, %c
+ ret i32 %add
+}
+
+define i32 @f8(i32 %a, i16 signext %b, i32 %c) {
+; CHECK-LABEL: f8:
+; CHECK: smlawb
+ %conv = sext i32 %a to i64
+ %conv1 = sext i16 %b to i64
+ %mul = mul nsw i64 %conv1, %conv
+ %shr5 = lshr i64 %mul, 16
+ %conv2 = trunc i64 %shr5 to i32
+ %add = add nsw i32 %conv2, %c
+ ret i32 %add
+}
+
+define i32 @f9(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: f9:
+; CHECK: smlawt
+ %conv = sext i32 %a to i64
+ %shr = ashr i32 %b, 16
+ %conv1 = sext i32 %shr to i64
+ %mul = mul nsw i64 %conv1, %conv
+ %shr26 = lshr i64 %mul, 16
+ %conv3 = trunc i64 %shr26 to i32
+ %add = add nsw i32 %conv3, %c
+ ret i32 %add
+}
+
+define i32 @f10(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: f10:
+; CHECK: smulwb
+ %shl = shl i32 %b, 16
+ %shr = ashr exact i32 %shl, 16
+ %conv = sext i32 %a to i64
+ %conv2 = sext i32 %shr to i64
+ %mul = mul nsw i64 %conv2, %conv
+ %shr37 = lshr i64 %mul, 16
+ %conv4 = trunc i64 %shr37 to i32
+ ret i32 %conv4
+}
+
+define i32 @f11(i32 %a, i16 signext %b, i32 %c) {
+; CHECK-LABEL: f11:
+; CHECK: smulwb
+ %conv = sext i32 %a to i64
+ %conv1 = sext i16 %b to i64
+ %mul = mul nsw i64 %conv1, %conv
+ %shr4 = lshr i64 %mul, 16
+ %conv2 = trunc i64 %shr4 to i32
+ ret i32 %conv2
+}
+
+define i32 @f12(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: f12:
+; CHECK: smulwt
+ %conv = sext i32 %a to i64
+ %shr = ashr i32 %b, 16
+ %conv1 = sext i32 %shr to i64
+ %mul = mul nsw i64 %conv1, %conv
+ %shr25 = lshr i64 %mul, 16
+ %conv3 = trunc i64 %shr25 to i32
+ ret i32 %conv3
+}
diff --git a/test/CodeGen/ARM/smulw.ll b/test/CodeGen/ARM/smulw.ll
deleted file mode 100644
index 8653903eee53..000000000000
--- a/test/CodeGen/ARM/smulw.ll
+++ /dev/null
@@ -1,26 +0,0 @@
-; RUN: llc -mtriple=arm--none-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
-; RUN: llc -mtriple=thumb--none-eabi -mcpu=cortex-a8 %s -o - | FileCheck %s
-
-; We cannot codegen the smulw[bt] or smlaw[bt] instructions for these functions,
-; as the top 16 bits of the result would differ
-
-define i32 @f1(i32 %a, i16 %b) {
-; CHECK-LABEL: f1:
-; CHECK: mul
-; CHECK: asr
- %tmp1 = sext i16 %b to i32
- %tmp2 = mul i32 %a, %tmp1
- %tmp3 = ashr i32 %tmp2, 16
- ret i32 %tmp3
-}
-
-define i32 @f2(i32 %a, i16 %b, i32 %c) {
-; CHECK-LABEL: f2:
-; CHECK: mul
-; CHECK: add{{.*}}, asr #16
- %tmp1 = sext i16 %b to i32
- %tmp2 = mul i32 %a, %tmp1
- %tmp3 = ashr i32 %tmp2, 16
- %tmp4 = add i32 %tmp3, %c
- ret i32 %tmp4
-}
diff --git a/test/CodeGen/ARM/special-reg-v8m-base.ll b/test/CodeGen/ARM/special-reg-v8m-base.ll
new file mode 100644
index 000000000000..20284daa0463
--- /dev/null
+++ b/test/CodeGen/ARM/special-reg-v8m-base.ll
@@ -0,0 +1,142 @@
+; RUN: not llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=V7M
+; RUN: llc < %s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s
+
+; V7M: LLVM ERROR: Invalid register name "sp_ns".
+
+define i32 @read_mclass_registers() nounwind {
+entry:
+ ; CHECK-LABEL: read_mclass_registers:
+ ; CHECK: mrs r0, apsr
+ ; CHECK: mrs r1, iapsr
+ ; CHECK: mrs r1, eapsr
+ ; CHECK: mrs r1, xpsr
+ ; CHECK: mrs r1, ipsr
+ ; CHECK: mrs r1, epsr
+ ; CHECK: mrs r1, iepsr
+ ; CHECK: mrs r1, msp
+ ; CHECK: mrs r1, psp
+ ; CHECK: mrs r1, primask
+ ; CHECK: mrs r1, control
+ ; CHECK: mrs r1, msplim
+ ; CHECK: mrs r1, psplim
+ ; CHECK: mrs r1, msp_ns
+ ; CHECK: mrs r1, psp_ns
+ ; CHECK: mrs r1, primask_ns
+ ; CHECK: mrs r1, control_ns
+ ; CHECK: mrs r1, sp_ns
+
+ %0 = call i32 @llvm.read_register.i32(metadata !0)
+ %1 = call i32 @llvm.read_register.i32(metadata !4)
+ %add1 = add i32 %1, %0
+ %2 = call i32 @llvm.read_register.i32(metadata !8)
+ %add2 = add i32 %add1, %2
+ %3 = call i32 @llvm.read_register.i32(metadata !12)
+ %add3 = add i32 %add2, %3
+ %4 = call i32 @llvm.read_register.i32(metadata !16)
+ %add4 = add i32 %add3, %4
+ %5 = call i32 @llvm.read_register.i32(metadata !17)
+ %add5 = add i32 %add4, %5
+ %6 = call i32 @llvm.read_register.i32(metadata !18)
+ %add6 = add i32 %add5, %6
+ %7 = call i32 @llvm.read_register.i32(metadata !19)
+ %add7 = add i32 %add6, %7
+ %8 = call i32 @llvm.read_register.i32(metadata !20)
+ %add8 = add i32 %add7, %8
+ %9 = call i32 @llvm.read_register.i32(metadata !21)
+ %add9 = add i32 %add8, %9
+ %10 = call i32 @llvm.read_register.i32(metadata !25)
+ %add10 = add i32 %add9, %10
+ %11 = call i32 @llvm.read_register.i32(metadata !26)
+ %add11 = add i32 %add10, %11
+ %12 = call i32 @llvm.read_register.i32(metadata !27)
+ %add12 = add i32 %add11, %12
+ %13 = call i32 @llvm.read_register.i32(metadata !28)
+ %add13 = add i32 %add12, %13
+ %14 = call i32 @llvm.read_register.i32(metadata !29)
+ %add14 = add i32 %add13, %14
+ %15 = call i32 @llvm.read_register.i32(metadata !32)
+ %add15 = add i32 %add14, %15
+ %16 = call i32 @llvm.read_register.i32(metadata !35)
+ %add16 = add i32 %add15, %16
+ %17 = call i32 @llvm.read_register.i32(metadata !36)
+ %add17 = add i32 %add16, %17
+ ret i32 %add10
+}
+
+define void @write_mclass_registers(i32 %x) nounwind {
+entry:
+ ; CHECK-LABEL: write_mclass_registers:
+ ; CHECK: msr apsr, r0
+ ; CHECK: msr apsr, r0
+ ; CHECK: msr iapsr, r0
+ ; CHECK: msr iapsr, r0
+ ; CHECK: msr eapsr, r0
+ ; CHECK: msr eapsr, r0
+ ; CHECK: msr xpsr, r0
+ ; CHECK: msr xpsr, r0
+ ; CHECK: msr ipsr, r0
+ ; CHECK: msr epsr, r0
+ ; CHECK: msr iepsr, r0
+ ; CHECK: msr msp, r0
+ ; CHECK: msr psp, r0
+ ; CHECK: msr primask, r0
+ ; CHECK: msr control, r0
+ ; CHECK: msr msplim, r0
+ ; CHECK: msr psplim, r0
+ ; CHECK: msr msp_ns, r0
+ ; CHECK: msr psp_ns, r0
+ ; CHECK: msr primask_ns, r0
+ ; CHECK: msr control_ns, r0
+ ; CHECK: msr sp_ns, r0
+
+ call void @llvm.write_register.i32(metadata !0, i32 %x)
+ call void @llvm.write_register.i32(metadata !1, i32 %x)
+ call void @llvm.write_register.i32(metadata !4, i32 %x)
+ call void @llvm.write_register.i32(metadata !5, i32 %x)
+ call void @llvm.write_register.i32(metadata !8, i32 %x)
+ call void @llvm.write_register.i32(metadata !9, i32 %x)
+ call void @llvm.write_register.i32(metadata !12, i32 %x)
+ call void @llvm.write_register.i32(metadata !13, i32 %x)
+ call void @llvm.write_register.i32(metadata !16, i32 %x)
+ call void @llvm.write_register.i32(metadata !17, i32 %x)
+ call void @llvm.write_register.i32(metadata !18, i32 %x)
+ call void @llvm.write_register.i32(metadata !19, i32 %x)
+ call void @llvm.write_register.i32(metadata !20, i32 %x)
+ call void @llvm.write_register.i32(metadata !21, i32 %x)
+ call void @llvm.write_register.i32(metadata !25, i32 %x)
+ call void @llvm.write_register.i32(metadata !26, i32 %x)
+ call void @llvm.write_register.i32(metadata !27, i32 %x)
+ call void @llvm.write_register.i32(metadata !28, i32 %x)
+ call void @llvm.write_register.i32(metadata !29, i32 %x)
+ call void @llvm.write_register.i32(metadata !32, i32 %x)
+ call void @llvm.write_register.i32(metadata !35, i32 %x)
+ call void @llvm.write_register.i32(metadata !36, i32 %x)
+ ret void
+}
+
+declare i32 @llvm.read_register.i32(metadata) nounwind
+declare void @llvm.write_register.i32(metadata, i32) nounwind
+
+!0 = !{!"apsr"}
+!1 = !{!"apsr_nzcvq"}
+!4 = !{!"iapsr"}
+!5 = !{!"iapsr_nzcvq"}
+!8 = !{!"eapsr"}
+!9 = !{!"eapsr_nzcvq"}
+!12 = !{!"xpsr"}
+!13 = !{!"xpsr_nzcvq"}
+!16 = !{!"ipsr"}
+!17 = !{!"epsr"}
+!18 = !{!"iepsr"}
+!19 = !{!"msp"}
+!20 = !{!"psp"}
+!21 = !{!"primask"}
+!25 = !{!"control"}
+!26 = !{!"msplim"}
+!27 = !{!"psplim"}
+!28 = !{!"msp_ns"}
+!29 = !{!"psp_ns"}
+!32 = !{!"primask_ns"}
+!35 = !{!"control_ns"}
+!36 = !{!"sp_ns"}
+
diff --git a/test/CodeGen/ARM/special-reg-v8m-main.ll b/test/CodeGen/ARM/special-reg-v8m-main.ll
new file mode 100644
index 000000000000..cde296c6b218
--- /dev/null
+++ b/test/CodeGen/ARM/special-reg-v8m-main.ll
@@ -0,0 +1,214 @@
+; RUN: not llc < %s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s --check-prefix=BASELINE
+; RUN: llc < %s -mtriple=thumbv8m.main-none-eabi -mattr=+dsp 2>&1 | FileCheck %s --check-prefix=MAINLINE
+
+; BASELINE: LLVM ERROR: Invalid register name "basepri_max_ns".
+
+define i32 @read_mclass_registers() nounwind {
+entry:
+ ; MAINLINE-LABEL: read_mclass_registers:
+ ; MAINLINE: mrs r0, apsr
+ ; MAINLINE: mrs r1, iapsr
+ ; MAINLINE: mrs r1, eapsr
+ ; MAINLINE: mrs r1, xpsr
+ ; MAINLINE: mrs r1, ipsr
+ ; MAINLINE: mrs r1, epsr
+ ; MAINLINE: mrs r1, iepsr
+ ; MAINLINE: mrs r1, msp
+ ; MAINLINE: mrs r1, psp
+ ; MAINLINE: mrs r1, primask
+ ; MAINLINE: mrs r1, basepri
+ ; MAINLINE: mrs r1, basepri_max
+ ; MAINLINE: mrs r1, faultmask
+ ; MAINLINE: mrs r1, control
+ ; MAINLINE: mrs r1, msplim
+ ; MAINLINE: mrs r1, psplim
+ ; MAINLINE: mrs r1, msp_ns
+ ; MAINLINE: mrs r1, psp_ns
+ ; MAINLINE: mrs r1, msplim_ns
+ ; MAINLINE: mrs r1, psplim_ns
+ ; MAINLINE: mrs r1, primask_ns
+ ; MAINLINE: mrs r1, basepri_ns
+ ; MAINLINE: mrs r1, faultmask_ns
+ ; MAINLINE: mrs r1, control_ns
+ ; MAINLINE: mrs r1, sp_ns
+ ; MAINLINE: mrs r1, basepri_max_ns
+
+ %0 = call i32 @llvm.read_register.i32(metadata !0)
+ %1 = call i32 @llvm.read_register.i32(metadata !4)
+ %add1 = add i32 %1, %0
+ %2 = call i32 @llvm.read_register.i32(metadata !8)
+ %add2 = add i32 %add1, %2
+ %3 = call i32 @llvm.read_register.i32(metadata !12)
+ %add3 = add i32 %add2, %3
+ %4 = call i32 @llvm.read_register.i32(metadata !16)
+ %add4 = add i32 %add3, %4
+ %5 = call i32 @llvm.read_register.i32(metadata !17)
+ %add5 = add i32 %add4, %5
+ %6 = call i32 @llvm.read_register.i32(metadata !18)
+ %add6 = add i32 %add5, %6
+ %7 = call i32 @llvm.read_register.i32(metadata !19)
+ %add7 = add i32 %add6, %7
+ %8 = call i32 @llvm.read_register.i32(metadata !20)
+ %add8 = add i32 %add7, %8
+ %9 = call i32 @llvm.read_register.i32(metadata !21)
+ %add9 = add i32 %add8, %9
+ %10 = call i32 @llvm.read_register.i32(metadata !22)
+ %add10 = add i32 %add9, %10
+ %11 = call i32 @llvm.read_register.i32(metadata !23)
+ %add11 = add i32 %add10, %11
+ %12 = call i32 @llvm.read_register.i32(metadata !24)
+ %add12 = add i32 %add11, %12
+ %13 = call i32 @llvm.read_register.i32(metadata !25)
+ %add13 = add i32 %add12, %13
+ %14 = call i32 @llvm.read_register.i32(metadata !26)
+ %add14 = add i32 %add13, %14
+ %15 = call i32 @llvm.read_register.i32(metadata !27)
+ %add15 = add i32 %add14, %15
+ %16 = call i32 @llvm.read_register.i32(metadata !28)
+ %add16 = add i32 %add15, %16
+ %17 = call i32 @llvm.read_register.i32(metadata !29)
+ %add17 = add i32 %add16, %17
+ %18 = call i32 @llvm.read_register.i32(metadata !30)
+ %add18 = add i32 %add17, %18
+ %19 = call i32 @llvm.read_register.i32(metadata !31)
+ %add19 = add i32 %add18, %19
+ %20 = call i32 @llvm.read_register.i32(metadata !32)
+ %add20 = add i32 %add19, %20
+ %21 = call i32 @llvm.read_register.i32(metadata !33)
+ %add21 = add i32 %add20, %21
+ %22 = call i32 @llvm.read_register.i32(metadata !34)
+ %add22 = add i32 %add21, %22
+ %23 = call i32 @llvm.read_register.i32(metadata !35)
+ %add23 = add i32 %add22, %23
+ %24 = call i32 @llvm.read_register.i32(metadata !36)
+ %add24 = add i32 %add23, %24
+ %25 = call i32 @llvm.read_register.i32(metadata !37)
+ %add25 = add i32 %add24, %25
+ ret i32 %add25
+}
+
+define void @write_mclass_registers(i32 %x) nounwind {
+entry:
+ ; MAINLINE-LABEL: write_mclass_registers:
+ ; MAINLINE: msr apsr_nzcvqg, r0
+ ; MAINLINE: msr apsr_nzcvq, r0
+ ; MAINLINE: msr apsr_g, r0
+ ; MAINLINE: msr apsr_nzcvqg, r0
+ ; MAINLINE: msr iapsr_nzcvqg, r0
+ ; MAINLINE: msr iapsr_nzcvq, r0
+ ; MAINLINE: msr iapsr_g, r0
+ ; MAINLINE: msr iapsr_nzcvqg, r0
+ ; MAINLINE: msr eapsr_nzcvqg, r0
+ ; MAINLINE: msr eapsr_nzcvq, r0
+ ; MAINLINE: msr eapsr_g, r0
+ ; MAINLINE: msr eapsr_nzcvqg, r0
+ ; MAINLINE: msr xpsr_nzcvqg, r0
+ ; MAINLINE: msr xpsr_nzcvq, r0
+ ; MAINLINE: msr xpsr_g, r0
+ ; MAINLINE: msr xpsr_nzcvqg, r0
+ ; MAINLINE: msr ipsr, r0
+ ; MAINLINE: msr epsr, r0
+ ; MAINLINE: msr iepsr, r0
+ ; MAINLINE: msr msp, r0
+ ; MAINLINE: msr psp, r0
+ ; MAINLINE: msr primask, r0
+ ; MAINLINE: msr basepri, r0
+ ; MAINLINE: msr basepri_max, r0
+ ; MAINLINE: msr faultmask, r0
+ ; MAINLINE: msr control, r0
+ ; MAINLINE: msr msplim, r0
+ ; MAINLINE: msr psplim, r0
+ ; MAINLINE: msr msp_ns, r0
+ ; MAINLINE: msr psp_ns, r0
+ ; MAINLINE: msr msplim_ns, r0
+ ; MAINLINE: msr psplim_ns, r0
+ ; MAINLINE: msr primask_ns, r0
+ ; MAINLINE: msr basepri_ns, r0
+ ; MAINLINE: msr faultmask_ns, r0
+ ; MAINLINE: msr control_ns, r0
+ ; MAINLINE: msr sp_ns, r0
+ ; MAINLINE: msr basepri_max_ns, r0
+
+ call void @llvm.write_register.i32(metadata !0, i32 %x)
+ call void @llvm.write_register.i32(metadata !1, i32 %x)
+ call void @llvm.write_register.i32(metadata !2, i32 %x)
+ call void @llvm.write_register.i32(metadata !3, i32 %x)
+ call void @llvm.write_register.i32(metadata !4, i32 %x)
+ call void @llvm.write_register.i32(metadata !5, i32 %x)
+ call void @llvm.write_register.i32(metadata !6, i32 %x)
+ call void @llvm.write_register.i32(metadata !7, i32 %x)
+ call void @llvm.write_register.i32(metadata !8, i32 %x)
+ call void @llvm.write_register.i32(metadata !9, i32 %x)
+ call void @llvm.write_register.i32(metadata !10, i32 %x)
+ call void @llvm.write_register.i32(metadata !11, i32 %x)
+ call void @llvm.write_register.i32(metadata !12, i32 %x)
+ call void @llvm.write_register.i32(metadata !13, i32 %x)
+ call void @llvm.write_register.i32(metadata !14, i32 %x)
+ call void @llvm.write_register.i32(metadata !15, i32 %x)
+ call void @llvm.write_register.i32(metadata !16, i32 %x)
+ call void @llvm.write_register.i32(metadata !17, i32 %x)
+ call void @llvm.write_register.i32(metadata !18, i32 %x)
+ call void @llvm.write_register.i32(metadata !19, i32 %x)
+ call void @llvm.write_register.i32(metadata !20, i32 %x)
+ call void @llvm.write_register.i32(metadata !21, i32 %x)
+ call void @llvm.write_register.i32(metadata !22, i32 %x)
+ call void @llvm.write_register.i32(metadata !23, i32 %x)
+ call void @llvm.write_register.i32(metadata !24, i32 %x)
+ call void @llvm.write_register.i32(metadata !25, i32 %x)
+ call void @llvm.write_register.i32(metadata !26, i32 %x)
+ call void @llvm.write_register.i32(metadata !27, i32 %x)
+ call void @llvm.write_register.i32(metadata !28, i32 %x)
+ call void @llvm.write_register.i32(metadata !29, i32 %x)
+ call void @llvm.write_register.i32(metadata !30, i32 %x)
+ call void @llvm.write_register.i32(metadata !31, i32 %x)
+ call void @llvm.write_register.i32(metadata !32, i32 %x)
+ call void @llvm.write_register.i32(metadata !33, i32 %x)
+ call void @llvm.write_register.i32(metadata !34, i32 %x)
+ call void @llvm.write_register.i32(metadata !35, i32 %x)
+ call void @llvm.write_register.i32(metadata !36, i32 %x)
+ call void @llvm.write_register.i32(metadata !37, i32 %x)
+ ret void
+}
+
+declare i32 @llvm.read_register.i32(metadata) nounwind
+declare void @llvm.write_register.i32(metadata, i32) nounwind
+
+!0 = !{!"apsr"}
+!1 = !{!"apsr_nzcvq"}
+!2 = !{!"apsr_g"}
+!3 = !{!"apsr_nzcvqg"}
+!4 = !{!"iapsr"}
+!5 = !{!"iapsr_nzcvq"}
+!6 = !{!"iapsr_g"}
+!7 = !{!"iapsr_nzcvqg"}
+!8 = !{!"eapsr"}
+!9 = !{!"eapsr_nzcvq"}
+!10 = !{!"eapsr_g"}
+!11 = !{!"eapsr_nzcvqg"}
+!12 = !{!"xpsr"}
+!13 = !{!"xpsr_nzcvq"}
+!14 = !{!"xpsr_g"}
+!15 = !{!"xpsr_nzcvqg"}
+!16 = !{!"ipsr"}
+!17 = !{!"epsr"}
+!18 = !{!"iepsr"}
+!19 = !{!"msp"}
+!20 = !{!"psp"}
+!21 = !{!"primask"}
+!22 = !{!"basepri"}
+!23 = !{!"basepri_max"}
+!24 = !{!"faultmask"}
+!25 = !{!"control"}
+!26 = !{!"msplim"}
+!27 = !{!"psplim"}
+!28 = !{!"msp_ns"}
+!29 = !{!"psp_ns"}
+!30 = !{!"msplim_ns"}
+!31 = !{!"psplim_ns"}
+!32 = !{!"primask_ns"}
+!33 = !{!"basepri_ns"}
+!34 = !{!"faultmask_ns"}
+!35 = !{!"control_ns"}
+!36 = !{!"sp_ns"}
+!37 = !{!"basepri_max_ns"}
+
diff --git a/test/CodeGen/ARM/ssat.ll b/test/CodeGen/ARM/ssat.ll
new file mode 100644
index 000000000000..2b75bc410aa8
--- /dev/null
+++ b/test/CodeGen/ARM/ssat.ll
@@ -0,0 +1,215 @@
+; RUN: llc -mtriple=arm-eabi %s -o - | FileCheck %s
+
+; Check for several conditions that should result in SSAT.
+; For example, the base test is equivalent to
+; x < -k ? -k : (x > k ? k : x) in C. All patterns that bound x
+; to the interval [-k, k] where k is a power of 2 can be
+; transformed into SSAT. At the end there are some tests
+; checking that conditionals are not transformed if they don't
+; match the right pattern.
+
+;
+; Base tests with different bit widths
+;
+
+; x < -k ? -k : (x > k ? k : x)
+; 32-bit base test
+define i32 @sat_base_32bit(i32 %x) #0 {
+; CHECK-LABEL: sat_base_32bit:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpLow = icmp slt i32 %x, -8388608
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %x
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %saturateUp
+ ret i32 %saturateLow
+}
+
+; x < -k ? -k : (x > k ? k : x)
+; 16-bit base test
+define i16 @sat_base_16bit(i16 %x) #0 {
+; CHECK-LABEL: sat_base_16bit:
+; CHECK: ssat r0, #12, r0
+entry:
+ %cmpLow = icmp slt i16 %x, -2048
+ %cmpUp = icmp sgt i16 %x, 2047
+ %saturateUp = select i1 %cmpUp, i16 2047, i16 %x
+ %saturateLow = select i1 %cmpLow, i16 -2048, i16 %saturateUp
+ ret i16 %saturateLow
+}
+
+; x < -k ? -k : (x > k ? k : x)
+; 8-bit base test
+define i8 @sat_base_8bit(i8 %x) #0 {
+; CHECK-LABEL: sat_base_8bit:
+; CHECK: ssat r0, #6, r0
+entry:
+ %cmpLow = icmp slt i8 %x, -32
+ %cmpUp = icmp sgt i8 %x, 31
+ %saturateUp = select i1 %cmpUp, i8 31, i8 %x
+ %saturateLow = select i1 %cmpLow, i8 -32, i8 %saturateUp
+ ret i8 %saturateLow
+}
+
+;
+; Tests where the conditionals that check for upper and lower bounds,
+; or the < and > operators, are arranged in different ways. Only some
+; of the possible combinations that lead to SSAT are tested.
+;
+
+; x < -k ? -k : (x < k ? x : k)
+define i32 @sat_lower_upper_1(i32 %x) #0 {
+; CHECK-LABEL: sat_lower_upper_1:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpLow = icmp slt i32 %x, -8388608
+ %cmpUp = icmp slt i32 %x, 8388607
+ %saturateUp = select i1 %cmpUp, i32 %x, i32 8388607
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %saturateUp
+ ret i32 %saturateLow
+}
+
+; x > -k ? (x > k ? k : x) : -k
+define i32 @sat_lower_upper_2(i32 %x) #0 {
+; CHECK-LABEL: sat_lower_upper_2:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpLow = icmp sgt i32 %x, -8388608
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %x
+ %saturateLow = select i1 %cmpLow, i32 %saturateUp, i32 -8388608
+ ret i32 %saturateLow
+}
+
+; x < k ? (x < -k ? -k : x) : k
+define i32 @sat_upper_lower_1(i32 %x) #0 {
+; CHECK-LABEL: sat_upper_lower_1:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpUp = icmp slt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 %saturateLow, i32 8388607
+ ret i32 %saturateUp
+}
+
+; x > k ? k : (x < -k ? -k : x)
+define i32 @sat_upper_lower_2(i32 %x) #0 {
+; CHECK-LABEL: sat_upper_lower_2:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; k < x ? k : (x > -k ? x : -k)
+define i32 @sat_upper_lower_3(i32 %x) #0 {
+; CHECK-LABEL: sat_upper_lower_3:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpUp = icmp slt i32 8388607, %x
+ %cmpLow = icmp sgt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 %x, i32 -8388608
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+;
+; Miscellanea
+;
+
+; Check that >= and <= work the same as > and <
+; k <= x ? k : (x >= -k ? x : -k)
+define i32 @sat_le_ge(i32 %x) #0 {
+; CHECK-LABEL: sat_le_ge:
+; CHECK: ssat r0, #24, r0
+entry:
+ %cmpUp = icmp sle i32 8388607, %x
+ %cmpLow = icmp sge i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 %x, i32 -8388608
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+;
+; The following tests check for patterns that should not transform
+; into SSAT but are similar enough that could confuse the selector.
+;
+
+; x > k ? k : (x > -k ? -k : x)
+; First condition upper-saturates, second doesn't lower-saturate.
+define i32 @no_sat_missing_lower(i32 %x) #0 {
+; CHECK-LABEL: no_sat_missing_lower
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp sgt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; x < k ? k : (x < -k ? -k : x)
+; Second condition lower-saturates, first doesn't upper-saturate.
+define i32 @no_sat_missing_upper(i32 %x) #0 {
+; CHECK-LABEL: no_sat_missing_upper:
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp slt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; Lower constant is different in the select and in the compare
+define i32 @no_sat_incorrect_constant(i32 %x) #0 {
+; CHECK-LABEL: no_sat_incorrect_constant:
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388607, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; The interval is not [k, ~k]
+define i32 @no_sat_incorrect_interval(i32 %x) #0 {
+; CHECK-LABEL: no_sat_incorrect_interval:
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -19088744
+ %saturateLow = select i1 %cmpLow, i32 -19088744, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; The returned value (y) is not the same as the tested value (x).
+define i32 @no_sat_incorrect_return(i32 %x, i32 %y) #0 {
+; CHECK-LABEL: no_sat_incorrect_return:
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %x, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %y
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
+
+; One of the values in a compare (y) is not the same as the rest
+; of the compare and select values (x).
+define i32 @no_sat_incorrect_compare(i32 %x, i32 %y) #0 {
+; CHECK-LABEL: no_sat_incorrect_compare:
+; CHECK-NOT: ssat
+entry:
+ %cmpUp = icmp sgt i32 %x, 8388607
+ %cmpLow = icmp slt i32 %y, -8388608
+ %saturateLow = select i1 %cmpLow, i32 -8388608, i32 %x
+ %saturateUp = select i1 %cmpUp, i32 8388607, i32 %saturateLow
+ ret i32 %saturateUp
+}
diff --git a/test/CodeGen/ARM/static-addr-hoisting.ll b/test/CodeGen/ARM/static-addr-hoisting.ll
new file mode 100644
index 000000000000..3d47e02f965e
--- /dev/null
+++ b/test/CodeGen/ARM/static-addr-hoisting.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple=thumbv7-apple-ios %s -o - | FileCheck %s
+
+define void @multiple_store() {
+; CHECK-LABEL: multiple_store:
+; CHECK: movw r[[BASE1:[0-9]+]], #16960
+; CHECK: movs [[VAL:r[0-9]+]], #42
+; CHECK: movt r[[BASE1]], #15
+
+; CHECK: str [[VAL]], [r[[BASE1]]]
+; CHECK: str [[VAL]], [r[[BASE1]], #24]
+; CHECK: str.w [[VAL]], [r[[BASE1]], #42]
+
+; CHECK: movw r[[BASE2:[0-9]+]], #20394
+; CHECK: movt r[[BASE2]], #18
+
+; CHECK: str [[VAL]], [r[[BASE2]]]
+ store i32 42, i32* inttoptr(i32 1000000 to i32*)
+ store i32 42, i32* inttoptr(i32 1000024 to i32*)
+ store i32 42, i32* inttoptr(i32 1000042 to i32*)
+ store i32 42, i32* inttoptr(i32 1200042 to i32*)
+ ret void
+}
diff --git a/test/CodeGen/ARM/stc2.ll b/test/CodeGen/ARM/stc2.ll
new file mode 100644
index 000000000000..1127796387bb
--- /dev/null
+++ b/test/CodeGen/ARM/stc2.ll
@@ -0,0 +1,11 @@
+; RUN: not llc < %s -mtriple=armv8-eabi 2>&1 | FileCheck %s
+; RUN: not llc < %s -mtriple=thumbv8-eabi 2>&1 | FileCheck %s
+
+; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.stc2
+define void @stc2(i8* %i) nounwind {
+entry:
+ call void @llvm.arm.stc2(i32 1, i32 2, i8* %i) nounwind
+ ret void
+}
+
+declare void @llvm.arm.stc2(i32, i32, i8*) nounwind
diff --git a/test/CodeGen/ARM/struct_byval.ll b/test/CodeGen/ARM/struct_byval.ll
index d7b9b477ec1e..6c8f6fa0b39c 100644
--- a/test/CodeGen/ARM/struct_byval.ll
+++ b/test/CodeGen/ARM/struct_byval.ll
@@ -1,5 +1,5 @@
; RUN: llc < %s -mtriple=armv7-apple-ios6.0 | FileCheck %s
-; RUN: llc < %s -mtriple=thumbv7-apple-ios6.0 | FileCheck %s -check-prefix=THUMB
+; RUN: llc < %s -mtriple=thumbv7-apple-ios6.0 | FileCheck %s
; RUN: llc < %s -mtriple=armv7-unknown-nacl-gnueabi | FileCheck %s -check-prefix=NACL
; RUN: llc < %s -mtriple=armv5-none-linux-gnueabi | FileCheck %s -check-prefix=NOMOVT
@@ -15,10 +15,6 @@ entry:
; CHECK: ldr
; CHECK: str
; CHECK-NOT:bne
-; THUMB-LABEL: f:
-; THUMB: ldr
-; THUMB: str
-; THUMB-NOT:bne
%st = alloca %struct.SmallStruct, align 4
%call = call i32 @e1(%struct.SmallStruct* byval %st)
ret i32 0
@@ -32,11 +28,6 @@ entry:
; CHECK: sub
; CHECK: str
; CHECK: bne
-; THUMB-LABEL: g:
-; THUMB: ldr
-; THUMB: sub
-; THUMB: str
-; THUMB: bne
; NACL-LABEL: g:
; Ensure that use movw instead of constpool for the loop trip count. But don't
; match the __stack_chk_guard movw
@@ -58,11 +49,6 @@ entry:
; CHECK: sub
; CHECK: vst1
; CHECK: bne
-; THUMB-LABEL: h:
-; THUMB: vld1
-; THUMB: sub
-; THUMB: vst1
-; THUMB: bne
; NACL: movw r{{[1-9]}}, #
; NACL: vld1
; NACL: sub
@@ -83,8 +69,6 @@ declare i32 @e3(%struct.LargeStruct* nocapture byval align 16 %in) nounwind
define void @f3(%struct.SmallStruct* nocapture byval %s) nounwind optsize {
; CHECK-LABEL: f3
; CHECK: bl _consumestruct
-; THUMB-LABEL: f3
-; THUMB: blx _consumestruct
entry:
%0 = bitcast %struct.SmallStruct* %s to i8*
tail call void @consumestruct(i8* %0, i32 80) optsize
@@ -94,8 +78,6 @@ entry:
define void @f4(%struct.SmallStruct* nocapture byval %s) nounwind optsize {
; CHECK-LABEL: f4
; CHECK: bl _consumestruct
-; THUMB-LABEL: f4
-; THUMB: blx _consumestruct
entry:
%addr = getelementptr inbounds %struct.SmallStruct, %struct.SmallStruct* %s, i32 0, i32 0
%0 = bitcast i32* %addr to i8*
@@ -106,9 +88,7 @@ entry:
; 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-LABEL: f5
-; CHECK: b _consumestruct
-; THUMB-LABEL: f5
-; THUMB: b.w _consumestruct
+; CHECK: b{{(\.w)?}} _consumestruct
entry:
%0 = bitcast %struct.SmallStruct* %s to i8*
tail call void @consumestruct(i8* %0, i32 80) optsize
@@ -117,9 +97,7 @@ entry:
define void @f6(i32 %a, i32 %b, i32 %c, i32 %d, %struct.SmallStruct* nocapture byval %s) nounwind optsize {
; CHECK-LABEL: f6
-; CHECK: b _consumestruct
-; THUMB-LABEL: f6
-; THUMB: b.w _consumestruct
+; CHECK: b{{(\.w)?}} _consumestruct
entry:
%addr = getelementptr inbounds %struct.SmallStruct, %struct.SmallStruct* %s, i32 0, i32 0
%0 = bitcast i32* %addr to i8*
@@ -137,9 +115,6 @@ define void @test_I_16() {
; CHECK-LABEL: test_I_16
; CHECK: ldrb
; CHECK: strb
-; THUMB-LABEL: test_I_16
-; THUMB: ldrb
-; THUMB: strb
entry:
call void @use_I(%struct.I.8* byval align 16 undef)
ret void
diff --git a/test/CodeGen/ARM/swift-ios.ll b/test/CodeGen/ARM/swift-ios.ll
new file mode 100644
index 000000000000..a5d09524e11d
--- /dev/null
+++ b/test/CodeGen/ARM/swift-ios.ll
@@ -0,0 +1,68 @@
+; RUN: llc -mtriple=armv7-apple-ios < %s | FileCheck %s
+
+define swiftcc float @t1(float %a, float %b) {
+entry:
+; CHECK: t1
+; CHECK-NOT: vmov
+; CHECK: vadd.f32
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define swiftcc double @t2(double %a, double %b) {
+entry:
+; CHECK: t2
+; CHECK-NOT: vmov
+; CHECK: vadd.f64
+ %add = fadd double %a, %b
+ ret double %add
+}
+
+define swiftcc double @t9(double %d0, double %d1, double %d2, double %d3,
+ double %d4, double %d5, double %d6, double %d7, float %a, float %b) {
+entry:
+; CHECK-LABEL: t9:
+; CHECK-NOT: vmov
+; CHECK: vldr
+ %add = fadd float %a, %b
+ %conv = fpext float %add to double
+ ret double %conv
+}
+
+define swiftcc double @t10(double %d0, double %d1, double %d2, double %d3,
+ double %d4, double %d5, double %a, float %b, double %c) {
+entry:
+; CHECK-LABEL: t10:
+; CHECK-NOT: vmov
+; CHECK: vldr
+ %add = fadd double %a, %c
+ ret double %add
+}
+
+define swiftcc float @t11(double %d0, double %d1, double %d2, double %d3,
+ double %d4, double %d5, double %d6, float %a, double %b, float %c) {
+entry:
+; CHECK-LABEL: t11:
+; CHECK: vldr
+ %add = fadd float %a, %c
+ ret float %add
+}
+
+define swiftcc double @t12(double %a, double %b) {
+entry:
+; CHECK-LABEL: t12:
+; CHECK: vstr
+ %add = fadd double %a, %b
+ %sub = fsub double %a, %b
+ %call = tail call swiftcc double @x(double 0.000000e+00, double 0.000000e+00,
+ double 0.000000e+00, double 0.000000e+00, double 0.000000e+00,
+ double 0.000000e+00, double %add, float 0.000000e+00,
+ double %sub)
+ ret double %call
+}
+
+declare swiftcc double @x(double, double, double, double, double, double,
+ double, float, double)
+
+attributes #0 = { readnone }
+attributes #1 = { readonly }
diff --git a/test/CodeGen/ARM/swift-return.ll b/test/CodeGen/ARM/swift-return.ll
new file mode 100644
index 000000000000..4a5ef5e382ca
--- /dev/null
+++ b/test/CodeGen/ARM/swift-return.ll
@@ -0,0 +1,133 @@
+; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
+
+; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s | FileCheck %s
+; RUN: llc -mtriple=armv7-apple-ios -verify-machineinstrs < %s -O0 | FileCheck --check-prefix=CHECK-O0 %s
+
+; Test how llvm handles return type of {i16, i8}. The return value will be
+; passed in %r0 and %r1.
+; CHECK-LABEL: test:
+; CHECK: bl {{.*}}gen
+; CHECK: sxth {{.*}}, r0
+; CHECK: sxtab r0, {{.*}}, r1
+; CHECK-O0-LABEL: test:
+; CHECK-O0: bl {{.*}}gen
+; CHECK-O0: sxth r0, r0
+; CHECK-O0: sxtb r1, r1
+; CHECK-O0: add r0, r0, r1
+define i16 @test(i32 %key) {
+entry:
+ %key.addr = alloca i32, align 4
+ store i32 %key, i32* %key.addr, align 4
+ %0 = load i32, i32* %key.addr, align 4
+ %call = call swiftcc { i16, i8 } @gen(i32 %0)
+ %v3 = extractvalue { i16, i8 } %call, 0
+ %v1 = sext i16 %v3 to i32
+ %v5 = extractvalue { i16, i8 } %call, 1
+ %v2 = sext i8 %v5 to i32
+ %add = add nsw i32 %v1, %v2
+ %conv = trunc i32 %add to i16
+ ret i16 %conv
+}
+
+declare swiftcc { i16, i8 } @gen(i32)
+
+; We can't pass every return value in register, instead, pass everything in
+; memroy.
+; The caller provides space for the return value and passes the address in %r0.
+; The first input argument will be in %r1.
+; CHECK-LABEL: test2:
+; CHECK: mov r1, r0
+; CHECK: mov r0, sp
+; CHECK: bl {{.*}}gen2
+; CHECK-DAG: add
+; CHECK-DAG: ldr {{.*}}, [sp, #16]
+; CHECK-DAG: add
+; CHECK-DAG: add
+; CHECK-DAG: add
+; CHECK-O0-LABEL: test2:
+; CHECK-O0: str r0
+; CHECK-O0: mov r0, sp
+; CHECK-O0: bl {{.*}}gen2
+; CHECK-O0-DAG: ldr {{.*}}, [sp]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #4]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #8]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #12]
+; CHECK-O0-DAG: ldr {{.*}}, [sp, #16]
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+; CHECK-O0-DAG: add
+define i32 @test2(i32 %key) #0 {
+entry:
+ %key.addr = alloca i32, align 4
+ store i32 %key, i32* %key.addr, align 4
+ %0 = load i32, i32* %key.addr, align 4
+ %call = call swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %0)
+
+ %v3 = extractvalue { i32, i32, i32, i32, i32 } %call, 0
+ %v5 = extractvalue { i32, i32, i32, i32, i32 } %call, 1
+ %v6 = extractvalue { i32, i32, i32, i32, i32 } %call, 2
+ %v7 = extractvalue { i32, i32, i32, i32, i32 } %call, 3
+ %v8 = extractvalue { i32, i32, i32, i32, i32 } %call, 4
+
+ %add = add nsw i32 %v3, %v5
+ %add1 = add nsw i32 %add, %v6
+ %add2 = add nsw i32 %add1, %v7
+ %add3 = add nsw i32 %add2, %v8
+ ret i32 %add3
+}
+
+; The address of the return value is passed in %r0.
+; CHECK-LABEL: gen2:
+; CHECK-DAG: str r1, [r0]
+; CHECK-DAG: str r1, [r0, #4]
+; CHECK-DAG: str r1, [r0, #8]
+; CHECK-DAG: str r1, [r0, #12]
+; CHECK-DAG: str r1, [r0, #16]
+; CHECK-O0-LABEL: gen2:
+; CHECK-O0-DAG: str r1, [r0]
+; CHECK-O0-DAG: str r1, [r0, #4]
+; CHECK-O0-DAG: str r1, [r0, #8]
+; CHECK-O0-DAG: str r1, [r0, #12]
+; CHECK-O0-DAG: str r1, [r0, #16]
+define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
+ %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
+ %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
+ %Z2 = insertvalue { i32, i32, i32, i32, i32 } %Z, i32 %key, 2
+ %Z3 = insertvalue { i32, i32, i32, i32, i32 } %Z2, i32 %key, 3
+ %Z4 = insertvalue { i32, i32, i32, i32, i32 } %Z3, i32 %key, 4
+ ret { i32, i32, i32, i32, i32 } %Z4
+}
+
+; The return value {i32, i32, i32, i32} will be returned via registers %r0, %r1,
+; %r2, %r3.
+; CHECK-LABEL: test3:
+; CHECK: bl {{.*}}gen3
+; CHECK: add r0, r0, r1
+; CHECK: add r0, r0, r2
+; CHECK: add r0, r0, r3
+; CHECK-O0-LABEL: test3:
+; CHECK-O0: bl {{.*}}gen3
+; CHECK-O0: add r0, r0, r1
+; CHECK-O0: add r0, r0, r2
+; CHECK-O0: add r0, r0, r3
+define i32 @test3(i32 %key) #0 {
+entry:
+ %key.addr = alloca i32, align 4
+ store i32 %key, i32* %key.addr, align 4
+ %0 = load i32, i32* %key.addr, align 4
+ %call = call swiftcc { i32, i32, i32, i32 } @gen3(i32 %0)
+
+ %v3 = extractvalue { i32, i32, i32, i32 } %call, 0
+ %v5 = extractvalue { i32, i32, i32, i32 } %call, 1
+ %v6 = extractvalue { i32, i32, i32, i32 } %call, 2
+ %v7 = extractvalue { i32, i32, i32, i32 } %call, 3
+
+ %add = add nsw i32 %v3, %v5
+ %add1 = add nsw i32 %add, %v6
+ %add2 = add nsw i32 %add1, %v7
+ ret i32 %add2
+}
+
+declare swiftcc { i32, i32, i32, i32 } @gen3(i32 %key)
diff --git a/test/CodeGen/ARM/swift-vldm.ll b/test/CodeGen/ARM/swift-vldm.ll
index 9e507279fa09..a53b2413bde1 100644
--- a/test/CodeGen/ARM/swift-vldm.ll
+++ b/test/CodeGen/ARM/swift-vldm.ll
@@ -1,4 +1,5 @@
; RUN: llc < %s -mcpu=swift -mtriple=armv7s-apple-ios | FileCheck %s
+; RUN: llc < %s -arm-assume-misaligned-load-store -mcpu=swift -mtriple=armv7s-apple-ios | FileCheck %s
; Check that we avoid producing vldm instructions using d registers that
; begin in the most-significant half of a q register. These require more
diff --git a/test/CodeGen/ARM/swifterror.ll b/test/CodeGen/ARM/swifterror.ll
new file mode 100644
index 000000000000..17bd7059f6d4
--- /dev/null
+++ b/test/CodeGen/ARM/swifterror.ll
@@ -0,0 +1,381 @@
+; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s
+; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s
+
+declare i8* @malloc(i64)
+declare void @free(i8*)
+%swift_error = type { i64, i8 }
+%struct.S = type { i32, i32, i32, i32, i32, i32 }
+
+; This tests the basic usage of a swifterror parameter. "foo" is the function
+; that takes a swifterror parameter and "caller" is the caller of "foo".
+define float @foo(%swift_error** swifterror %error_ptr_ref) {
+; CHECK-APPLE-LABEL: foo:
+; CHECK-APPLE: mov r0, #16
+; CHECK-APPLE: malloc
+; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], #1
+; CHECK-APPLE-DAG: mov r6, r{{.*}}
+; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
+
+; CHECK-O0-LABEL: foo:
+; CHECK-O0: mov r{{.*}}, #16
+; CHECK-O0: malloc
+; CHECK-O0: mov [[ID2:r[0-9]+]], r0
+; CHECK-O0: mov [[ID:r[0-9]+]], #1
+; CHECK-O0: strb [[ID]], [r0, #8]
+; CHECK-O0: mov r6, [[ID2]]
+entry:
+ %call = call i8* @malloc(i64 16)
+ %call.0 = bitcast i8* %call to %swift_error*
+ store %swift_error* %call.0, %swift_error** %error_ptr_ref
+ %tmp = getelementptr inbounds i8, i8* %call, i64 8
+ store i8 1, i8* %tmp
+ ret float 1.0
+}
+
+; "caller" calls "foo" that takes a swifterror parameter.
+define float @caller(i8* %error_ref) {
+; CHECK-APPLE-LABEL: caller:
+; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
+; CHECK-APPLE-DAG: mov r6, #0
+; CHECK-APPLE: bl {{.*}}foo
+; CHECK-APPLE: cmp r6, #0
+; Access part of the error object and save it to error_ref
+; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
+; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
+; CHECK-APPLE: mov r0, r6
+; CHECK_APPLE: bl {{.*}}free
+
+; CHECK-O0-LABEL: caller:
+; spill r0
+; CHECK-O0-DAG: str r0,
+; CHECK-O0-DAG: mov r6, #0
+; CHECK-O0: bl {{.*}}foo
+; CHECK-O0: mov r{{.*}}, r6
+; CHECK-O0: bne
+; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
+; reload r0
+; CHECK-O0: ldr [[ID:r[0-9]+]],
+; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK-O0: mov r0,
+; CHECK-O0: free
+entry:
+ %error_ptr_ref = alloca swifterror %swift_error*
+ store %swift_error* null, %swift_error** %error_ptr_ref
+ %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+cont:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
+
+; "caller2" is the caller of "foo", it calls "foo" inside a loop.
+define float @caller2(i8* %error_ref) {
+; CHECK-APPLE-LABEL: caller2:
+; CHECK-APPLE-DAG: mov [[ID:r[0-9]+]], r0
+; CHECK-APPLE-DAG: mov r6, #0
+; CHECK-APPLE: bl {{.*}}foo
+; CHECK-APPLE: cmp r6, #0
+; CHECK-APPLE: bne
+; Access part of the error object and save it to error_ref
+; CHECK-APPLE: ldrb [[CODE:r[0-9]+]], [r6, #8]
+; CHECK-APPLE: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK-APPLE: mov r0, r6
+; CHECK_APPLE: bl {{.*}}free
+
+; CHECK-O0-LABEL: caller2:
+; spill r0
+; CHECK-O0-DAG: str r0,
+; CHECK-O0-DAG: mov r6, #0
+; CHECK-O0: bl {{.*}}foo
+; CHECK-O0: mov r{{.*}}, r6
+; CHECK-O0: bne
+; CHECK-O0: ble
+; CHECK-O0: ldrb [[CODE:r[0-9]+]], [r0, #8]
+; reload r0
+; CHECK-O0: ldr [[ID:r[0-9]+]],
+; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK-O0: mov r0,
+; CHECK-O0: free
+entry:
+ %error_ptr_ref = alloca swifterror %swift_error*
+ br label %bb_loop
+bb_loop:
+ store %swift_error* null, %swift_error** %error_ptr_ref
+ %call = call float @foo(%swift_error** swifterror %error_ptr_ref)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+cont:
+ %cmp = fcmp ogt float %call, 1.000000e+00
+ br i1 %cmp, label %bb_end, label %bb_loop
+bb_end:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
+
+; "foo_if" is a function that takes a swifterror parameter, it sets swifterror
+; under a certain condition.
+define float @foo_if(%swift_error** swifterror %error_ptr_ref, i32 %cc) {
+; CHECK-APPLE-LABEL: foo_if:
+; CHECK-APPLE: cmp r0, #0
+; CHECK-APPLE: eq
+; CHECK-APPLE: mov r0, #16
+; CHECK-APPLE: malloc
+; CHECK-APPLE: mov [[ID:r[0-9]+]], #1
+; CHECK-APPLE-DAG: mov r6, r{{.*}}
+; CHECK-APPLE-DAG: strb [[ID]], [r{{.*}}, #8]
+
+; CHECK-O0-LABEL: foo_if:
+; CHECK-O0: cmp r0, #0
+; spill to stack
+; CHECK-O0: str r6
+; CHECK-O0: beq
+; CHECK-O0: mov r0, #16
+; CHECK-O0: malloc
+; CHECK-O0: mov [[ID:r[0-9]+]], r0
+; CHECK-O0: mov [[ID2:[a-z0-9]+]], #1
+; CHECK-O0: strb [[ID2]], [r0, #8]
+; CHECK-O0: mov r6, [[ID]]
+; reload from stack
+; CHECK-O0: ldr r6
+entry:
+ %cond = icmp ne i32 %cc, 0
+ br i1 %cond, label %gen_error, label %normal
+
+gen_error:
+ %call = call i8* @malloc(i64 16)
+ %call.0 = bitcast i8* %call to %swift_error*
+ store %swift_error* %call.0, %swift_error** %error_ptr_ref
+ %tmp = getelementptr inbounds i8, i8* %call, i64 8
+ store i8 1, i8* %tmp
+ ret float 1.0
+
+normal:
+ ret float 0.0
+}
+
+; "foo_loop" is a function that takes a swifterror parameter, it sets swifterror
+; under a certain condition inside a loop.
+define float @foo_loop(%swift_error** swifterror %error_ptr_ref, i32 %cc, float %cc2) {
+; CHECK-APPLE-LABEL: foo_loop:
+; CHECK-APPLE: mov [[CODE:r[0-9]+]], r0
+; swifterror is kept in a register
+; CHECK-APPLE: mov [[ID:r[0-9]+]], r6
+; CHECK-APPLE: cmp [[CODE]], #0
+; CHECK-APPLE: beq
+; CHECK-APPLE: mov r0, #16
+; CHECK-APPLE: malloc
+; CHECK-APPLE: strb r{{.*}}, [{{.*}}[[ID]], #8]
+; CHECK-APPLE: ble
+; CHECK-APPLE: mov r6, [[ID]]
+
+; CHECK-O0-LABEL: foo_loop:
+; CHECK-O0: mov r{{.*}}, r6
+; CHECK-O0: cmp r{{.*}}, #0
+; CHECK-O0: beq
+; CHECK-O0-DAG: movw r{{.*}}, #1
+; CHECK-O0-DAG: mov r{{.*}}, #16
+; CHECK-O0: malloc
+; CHECK-O0-DAG: mov [[ID:r[0-9]+]], r0
+; CHECK-O0-DAG: ldr [[ID2:r[0-9]+]], [sp{{.*}}]
+; CHECK-O0: strb [[ID2]], [{{.*}}[[ID]], #8]
+; spill r0
+; CHECK-O0: str r0, [sp{{.*}}]
+; CHECK-O0: vcmpe
+; CHECK-O0: ble
+; reload from stack
+; CHECK-O0: ldr r6
+entry:
+ br label %bb_loop
+
+bb_loop:
+ %cond = icmp ne i32 %cc, 0
+ br i1 %cond, label %gen_error, label %bb_cont
+
+gen_error:
+ %call = call i8* @malloc(i64 16)
+ %call.0 = bitcast i8* %call to %swift_error*
+ store %swift_error* %call.0, %swift_error** %error_ptr_ref
+ %tmp = getelementptr inbounds i8, i8* %call, i64 8
+ store i8 1, i8* %tmp
+ br label %bb_cont
+
+bb_cont:
+ %cmp = fcmp ogt float %cc2, 1.000000e+00
+ br i1 %cmp, label %bb_end, label %bb_loop
+bb_end:
+ ret float 0.0
+}
+
+; "foo_sret" is a function that takes a swifterror parameter, it also has a sret
+; parameter.
+define void @foo_sret(%struct.S* sret %agg.result, i32 %val1, %swift_error** swifterror %error_ptr_ref) {
+; CHECK-APPLE-LABEL: foo_sret:
+; CHECK-APPLE: mov [[SRET:r[0-9]+]], r0
+; CHECK-APPLE: mov r0, #16
+; CHECK-APPLE: malloc
+; CHECK-APPLE: mov [[REG:r[0-9]+]], #1
+; CHECK-APPLE-DAG: mov r6, r0
+; CHECK-APPLE-DAG: strb [[REG]], [r0, #8]
+; CHECK-APPLE-DAG: str r{{.*}}, [{{.*}}[[SRET]], #4]
+
+; CHECK-O0-LABEL: foo_sret:
+; CHECK-O0: mov r{{.*}}, #16
+; spill to stack: sret and val1
+; CHECK-O0-DAG: str r0
+; CHECK-O0-DAG: str r1
+; CHECK-O0: malloc
+; CHECK-O0: mov [[ID:r[0-9]+]], #1
+; CHECK-O0: strb [[ID]], [r0, #8]
+; reload from stack: sret and val1
+; CHECK-O0: ldr
+; CHECK-O0: ldr
+; CHECK-O0: str r{{.*}}, [{{.*}}, #4]
+; CHECK-O0: mov r6
+entry:
+ %call = call i8* @malloc(i64 16)
+ %call.0 = bitcast i8* %call to %swift_error*
+ store %swift_error* %call.0, %swift_error** %error_ptr_ref
+ %tmp = getelementptr inbounds i8, i8* %call, i64 8
+ store i8 1, i8* %tmp
+ %v2 = getelementptr inbounds %struct.S, %struct.S* %agg.result, i32 0, i32 1
+ store i32 %val1, i32* %v2
+ ret void
+}
+
+; "caller3" calls "foo_sret" that takes a swifterror parameter.
+define float @caller3(i8* %error_ref) {
+; CHECK-APPLE-LABEL: caller3:
+; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
+; CHECK-APPLE: mov r6, #0
+; CHECK-APPLE: bl {{.*}}foo_sret
+; CHECK-APPLE: cmp r6, #0
+; Access part of the error object and save it to error_ref
+; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
+; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
+; CHECK-APPLE: mov r0, r6
+; CHECK_APPLE: bl {{.*}}free
+
+; CHECK-O0-LABEL: caller3:
+; CHECK-O0-DAG: mov r6, #0
+; CHECK-O0-DAG: mov r0
+; CHECK-O0-DAG: mov r1
+; CHECK-O0: bl {{.*}}foo_sret
+; CHECK-O0: mov [[ID2:r[0-9]+]], r6
+; CHECK-O0: cmp [[ID2]]
+; CHECK-O0: bne
+; Access part of the error object and save it to error_ref
+; CHECK-O0: ldrb [[CODE:r[0-9]+]]
+; CHECK-O0: ldr [[ID:r[0-9]+]]
+; CHECK-O0: strb [[CODE]], [{{.*}}[[ID]]]
+; CHECK-O0: mov r0,
+; CHECK_O0: bl {{.*}}free
+entry:
+ %s = alloca %struct.S, align 8
+ %error_ptr_ref = alloca swifterror %swift_error*
+ store %swift_error* null, %swift_error** %error_ptr_ref
+ call void @foo_sret(%struct.S* sret %s, i32 1, %swift_error** swifterror %error_ptr_ref)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+cont:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
+
+; "foo_vararg" is a function that takes a swifterror parameter, it also has
+; variable number of arguments.
+declare void @llvm.va_start(i8*) nounwind
+define float @foo_vararg(%swift_error** swifterror %error_ptr_ref, ...) {
+; CHECK-APPLE-LABEL: foo_vararg:
+; CHECK-APPLE: mov r0, #16
+; CHECK-APPLE: malloc
+; CHECK-APPLE: mov [[REG:r[0-9]+]], r0
+; CHECK-APPLE: mov [[ID:r[0-9]+]], #1
+; CHECK-APPLE-DAG: strb [[ID]], [{{.*}}[[REG]], #8]
+; CHECK-APPLE-DAG: mov r6, [[REG]]
+
+entry:
+ %call = call i8* @malloc(i64 16)
+ %call.0 = bitcast i8* %call to %swift_error*
+ store %swift_error* %call.0, %swift_error** %error_ptr_ref
+ %tmp = getelementptr inbounds i8, i8* %call, i64 8
+ store i8 1, i8* %tmp
+
+ %args = alloca i8*, align 8
+ %a10 = alloca i32, align 4
+ %a11 = alloca i32, align 4
+ %a12 = alloca i32, align 4
+ %v10 = bitcast i8** %args to i8*
+ call void @llvm.va_start(i8* %v10)
+ %v11 = va_arg i8** %args, i32
+ store i32 %v11, i32* %a10, align 4
+ %v12 = va_arg i8** %args, i32
+ store i32 %v12, i32* %a11, align 4
+ %v13 = va_arg i8** %args, i32
+ store i32 %v13, i32* %a12, align 4
+
+ ret float 1.0
+}
+
+; "caller4" calls "foo_vararg" that takes a swifterror parameter.
+define float @caller4(i8* %error_ref) {
+; CHECK-APPLE-LABEL: caller4:
+; CHECK-APPLE: mov [[ID:r[0-9]+]], r0
+; CHECK-APPLE: mov r6, #0
+; CHECK-APPLE: bl {{.*}}foo_vararg
+; CHECK-APPLE: cmp r6, #0
+; Access part of the error object and save it to error_ref
+; CHECK-APPLE: ldrbeq [[CODE:r[0-9]+]], [r6, #8]
+; CHECK-APPLE: strbeq [[CODE]], [{{.*}}[[ID]]]
+; CHECK-APPLE: mov r0, r6
+; CHECK_APPLE: bl {{.*}}free
+entry:
+ %error_ptr_ref = alloca swifterror %swift_error*
+ store %swift_error* null, %swift_error** %error_ptr_ref
+
+ %a10 = alloca i32, align 4
+ %a11 = alloca i32, align 4
+ %a12 = alloca i32, align 4
+ store i32 10, i32* %a10, align 4
+ store i32 11, i32* %a11, align 4
+ store i32 12, i32* %a12, align 4
+ %v10 = load i32, i32* %a10, align 4
+ %v11 = load i32, i32* %a11, align 4
+ %v12 = load i32, i32* %a12, align 4
+
+ %call = call float (%swift_error**, ...) @foo_vararg(%swift_error** swifterror %error_ptr_ref, i32 %v10, i32 %v11, i32 %v12)
+ %error_from_foo = load %swift_error*, %swift_error** %error_ptr_ref
+ %had_error_from_foo = icmp ne %swift_error* %error_from_foo, null
+ %tmp = bitcast %swift_error* %error_from_foo to i8*
+ br i1 %had_error_from_foo, label %handler, label %cont
+
+cont:
+ %v1 = getelementptr inbounds %swift_error, %swift_error* %error_from_foo, i64 0, i32 1
+ %t = load i8, i8* %v1
+ store i8 %t, i8* %error_ref
+ br label %handler
+handler:
+ call void @free(i8* %tmp)
+ ret float 1.0
+}
diff --git a/test/CodeGen/ARM/swiftself.ll b/test/CodeGen/ARM/swiftself.ll
new file mode 100644
index 000000000000..6826b123472f
--- /dev/null
+++ b/test/CodeGen/ARM/swiftself.ll
@@ -0,0 +1,65 @@
+; RUN: llc -verify-machineinstrs -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT --check-prefix=TAILCALL %s
+; RUN: llc -O0 -verify-machineinstrs -mtriple=armv7k-apple-ios8.0 -mcpu=cortex-a7 -o - %s | FileCheck %s
+
+; RUN: llc -verify-machineinstrs -mtriple=armv7-apple-ios -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s
+; RUN: llc -O0 -verify-machineinstrs -mtriple=armv7-apple-ios -o - %s | FileCheck %s
+
+; Parameter with swiftself should be allocated to r10.
+; CHECK-LABEL: swiftself_param:
+; CHECK: mov r0, r10
+define i8 *@swiftself_param(i8* swiftself %addr0) {
+ ret i8 *%addr0
+}
+
+; Check that r10 is used to pass a swiftself argument.
+; CHECK-LABEL: call_swiftself:
+; CHECK: mov r10, r0
+; CHECK: bl {{_?}}swiftself_param
+define i8 *@call_swiftself(i8* %arg) {
+ %res = call i8 *@swiftself_param(i8* swiftself %arg)
+ ret i8 *%res
+}
+
+; r10 should be saved by the callee even if used for swiftself
+; CHECK-LABEL: swiftself_clobber:
+; CHECK: push {r10}
+; ...
+; CHECK: pop {r10}
+define i8 *@swiftself_clobber(i8* swiftself %addr0) {
+ call void asm sideeffect "", "~{r10}"()
+ ret i8 *%addr0
+}
+
+; Demonstrate that we do not need any movs when calling multiple functions
+; with swiftself argument.
+; CHECK-LABEL: swiftself_passthrough:
+; OPT-NOT: mov{{.*}}r10
+; OPT: bl {{_?}}swiftself_param
+; OPT-NOT: mov{{.*}}r10
+; OPT-NEXT: bl {{_?}}swiftself_param
+define void @swiftself_passthrough(i8* swiftself %addr0) {
+ call i8 *@swiftself_param(i8* swiftself %addr0)
+ call i8 *@swiftself_param(i8* swiftself %addr0)
+ ret void
+}
+
+; We can use a tail call if the callee swiftself is the same as the caller one.
+; CHECK-LABEL: swiftself_tail:
+; TAILCALL: b {{_?}}swiftself_param
+; TAILCALL-NOT: pop
+define i8* @swiftself_tail(i8* swiftself %addr0) {
+ call void asm sideeffect "", "~{r10}"()
+ %res = tail call i8* @swiftself_param(i8* swiftself %addr0)
+ ret i8* %res
+}
+
+; We can not use a tail call if the callee swiftself is not the same as the
+; caller one.
+; CHECK-LABEL: swiftself_notail:
+; CHECK: mov r10, r0
+; CHECK: bl {{_?}}swiftself_param
+; CHECK: pop
+define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind {
+ %res = tail call i8* @swiftself_param(i8* swiftself %addr1)
+ ret i8* %res
+}
diff --git a/test/CodeGen/ARM/t2-shrink-ldrpost.ll b/test/CodeGen/ARM/t2-shrink-ldrpost.ll
new file mode 100644
index 000000000000..e26f3848ddcd
--- /dev/null
+++ b/test/CodeGen/ARM/t2-shrink-ldrpost.ll
@@ -0,0 +1,52 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+target triple = "thumbv7m--linux-gnu"
+
+; CHECK-LABEL: f:
+; CHECK: ldm r{{[0-9]}}!, {r[[x:[0-9]]]}
+; CHECK: add.w r[[x]], r[[x]], #3
+; CHECK: stm r{{[0-9]}}!, {r[[x]]}
+define void @f(i32 %n, i32* nocapture %a, i32* nocapture readonly %b) optsize minsize {
+ %1 = icmp sgt i32 %n, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %.lr.ph, %0
+ %i.04 = phi i32 [ %6, %.lr.ph ], [ 0, %0 ]
+ %.03 = phi i32* [ %2, %.lr.ph ], [ %b, %0 ]
+ %.012 = phi i32* [ %5, %.lr.ph ], [ %a, %0 ]
+ %2 = getelementptr inbounds i32, i32* %.03, i32 1
+ %3 = load i32, i32* %.03, align 4
+ %4 = add nsw i32 %3, 3
+ %5 = getelementptr inbounds i32, i32* %.012, i32 1
+ store i32 %4, i32* %.012, align 4
+ %6 = add nsw i32 %i.04, 1
+ %exitcond = icmp eq i32 %6, %n
+ br i1 %exitcond, label %._crit_edge, label %.lr.ph
+
+._crit_edge: ; preds = %.lr.ph, %0
+ ret void
+}
+
+; CHECK-LABEL: f_nominsize:
+; CHECK-NOT: ldm
+define void @f_nominsize(i32 %n, i32* nocapture %a, i32* nocapture readonly %b) optsize {
+ %1 = icmp sgt i32 %n, 0
+ br i1 %1, label %.lr.ph, label %._crit_edge
+
+.lr.ph: ; preds = %.lr.ph, %0
+ %i.04 = phi i32 [ %6, %.lr.ph ], [ 0, %0 ]
+ %.03 = phi i32* [ %2, %.lr.ph ], [ %b, %0 ]
+ %.012 = phi i32* [ %5, %.lr.ph ], [ %a, %0 ]
+ %2 = getelementptr inbounds i32, i32* %.03, i32 1
+ %3 = load i32, i32* %.03, align 4
+ %4 = add nsw i32 %3, 3
+ %5 = getelementptr inbounds i32, i32* %.012, i32 1
+ store i32 %4, i32* %.012, align 4
+ %6 = add nsw i32 %i.04, 1
+ %exitcond = icmp eq i32 %6, %n
+ br i1 %exitcond, label %._crit_edge, label %.lr.ph
+
+._crit_edge: ; preds = %.lr.ph, %0
+ ret void
+}
diff --git a/test/CodeGen/ARM/tail-call-builtin.ll b/test/CodeGen/ARM/tail-call-builtin.ll
new file mode 100644
index 000000000000..c829cc52462e
--- /dev/null
+++ b/test/CodeGen/ARM/tail-call-builtin.ll
@@ -0,0 +1,37 @@
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf %s -o - | FileCheck %s
+
+define i64 @test_mismatched_call(double %in) {
+; CHECK-LABEL: test_mismatched_call:
+; CHECK: bl floor
+; CHECK: vmov r0, r1, d0
+
+ %val = tail call double @floor(double %in)
+ %res = bitcast double %val to i64
+ ret i64 %res
+}
+
+define double @test_matched_call(double %in) {
+; CHECK-LABEL: test_matched_call:
+; CHECK: b floor
+
+ %val = tail call double @floor(double %in)
+ ret double %val
+}
+
+define void @test_irrelevant_call(double %in) {
+; CHECK-LABEL: test_irrelevant_call:
+; CHECK-NOT: bl floor
+
+ %val = tail call double @floor(double %in)
+ ret void
+}
+
+define arm_aapcscc double @test_callingconv(double %in) {
+; CHECK: test_callingconv:
+; CHECK: bl floor
+
+ %val = tail call double @floor(double %in)
+ ret double %val
+}
+
+declare double @floor(double) nounwind readonly
diff --git a/test/CodeGen/ARM/tail-call-weak.ll b/test/CodeGen/ARM/tail-call-weak.ll
index 466c33d38786..e0117dffecbf 100644
--- a/test/CodeGen/ARM/tail-call-weak.ll
+++ b/test/CodeGen/ARM/tail-call-weak.ll
@@ -1,6 +1,6 @@
; RUN: llc -mtriple thumbv7-windows-coff -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-COFF
-; RUN: llc -mtriple thumbv7-elf -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-ELF
-; RUN: llc -mtriple thumbv7-macho -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MACHO
+; RUN: llc -mtriple thumbv7-elf -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-OTHER
+; RUN: llc -mtriple thumbv7-macho -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-OTHER
declare i8* @f()
declare extern_weak i8* @g(i8*)
@@ -14,6 +14,5 @@ define void @test() {
}
; CHECK-COFF: b g
-; CHECK-ELF: bl g
-; CHECK-MACHO: blx _g
+; CHECK-OTHER: bl {{_?}}g
diff --git a/test/CodeGen/ARM/this-return.ll b/test/CodeGen/ARM/this-return.ll
index 802f880c1380..931210c2a8ed 100644
--- a/test/CodeGen/ARM/this-return.ll
+++ b/test/CodeGen/ARM/this-return.ll
@@ -1,5 +1,5 @@
-; RUN: llc < %s -mtriple=armv6-linux-gnueabi | FileCheck %s -check-prefix=CHECKELF
-; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D
+; RUN: llc < %s -mtriple=armv6-linux-gnueabi -arm-this-return-forwarding | FileCheck %s -check-prefix=CHECKELF
+; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 -arm-this-return-forwarding | FileCheck %s -check-prefix=CHECKT2D
%struct.A = type { i8 }
%struct.B = type { i32 }
@@ -24,7 +24,7 @@ entry:
; CHECKELF: b B_ctor_base
; CHECKT2D-LABEL: C_ctor_base:
; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
-; CHECKT2D: blx _A_ctor_base
+; CHECKT2D: bl _A_ctor_base
; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
; CHECKT2D: b.w _B_ctor_base
%0 = bitcast %struct.C* %this to %struct.A*
@@ -43,7 +43,7 @@ entry:
; CHECKELF-NOT: b B_ctor_base_nothisret
; CHECKT2D-LABEL: C_ctor_base_nothisret:
; CHECKT2D: mov [[SAVETHIS:r[0-9]+]], r0
-; CHECKT2D: blx _A_ctor_base_nothisret
+; CHECKT2D: bl _A_ctor_base_nothisret
; CHECKT2D: mov r0, [[SAVETHIS]]
; CHECKT2D-NOT: b.w _B_ctor_base_nothisret
%0 = bitcast %struct.C* %this to %struct.A*
@@ -82,7 +82,7 @@ entry:
; CHECKELF: b B_ctor_complete
; CHECKT2D-LABEL: D_ctor_base:
; CHECKT2D-NOT: mov {{r[0-9]+}}, r0
-; CHECKT2D: blx _B_ctor_complete
+; CHECKT2D: bl _B_ctor_complete
; CHECKT2D-NOT: mov r0, {{r[0-9]+}}
; CHECKT2D: b.w _B_ctor_complete
%b = getelementptr inbounds %struct.D, %struct.D* %this, i32 0, i32 0
diff --git a/test/CodeGen/ARM/thread_pointer.ll b/test/CodeGen/ARM/thread_pointer.ll
index c403fa5c4a2a..fe1d3a4dfd0f 100644
--- a/test/CodeGen/ARM/thread_pointer.ll
+++ b/test/CodeGen/ARM/thread_pointer.ll
@@ -3,8 +3,8 @@
define i8* @test() {
entry:
- %tmp1 = call i8* @llvm.arm.thread.pointer( ) ; <i8*> [#uses=0]
+ %tmp1 = call i8* @llvm.thread.pointer( ) ; <i8*> [#uses=0]
ret i8* %tmp1
}
-declare i8* @llvm.arm.thread.pointer()
+declare i8* @llvm.thread.pointer()
diff --git a/test/CodeGen/ARM/thumb-alignment.ll b/test/CodeGen/ARM/thumb-alignment.ll
index b9ddfbb714d1..8e894d28b6c6 100644
--- a/test/CodeGen/ARM/thumb-alignment.ll
+++ b/test/CodeGen/ARM/thumb-alignment.ll
@@ -3,13 +3,13 @@
@x = external global i32
; CHECK: .globl foo
-; CHECK-NEXT: .align 2
+; CHECK-NEXT: .p2align 2
define i32* @foo() {
ret i32* @x
}
; CHECK: .globl bar
-; CHECK-NEXT: .align 1
+; CHECK-NEXT: .p2align 1
define i32* @bar() {
ret i32* zeroinitializer
}
@@ -22,7 +22,7 @@ define i32* @bar() {
; Create a Thumb-2 jump table, which should force alignment to 4 bytes.
; CHECK: .globl baz
-; CHECK-NEXT: .align 2
+; CHECK-NEXT: .p2align 2
; CHECK: tbb
define i32 @baz() {
%1 = load i32, i32* @c, align 4
diff --git a/test/CodeGen/ARM/thumb-stub.ll b/test/CodeGen/ARM/thumb-stub.ll
new file mode 100644
index 000000000000..68001b6c0eec
--- /dev/null
+++ b/test/CodeGen/ARM/thumb-stub.ll
@@ -0,0 +1,10 @@
+; RUN: llc -relocation-model=pic -mtriple=thumb-apple-darwin < %s | FileCheck %s
+
+declare hidden void @f()
+
+; CHECK: bl _f
+
+define void @g() {
+ call void @f()
+ ret void
+}
diff --git a/test/CodeGen/ARM/thumb1-ldst-opt.ll b/test/CodeGen/ARM/thumb1-ldst-opt.ll
index eb82385de0c5..f3c83f04588f 100644
--- a/test/CodeGen/ARM/thumb1-ldst-opt.ll
+++ b/test/CodeGen/ARM/thumb1-ldst-opt.ll
@@ -1,4 +1,4 @@
-; RUN: llc -stop-after block-placement -o /dev/null %s | FileCheck %s
+; RUN: llc -stop-after block-placement -o - %s | FileCheck %s
target triple = "thumbv6m-none-none"
diff --git a/test/CodeGen/ARM/thumb1-varalloc.ll b/test/CodeGen/ARM/thumb1-varalloc.ll
index 0637be03d565..3787c4282b28 100644
--- a/test/CodeGen/ARM/thumb1-varalloc.ll
+++ b/test/CodeGen/ARM/thumb1-varalloc.ll
@@ -52,7 +52,7 @@ define void @test_simple_var() {
; CHECK: mov r0, sp
; CHECK-NOT: adds r0
-; CHECK: blx
+; CHECK: bl
call void @take_ptr(i8* %addr8)
ret void
}
@@ -67,12 +67,12 @@ define void @test_local_var_addr_aligned() {
%addr2 = bitcast i32* %addr2.32 to i8*
; CHECK: add r0, sp, #{{[0-9]+}}
-; CHECK: blx
+; CHECK: bl
call void @take_ptr(i8* %addr1)
; CHECK: mov r0, sp
; CHECK-NOT: add r0
-; CHECK: blx
+; CHECK: bl
call void @take_ptr(i8* %addr2)
ret void
@@ -87,7 +87,7 @@ define void @test_local_var_big_offset() {
; CHECK: add [[RTMP:r[0-9]+]], sp, #1020
; CHECK: adds [[RTMP]], #8
-; CHECK: blx
+; CHECK: bl
call void @take_ptr(i8* %addr1)
ret void
@@ -100,7 +100,7 @@ define void @test_local_var_offset_1020() {
%addr2 = alloca i8, i32 1020
; CHECK: add r0, sp, #1020
-; CHECK-NEXT: blx
+; CHECK-NEXT: bl
call void @take_ptr(i8* %addr1)
ret void
@@ -116,7 +116,7 @@ define void @test_local_var_offset_1268() {
; CHECK: add r0, sp, #1020
; CHECK: adds r0, #248
-; CHECK-NEXT: blx
+; CHECK-NEXT: bl
call void @take_ptr(i8* %addr1)
ret void
diff --git a/test/CodeGen/ARM/thumb2-size-opt.ll b/test/CodeGen/ARM/thumb2-size-opt.ll
index 0084a456a72e..aba027607ea7 100644
--- a/test/CodeGen/ARM/thumb2-size-opt.ll
+++ b/test/CodeGen/ARM/thumb2-size-opt.ll
@@ -82,3 +82,19 @@ entry:
%shr = lshr i32 %a, %b
ret i32 %shr
}
+
+define i32 @bundled_instruction(i32* %addr, i32** %addr2, i1 %tst) minsize {
+; CHECK-LABEL: bundled_instruction:
+; CHECK: iteee ne
+; CHECK: ldmeq r0!, {{{r[0-9]+}}}
+ br i1 %tst, label %true, label %false
+
+true:
+ ret i32 0
+
+false:
+ %res = load i32, i32* %addr, align 4
+ %next = getelementptr i32, i32* %addr, i32 1
+ store i32* %next, i32** %addr2
+ ret i32 %res
+}
diff --git a/test/CodeGen/ARM/tls-models.ll b/test/CodeGen/ARM/tls-models.ll
index f3c58f74ebf7..d8c74d213b13 100644
--- a/test/CodeGen/ARM/tls-models.ll
+++ b/test/CodeGen/ARM/tls-models.ll
@@ -130,7 +130,7 @@ entry:
; EMU-NOT: __emutls_t.external_gd
; EMU-NOT: __emutls_v.external_gd
-; EMU: .align 2
+; EMU: .p2align 2
; EMU-LABEL: __emutls_v.internal_gd:
; EMU-NEXT: .long 4
; EMU-NEXT: .long 4
@@ -144,7 +144,7 @@ entry:
; EMU-NOT: __emutls_t.external_gd
; EMU-NOT: __emutls_v.external_gd
-; EMU: .align 2
+; EMU: .p2align 2
; EMU-LABEL: __emutls_v.internal_le:
; EMU-NEXT: .long 4
; EMU-NEXT: .long 4
diff --git a/test/CodeGen/ARM/tls3.ll b/test/CodeGen/ARM/tls3.ll
index 94cadeedd938..ca3cde264da7 100644
--- a/test/CodeGen/ARM/tls3.ll
+++ b/test/CodeGen/ARM/tls3.ll
@@ -23,7 +23,7 @@ entry:
; CHECK-NOT: __emutls_t.teste
-; EMU: .align 2
+; EMU: .p2align 2
; EMU-LABEL: __emutls_v.teste:
; EMU-NEXT: .long 8
; EMU-NEXT: .long 4
diff --git a/test/CodeGen/ARM/trap.ll b/test/CodeGen/ARM/trap.ll
index 0baf50b45b20..585218cf337c 100644
--- a/test/CodeGen/ARM/trap.ll
+++ b/test/CodeGen/ARM/trap.ll
@@ -1,38 +1,56 @@
-; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=INSTR
+; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
; RUN: llc < %s -mtriple=arm-apple-darwin -trap-func=_trap | FileCheck %s -check-prefix=FUNC
; RUN: llc < %s -mtriple=arm-apple-darwin -trap-func=_trap -O0 | FileCheck %s -check-prefix=FUNC
-; RUN: llc -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble -triple armv7-unknown-nacl - \
-; RUN: | FileCheck %s -check-prefix=ENCODING-NACL
-; RUN: llc -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \
-; RUN: | FileCheck %s -check-prefix=ENCODING-NACL
+; RUN: llc < %s -mtriple=armv7 -mattr=+nacl-trap | FileCheck %s -check-prefix=NACL
+; RUN: llc < %s -mtriple=armv7 | FileCheck %s -check-prefix=ARM
+; RUN: llc < %s -mtriple=thumbv7 | FileCheck %s -check-prefix=THUMB
+
; RUN: llc -mtriple=armv7 -mattr=+nacl-trap -filetype=obj %s -o - \
; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \
; RUN: | FileCheck %s -check-prefix=ENCODING-NACL
-; RUN: llc -verify-machineinstrs -fast-isel -mtriple=armv7-unknown-nacl -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble -triple armv7-unknown-nacl - \
+; RUN: llc -verify-machineinstrs -fast-isel -mtriple=armv7 -mattr=+nacl-trap -filetype=obj %s -o - \
+; RUN: | llvm-objdump -disassemble -triple armv7 -mattr=+nacl-trap - \
; RUN: | FileCheck %s -check-prefix=ENCODING-NACL
+
; RUN: llc -mtriple=armv7 -filetype=obj %s -o - \
; RUN: | llvm-objdump -disassemble -triple armv7 - \
-; RUN: | FileCheck %s -check-prefix=ENCODING-ALL
+; RUN: | FileCheck %s -check-prefix=ENCODING-ARM
; RUN: llc -verify-machineinstrs -fast-isel -mtriple=armv7 -filetype=obj %s -o - \
; RUN: | llvm-objdump -disassemble -triple armv7 - \
-; RUN: | FileCheck %s -check-prefix=ENCODING-ALL
+; RUN: | FileCheck %s -check-prefix=ENCODING-ARM
+
+; RUN: llc -mtriple=thumbv7 -filetype=obj %s -o - \
+; RUN: | llvm-objdump -disassemble -triple thumbv7 - \
+; RUN: | FileCheck %s -check-prefix=ENCODING-THUMB
+; RUN: llc -verify-machineinstrs -fast-isel -mtriple=thumbv7 -filetype=obj %s -o - \
+; RUN: | llvm-objdump -disassemble -triple thumbv7 - \
+; RUN: | FileCheck %s -check-prefix=ENCODING-THUMB
+
; rdar://7961298
; rdar://9249183
define void @t() nounwind {
entry:
-; INSTR-LABEL: t:
-; INSTR: trap
+; DARWIN-LABEL: t:
+; DARWIN: trap
; FUNC-LABEL: t:
; FUNC: bl __trap
-; ENCODING-NACL: f0 de fe e7
+; NACL-LABEL: t:
+; NACL: .inst 0xe7fedef0
-; ENCODING-ALL: fe de ff e7
+; ARM-LABEL: t:
+; ARM: .inst 0xe7ffdefe
+
+; THUMB-LABEL: t:
+; THUMB: .inst.n 0xdefe
+
+; ENCODING-NACL: f0 de fe e7 trap
+
+; ENCODING-ARM: fe de ff e7 trap
+
+; ENCODING-THUMB: fe de trap
call void @llvm.trap()
unreachable
@@ -40,15 +58,26 @@ entry:
define void @t2() nounwind {
entry:
-; INSTR-LABEL: t2:
-; INSTR: trap
+; DARWIN-LABEL: t2:
+; DARWIN: trap
; FUNC-LABEL: t2:
; FUNC: bl __trap
-; ENCODING-NACL: f0 de fe e7
+; NACL-LABEL: t2:
+; NACL: .inst 0xe7fedef0
+
+; ARM-LABEL: t2:
+; ARM: .inst 0xe7ffdefe
+
+; THUMB-LABEL: t2:
+; THUMB: .inst.n 0xdefe
+
+; ENCODING-NACL: f0 de fe e7 trap
+
+; ENCODING-ARM: fe de ff e7 trap
-; ENCODING-ALL: fe de ff e7
+; ENCODING-THUMB: fe de trap
call void @llvm.debugtrap()
unreachable
diff --git a/test/CodeGen/ARM/truncstore-dag-combine.ll b/test/CodeGen/ARM/truncstore-dag-combine.ll
index 11fa022451f6..5142a305b3a7 100644
--- a/test/CodeGen/ARM/truncstore-dag-combine.ll
+++ b/test/CodeGen/ARM/truncstore-dag-combine.ll
@@ -1,5 +1,8 @@
; RUN: llc -mtriple=arm-eabi -mattr=+v4t %s -o - | FileCheck %s
+; CHECK-LABEL: bar
+; CHECK-NOT: orr
+; CHECK-NOT: mov
define void @bar(i8* %P, i16* %Q) {
entry:
%P1 = bitcast i8* %P to i16* ; <i16*> [#uses=1]
@@ -8,6 +11,9 @@ entry:
ret void
}
+; CHECK-LABEL: foo
+; CHECK-NOT: orr
+; CHECK-NOT: mov
define void @foo(i8* %P, i32* %Q) {
entry:
%P1 = bitcast i8* %P to i32* ; <i32*> [#uses=1]
@@ -15,7 +21,3 @@ entry:
store i32 %tmp, i32* %P1, align 1
ret void
}
-
-; CHECK-NOT: orr
-; CHECK-NOT: mov
-
diff --git a/test/CodeGen/ARM/twoaddrinstr.ll b/test/CodeGen/ARM/twoaddrinstr.ll
index 97a49334b742..f0a95c833c6b 100644
--- a/test/CodeGen/ARM/twoaddrinstr.ll
+++ b/test/CodeGen/ARM/twoaddrinstr.ll
@@ -5,6 +5,7 @@ define void @PR13378() nounwind {
; This was orriginally a crasher trying to schedule the instructions.
; CHECK-LABEL: PR13378:
; CHECK: vld1.32
+; CHECK-NEXT: vmov.i32
; CHECK-NEXT: vst1.32
; CHECK-NEXT: vst1.32
; CHECK-NEXT: vmov.f32
diff --git a/test/CodeGen/ARM/urem-opt-size.ll b/test/CodeGen/ARM/urem-opt-size.ll
new file mode 100644
index 000000000000..7f1cd43bc4e3
--- /dev/null
+++ b/test/CodeGen/ARM/urem-opt-size.ll
@@ -0,0 +1,45 @@
+; When optimising for minimum size, we don't want to expand a div to a mul
+; and a shift sequence. As a result, the urem instruction e.g. will not be
+; expanded to a sequence of umull, lsrs, muls and sub instructions, but
+; just a call to __aeabi_uidivmod.
+;
+; RUN: llc -mtriple=armv7a-eabi -mattr=-neon -verify-machineinstrs %s -o - | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "thumbv7m-arm-none-eabi"
+
+define i32 @foo1() local_unnamed_addr #0 {
+entry:
+; CHECK-LABEL: foo1:
+; CHECK:__aeabi_idiv
+; CHECK-NOT: smmul
+ %call = tail call i32 bitcast (i32 (...)* @GetValue to i32 ()*)()
+ %div = sdiv i32 %call, 1000000
+ ret i32 %div
+}
+
+define i32 @foo2() local_unnamed_addr #0 {
+entry:
+; CHECK-LABEL: foo2:
+; CHECK: __aeabi_uidiv
+; CHECK-NOT: umull
+ %call = tail call i32 bitcast (i32 (...)* @GetValue to i32 ()*)()
+ %div = udiv i32 %call, 1000000
+ ret i32 %div
+}
+
+define i32 @foo3() local_unnamed_addr #0 {
+entry:
+; CHECK-LABEL: foo3:
+; CHECK: __aeabi_uidivmod
+; CHECK-NOT: umull
+ %call = tail call i32 bitcast (i32 (...)* @GetValue to i32 ()*)()
+ %rem = urem i32 %call, 1000000
+ %cmp = icmp eq i32 %rem, 0
+ %conv = zext i1 %cmp to i32
+ ret i32 %conv
+}
+
+declare i32 @GetValue(...) local_unnamed_addr
+
+attributes #0 = { minsize nounwind optsize }
diff --git a/test/CodeGen/ARM/v7k-libcalls.ll b/test/CodeGen/ARM/v7k-libcalls.ll
index a1dfb07ca614..8ca31ef4e652 100644
--- a/test/CodeGen/ARM/v7k-libcalls.ll
+++ b/test/CodeGen/ARM/v7k-libcalls.ll
@@ -145,6 +145,15 @@ define arm_aapcs_vfpcc double @t14(double %x) {
ret double %__exp10
}
+define i16 @t15(double %x) {
+; CHECK-LABEL: t15:
+; CHECK-NOT: vmov
+; CHECK: bl ___truncdfhf2
+ %tmp0 = fptrunc double %x to half
+ %tmp1 = bitcast half %tmp0 to i16
+ ret i16 %tmp1
+}
+
declare arm_aapcs_vfpcc double @x(double, double, double, double, double, double, double, float, double)
declare arm_aapcs_vfpcc double @cos(double) #0
declare arm_aapcs_vfpcc double @sin(double) #0
diff --git a/test/CodeGen/ARM/v7k-sincos.ll b/test/CodeGen/ARM/v7k-sincos.ll
index b89d4dc8120b..2db2dc088d95 100644
--- a/test/CodeGen/ARM/v7k-sincos.ll
+++ b/test/CodeGen/ARM/v7k-sincos.ll
@@ -5,7 +5,7 @@ declare double @cos(double) nounwind readnone
define double @test_stret(double %in) {
; CHECK-LABEL: test_stret:
-; CHECK: blx ___sincos_stret
+; CHECK: bl ___sincos_stret
; CHECK-NOT: ldr
; CHECK: vadd.f64 d0, d0, d1
diff --git a/test/CodeGen/ARM/vcnt.ll b/test/CodeGen/ARM/vcnt.ll
index de251c58e6b9..6d9667bda6f3 100644
--- a/test/CodeGen/ARM/vcnt.ll
+++ b/test/CodeGen/ARM/vcnt.ll
@@ -44,6 +44,13 @@ define <2 x i32> @vclz32(<2 x i32>* %A) nounwind {
ret <2 x i32> %tmp2
}
+define <1 x i64> @vclz64(<1 x i64>* %A) nounwind {
+;CHECK-LABEL: vclz64:
+ %tmp1 = load <1 x i64>, <1 x i64>* %A
+ %tmp2 = call <1 x i64> @llvm.ctlz.v1i64(<1 x i64> %tmp1, i1 0)
+ ret <1 x i64> %tmp2
+}
+
define <16 x i8> @vclzQ8(<16 x i8>* %A) nounwind {
;CHECK-LABEL: vclzQ8:
;CHECK: vclz.i8 {{q[0-9]+}}, {{q[0-9]+}}
@@ -68,13 +75,84 @@ define <4 x i32> @vclzQ32(<4 x i32>* %A) nounwind {
ret <4 x i32> %tmp2
}
+define <2 x i64> @vclzQ64(<2 x i64>* %A) nounwind {
+;CHECK-LABEL: vclzQ64:
+ %tmp1 = load <2 x i64>, <2 x i64>* %A
+ %tmp2 = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %tmp1, i1 0)
+ ret <2 x i64> %tmp2
+}
+
+define <8 x i8> @vclz8b(<8 x i8>* %A) nounwind {
+;CHECK-LABEL: vclz8b:
+;CHECK: vclz.i8 {{d[0-9]+}}, {{d[0-9]+}}
+ %tmp1 = load <8 x i8>, <8 x i8>* %A
+ %tmp2 = call <8 x i8> @llvm.ctlz.v8i8(<8 x i8> %tmp1, i1 1)
+ ret <8 x i8> %tmp2
+}
+
+define <4 x i16> @vclz16b(<4 x i16>* %A) nounwind {
+;CHECK-LABEL: vclz16b:
+;CHECK: vclz.i16 {{d[0-9]+}}, {{d[0-9]+}}
+ %tmp1 = load <4 x i16>, <4 x i16>* %A
+ %tmp2 = call <4 x i16> @llvm.ctlz.v4i16(<4 x i16> %tmp1, i1 1)
+ ret <4 x i16> %tmp2
+}
+
+define <2 x i32> @vclz32b(<2 x i32>* %A) nounwind {
+;CHECK-LABEL: vclz32b:
+;CHECK: vclz.i32 {{d[0-9]+}}, {{d[0-9]+}}
+ %tmp1 = load <2 x i32>, <2 x i32>* %A
+ %tmp2 = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %tmp1, i1 1)
+ ret <2 x i32> %tmp2
+}
+
+define <1 x i64> @vclz64b(<1 x i64>* %A) nounwind {
+;CHECK-LABEL: vclz64b:
+ %tmp1 = load <1 x i64>, <1 x i64>* %A
+ %tmp2 = call <1 x i64> @llvm.ctlz.v1i64(<1 x i64> %tmp1, i1 1)
+ ret <1 x i64> %tmp2
+}
+
+define <16 x i8> @vclzQ8b(<16 x i8>* %A) nounwind {
+;CHECK-LABEL: vclzQ8b:
+;CHECK: vclz.i8 {{q[0-9]+}}, {{q[0-9]+}}
+ %tmp1 = load <16 x i8>, <16 x i8>* %A
+ %tmp2 = call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %tmp1, i1 1)
+ ret <16 x i8> %tmp2
+}
+
+define <8 x i16> @vclzQ16b(<8 x i16>* %A) nounwind {
+;CHECK-LABEL: vclzQ16b:
+;CHECK: vclz.i16 {{q[0-9]+}}, {{q[0-9]+}}
+ %tmp1 = load <8 x i16>, <8 x i16>* %A
+ %tmp2 = call <8 x i16> @llvm.ctlz.v8i16(<8 x i16> %tmp1, i1 1)
+ ret <8 x i16> %tmp2
+}
+
+define <4 x i32> @vclzQ32b(<4 x i32>* %A) nounwind {
+;CHECK-LABEL: vclzQ32b:
+;CHECK: vclz.i32 {{q[0-9]+}}, {{q[0-9]+}}
+ %tmp1 = load <4 x i32>, <4 x i32>* %A
+ %tmp2 = call <4 x i32> @llvm.ctlz.v4i32(<4 x i32> %tmp1, i1 1)
+ ret <4 x i32> %tmp2
+}
+
+define <2 x i64> @vclzQ64b(<2 x i64>* %A) nounwind {
+;CHECK-LABEL: vclzQ64b:
+ %tmp1 = load <2 x i64>, <2 x i64>* %A
+ %tmp2 = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %tmp1, i1 1)
+ ret <2 x i64> %tmp2
+}
+
declare <8 x i8> @llvm.ctlz.v8i8(<8 x i8>, i1) nounwind readnone
declare <4 x i16> @llvm.ctlz.v4i16(<4 x i16>, i1) nounwind readnone
declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1) nounwind readnone
+declare <1 x i64> @llvm.ctlz.v1i64(<1 x i64>, i1) nounwind readnone
declare <16 x i8> @llvm.ctlz.v16i8(<16 x i8>, i1) nounwind readnone
declare <8 x i16> @llvm.ctlz.v8i16(<8 x i16>, i1) nounwind readnone
declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32>, i1) nounwind readnone
+declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) nounwind readnone
define <8 x i8> @vclss8(<8 x i8>* %A) nounwind {
;CHECK-LABEL: vclss8:
diff --git a/test/CodeGen/ARM/vcvt_combine.ll b/test/CodeGen/ARM/vcvt_combine.ll
index 9a8f084d2303..11bed5a1a474 100644
--- a/test/CodeGen/ARM/vcvt_combine.ll
+++ b/test/CodeGen/ARM/vcvt_combine.ll
@@ -62,3 +62,11 @@ define <4 x i32> @t5(<4 x float> %in) {
%vcvt.i = fptosi <4 x float> %mul.i to <4 x i32>
ret <4 x i32> %vcvt.i
}
+
+; CHECK-LABEL: test_illegal_fp_to_int:
+; CHECK: vcvt.s32.f32 {{q[0-9]+}}, {{q[0-9]+}}, #2
+define <3 x i32> @test_illegal_fp_to_int(<3 x float> %in) {
+ %scale = fmul <3 x float> %in, <float 4.0, float 4.0, float 4.0>
+ %val = fptosi <3 x float> %scale to <3 x i32>
+ ret <3 x i32> %val
+} \ No newline at end of file
diff --git a/test/CodeGen/ARM/vdiv_combine.ll b/test/CodeGen/ARM/vdiv_combine.ll
index 8511dbcb6876..4a6c36b42772 100644
--- a/test/CodeGen/ARM/vdiv_combine.ll
+++ b/test/CodeGen/ARM/vdiv_combine.ll
@@ -153,3 +153,11 @@ define <4 x float> @test8(<4 x i32> %in) {
%div.i = fdiv <4 x float> %vcvt.i, <float 2.0, float 2.0, float 2.0, float undef>
ret <4 x float> %div.i
}
+
+; CHECK-LABEL: test_illegal_int_to_fp:
+; CHECK: vcvt.f32.s32
+define <3 x float> @test_illegal_int_to_fp(<3 x i32> %in) {
+ %conv = sitofp <3 x i32> %in to <3 x float>
+ %res = fdiv <3 x float> %conv, <float 4.0, float 4.0, float 4.0>
+ ret <3 x float> %res
+} \ No newline at end of file
diff --git a/test/CodeGen/ARM/vfp-libcalls.ll b/test/CodeGen/ARM/vfp-libcalls.ll
index b08073ab62b3..59d5ccc95840 100644
--- a/test/CodeGen/ARM/vfp-libcalls.ll
+++ b/test/CodeGen/ARM/vfp-libcalls.ll
@@ -4,7 +4,7 @@
define float @test_call(float %a, float %b) {
; CHECK-HARD: vadd.f32 {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
-; CHECK-SOFTISH: blx ___addsf3vfp
+; CHECK-SOFTISH: bl ___addsf3vfp
; CHECK-SOFT: bl ___addsf3{{$}}
%sum = fadd float %a, %b
ret float %sum
diff --git a/test/CodeGen/ARM/vfp-regs-dwarf.ll b/test/CodeGen/ARM/vfp-regs-dwarf.ll
index 1b2055e5aff1..2ab85053a91f 100644
--- a/test/CodeGen/ARM/vfp-regs-dwarf.ll
+++ b/test/CodeGen/ARM/vfp-regs-dwarf.ll
@@ -31,11 +31,10 @@ define void @stack_offsets() !dbg !4 {
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!8, !9}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: 1, file: !1, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.5.0 ", isOptimized: false, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
!1 = !DIFile(filename: "tmp.c", directory: "/Users/tim/llvm/build")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "bar", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2)
+!4 = distinct !DISubprogram(name: "bar", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !5, type: !6, variables: !2)
!5 = !DIFile(filename: "tmp.c", directory: "/Users/tim/llvm/build")
!6 = !DISubroutineType(types: !7)
!7 = !{null}
diff --git a/test/CodeGen/ARM/vminmax.ll b/test/CodeGen/ARM/vminmax.ll
index 011bfd7ff88e..e4f30faa9177 100644
--- a/test/CodeGen/ARM/vminmax.ll
+++ b/test/CodeGen/ARM/vminmax.ll
@@ -291,3 +291,20 @@ declare <8 x i16> @llvm.arm.neon.vmaxu.v8i16(<8 x i16>, <8 x i16>) nounwind read
declare <4 x i32> @llvm.arm.neon.vmaxu.v4i32(<4 x i32>, <4 x i32>) nounwind readnone
declare <4 x float> @llvm.arm.neon.vmaxs.v4f32(<4 x float>, <4 x float>) nounwind readnone
+
+declare float @llvm.maxnum.f32(float %a, float %b)
+declare float @llvm.minnum.f32(float %a, float %b)
+
+define float @maxnum(float %a, float %b) {
+;CHECK-LABEL: maxnum:
+;CHECK: vmax.f32
+ %r = call nnan float @llvm.maxnum.f32(float %a, float %b)
+ ret float %r
+}
+
+define float @minnum(float %a, float %b) {
+;CHECK-LABEL: minnum:
+;CHECK: vmin.f32
+ %r = call nnan float @llvm.minnum.f32(float %a, float %b)
+ ret float %r
+}
diff --git a/test/CodeGen/ARM/warn-stack.ll b/test/CodeGen/ARM/warn-stack.ll
index 474dc1dfb447..6e819e404323 100644
--- a/test/CodeGen/ARM/warn-stack.ll
+++ b/test/CodeGen/ARM/warn-stack.ll
@@ -12,7 +12,7 @@ entry:
ret void
}
-; CHECK: warning: stack size limit exceeded (96) in warn
+; CHECK: warning: stack size limit exceeded (92) in warn
define void @warn() nounwind ssp {
entry:
%buffer = alloca [80 x i8], align 1
diff --git a/test/CodeGen/ARM/wide-compares.ll b/test/CodeGen/ARM/wide-compares.ll
new file mode 100644
index 000000000000..08e07ef76ad7
--- /dev/null
+++ b/test/CodeGen/ARM/wide-compares.ll
@@ -0,0 +1,52 @@
+; RUN: llc -mtriple=armv7-unknown-linux < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-ARM %s
+; RUN: llc -mtriple=thumbv6-unknown-linux < %s | FileCheck --check-prefix=CHECK-THUMB1 %s
+; RUN: llc -mtriple=thumbv7-unknown-linux < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-THUMB2 %s
+
+; CHECK-THUMB1-NOT: sbc
+
+; CHECK-LABEL: test_slt1:
+define i32 @test_slt1(i64 %a, i64 %b) {
+entry:
+ ; CHECK-ARM: subs {{[^,]+}}, r0, r2
+ ; CHECK-ARM: mov [[TMP:[0-9a-z]+]], #2
+ ; CHECK-ARM: sbcs {{[^,]+}}, r1, r3
+ ; CHECK-ARM: movwlt [[TMP]], #1
+ ; CHECK-ARM: mov r0, [[TMP]]
+ ; CHECK-ARM: bx lr
+ ; CHECK-THUMB2: subs {{[^,]+}}, r0, r2
+ ; CHECK-THUMB2: mov.w [[TMP:[0-9a-z]+]], #2
+ ; CHECK-THUMB2: sbcs.w {{[^,]+}}, r1, r3
+ ; CHECK-THUMB2: it lt
+ ; CHECK-THUMB2: movlt.w [[TMP]], #1
+ ; CHECK-THUMB2: mov r0, [[TMP]]
+ ; CHECK-THUMB2: bx lr
+ %cmp = icmp slt i64 %a, %b
+ br i1 %cmp, label %bb1, label %bb2
+bb1:
+ ret i32 1
+bb2:
+ ret i32 2
+}
+
+; CHECK-LABEL: test_slt2:
+define void @test_slt2(i64 %a, i64 %b) {
+entry:
+ %cmp = icmp slt i64 %a, %b
+ ; CHECK-ARM: subs {{[^,]+}}, r0, r2
+ ; CHECK-ARM: sbcs {{[^,]+}}, r1, r3
+ ; CHECK-THUMB2: subs {{[^,]+}}, r0, r2
+ ; CHECK-THUMB2: sbcs.w {{[^,]+}}, r1, r3
+ ; CHECK: bge [[BB2:\.[0-9A-Za-z_]+]]
+ br i1 %cmp, label %bb1, label %bb2
+bb1:
+ call void @f()
+ ret void
+bb2:
+ ; CHECK: [[BB2]]:
+ ; CHECK-NEXT: bl g
+ call void @g()
+ ret void
+}
+
+declare void @f()
+declare void @g()
diff --git a/test/CodeGen/ARM/widen-vmovs.ll b/test/CodeGen/ARM/widen-vmovs.ll
index 316cfabab48c..2abf8d9701fc 100644
--- a/test/CodeGen/ARM/widen-vmovs.ll
+++ b/test/CodeGen/ARM/widen-vmovs.ll
@@ -1,4 +1,4 @@
-; RUN: llc < %s -widen-vmovs -mcpu=cortex-a8 -verify-machineinstrs -disable-block-placement | FileCheck %s
+; RUN: llc < %s -mcpu=cortex-a8 -verify-machineinstrs -disable-block-placement | FileCheck %s
target triple = "thumbv7-apple-ios"
; The 1.0e+10 constant is loaded from the constant pool and kept in a register.
diff --git a/test/CodeGen/ARM/zero-cycle-zero.ll b/test/CodeGen/ARM/zero-cycle-zero.ll
index 4e8696f4418a..2022d88dd0ee 100644
--- a/test/CodeGen/ARM/zero-cycle-zero.ll
+++ b/test/CodeGen/ARM/zero-cycle-zero.ll
@@ -1,5 +1,5 @@
; RUN: llc -mtriple=armv8 -mcpu=cyclone < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTSWIFT
-; RUN: llc -mtriple=armv8 -mcpu=swift < %s | FileCheck %s --check-prefix=CHECK
+; RUN: llc -mtriple=armv8 -mcpu=swift < %s | FileCheck %s
; RUN: llc -mtriple=armv8 -mcpu=cortex-a57 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTSWIFT
declare arm_aapcs_vfpcc void @take_vec64(<2 x i32>)