diff options
Diffstat (limited to 'test/CodeGen/ARM')
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>) |
