diff options
Diffstat (limited to 'test/CodeGen/ARM')
50 files changed, 1392 insertions, 372 deletions
diff --git a/test/CodeGen/ARM/2009-10-16-Scope.ll b/test/CodeGen/ARM/2009-10-16-Scope.ll index ce440e9..a2e7ff7 100644 --- a/test/CodeGen/ARM/2009-10-16-Scope.ll +++ b/test/CodeGen/ARM/2009-10-16-Scope.ll @@ -23,10 +23,10 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone declare i32 @foo(i32) ssp !0 = metadata !{i32 5, i32 2, metadata !1, null} -!1 = metadata !{i32 458763, metadata !2}; [DW_TAG_lexical_block ] +!1 = metadata !{i32 458763, metadata !2, i32 1, i32 1}; [DW_TAG_lexical_block ] !2 = metadata !{i32 458798, i32 0, metadata !3, metadata !"bar", metadata !"bar", metadata !"bar", metadata !3, i32 4, null, i1 false, i1 true}; [DW_TAG_subprogram ] !3 = metadata !{i32 458769, i32 0, i32 12, metadata !"genmodes.i", metadata !"/Users/yash/Downloads", metadata !"clang 1.1", i1 true, i1 false, metadata !"", i32 0}; [DW_TAG_compile_unit ] !4 = metadata !{i32 459008, metadata !5, metadata !"count_", metadata !3, i32 5, metadata !6}; [ DW_TAG_auto_variable ] -!5 = metadata !{i32 458763, metadata !1}; [DW_TAG_lexical_block ] +!5 = metadata !{i32 458763, metadata !1, i32 1, i32 1}; [DW_TAG_lexical_block ] !6 = metadata !{i32 458788, metadata !3, metadata !"int", metadata !3, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5}; [DW_TAG_base_type ] !7 = metadata !{i32 6, i32 1, metadata !2, null} diff --git a/test/CodeGen/ARM/2010-11-30-reloc-movt.ll b/test/CodeGen/ARM/2010-11-30-reloc-movt.ll index 930cd8d..8b164c5 100644 --- a/test/CodeGen/ARM/2010-11-30-reloc-movt.ll +++ b/test/CodeGen/ARM/2010-11-30-reloc-movt.ll @@ -21,20 +21,20 @@ entry: ; OBJ-NEXT: 'sh_entsize' ; OBJ-NEXT: '_section_data', '00482de9 000000e3 000040e3 feffffeb 0088bde8' -; OBJ: Relocation 0x00000000 +; OBJ: Relocation 0 ; OBJ-NEXT: 'r_offset', 0x00000004 -; OBJ-NEXT: 'r_sym', 0x00000007 -; OBJ-NEXT: 'r_type', 0x0000002b +; OBJ-NEXT: 'r_sym', 0x000007 +; OBJ-NEXT: 'r_type', 0x2b -; OBJ: Relocation 0x00000001 +; OBJ: Relocation 1 ; OBJ-NEXT: 'r_offset', 0x00000008 ; OBJ-NEXT: 'r_sym' -; OBJ-NEXT: 'r_type', 0x0000002c +; OBJ-NEXT: 'r_type', 0x2c -; OBJ: # Relocation 0x00000002 +; OBJ: # Relocation 2 ; OBJ-NEXT: 'r_offset', 0x0000000c -; OBJ-NEXT: 'r_sym', 0x00000008 -; OBJ-NEXT: 'r_type', 0x0000001c +; OBJ-NEXT: 'r_sym', 0x000008 +; OBJ-NEXT: 'r_type', 0x1c } diff --git a/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll b/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll index 69d4a14..5cfbb4f 100644 --- a/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll +++ b/test/CodeGen/ARM/2010-12-15-elf-lcomm.ll @@ -5,7 +5,7 @@ @dummy = internal global i32 666 -@array00 = internal global [20 x i32] zeroinitializer +@array00 = internal global [80 x i8] zeroinitializer, align 1 @sum = internal global i32 55 @STRIDE = internal global i32 8 @@ -15,21 +15,22 @@ -; OBJ: Section 0x00000004 +; OBJ: Section 4 ; OBJ-NEXT: '.bss' ; OBJ: 'array00' ; OBJ-NEXT: 'st_value', 0x00000000 ; OBJ-NEXT: 'st_size', 0x00000050 -; OBJ-NEXT: 'st_bind', 0x00000000 -; OBJ-NEXT: 'st_type', 0x00000001 -; OBJ-NEXT: 'st_other', 0x00000000 -; OBJ-NEXT: 'st_shndx', 0x00000004 +; OBJ-NEXT: 'st_bind', 0x0 +; OBJ-NEXT: 'st_type', 0x1 +; OBJ-NEXT: 'st_other', 0x00 +; OBJ-NEXT: 'st_shndx', 0x0004 define i32 @main(i32 %argc) nounwind { %1 = load i32* @sum, align 4 - %2 = getelementptr [20 x i32]* @array00, i32 0, i32 %argc - %3 = load i32* %2, align 4 - %4 = add i32 %1, %3 - ret i32 %4; + %2 = getelementptr [80 x i8]* @array00, i32 0, i32 %argc + %3 = load i8* %2 + %4 = zext i8 %3 to i32 + %5 = add i32 %1, %4 + ret i32 %5 } diff --git a/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll b/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll index 4db3acf..7f0f795 100644 --- a/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll +++ b/test/CodeGen/ARM/2011-06-09-TailCallByVal.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -relocation-model=pic -mcpu=cortex-a8 -arm-tail-calls=1 | FileCheck %s + target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target triple = "thumbv7-apple-darwin10" diff --git a/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll new file mode 100644 index 0000000..f681c34 --- /dev/null +++ b/test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll @@ -0,0 +1,124 @@ +; RUN: llc < %s | FileCheck %s + +; Check debug info output for merged global. +; DW_AT_location +; DW_OP_addr +; DW_OP_plus +; .long __MergedGlobals +; DW_OP_constu +; offset + +;CHECK: .ascii "x2" @ DW_AT_name +;CHECK-NEXT: .byte 0 +;CHECK-NEXT: @ DW_AT_type +;CHECK-NEXT: @ DW_AT_decl_file +;CHECK-NEXT: @ DW_AT_decl_line +;CHECK-NEXT: @ DW_AT_location +;CHECK-NEXT: .byte 3 +;CHECK-NEXT: .long __MergedGlobals +;CHECK-NEXT: .byte 16 +; 4 is byte offset of x2 in __MergedGobals +;CHECK-NEXT: .byte 4 +;CHECK-NEXT: .byte 34 + + +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32" +target triple = "thumbv7-apple-macosx10.7.0" + +@x1 = internal unnamed_addr global i32 1, align 4 +@x2 = internal unnamed_addr global i32 2, align 4 +@x3 = internal unnamed_addr global i32 3, align 4 +@x4 = internal unnamed_addr global i32 4, align 4 +@x5 = global i32 0, align 4 + +define i32 @get1(i32 %a) nounwind optsize ssp { + tail call void @llvm.dbg.value(metadata !{i32 %a}, i64 0, metadata !10), !dbg !30 + %1 = load i32* @x1, align 4, !dbg !31 + tail call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !11), !dbg !31 + store i32 %a, i32* @x1, align 4, !dbg !31 + ret i32 %1, !dbg !31 +} + +define i32 @get2(i32 %a) nounwind optsize ssp { + tail call void @llvm.dbg.value(metadata !{i32 %a}, i64 0, metadata !13), !dbg !32 + %1 = load i32* @x2, align 4, !dbg !33 + tail call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !14), !dbg !33 + store i32 %a, i32* @x2, align 4, !dbg !33 + ret i32 %1, !dbg !33 +} + +define i32 @get3(i32 %a) nounwind optsize ssp { + tail call void @llvm.dbg.value(metadata !{i32 %a}, i64 0, metadata !16), !dbg !34 + %1 = load i32* @x3, align 4, !dbg !35 + tail call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !17), !dbg !35 + store i32 %a, i32* @x3, align 4, !dbg !35 + ret i32 %1, !dbg !35 +} + +define i32 @get4(i32 %a) nounwind optsize ssp { + tail call void @llvm.dbg.value(metadata !{i32 %a}, i64 0, metadata !19), !dbg !36 + %1 = load i32* @x4, align 4, !dbg !37 + tail call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !20), !dbg !37 + store i32 %a, i32* @x4, align 4, !dbg !37 + ret i32 %1, !dbg !37 +} + +define i32 @get5(i32 %a) nounwind optsize ssp { + tail call void @llvm.dbg.value(metadata !{i32 %a}, i64 0, metadata !27), !dbg !38 + %1 = load i32* @x5, align 4, !dbg !39 + tail call void @llvm.dbg.value(metadata !{i32 %1}, i64 0, metadata !28), !dbg !39 + store i32 %a, i32* @x5, align 4, !dbg !39 + ret i32 %1, !dbg !39 +} + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1, !6, !7, !8, !9} +!llvm.dbg.lv.get1 = !{!10, !11} +!llvm.dbg.lv.get2 = !{!13, !14} +!llvm.dbg.lv.get3 = !{!16, !17} +!llvm.dbg.lv.get4 = !{!19, !20} +!llvm.dbg.gv = !{!22, !23, !24, !25, !26} +!llvm.dbg.lv.get5 = !{!27, !28} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"ss3.c", metadata !"/private/tmp", metadata !"clang", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get1", metadata !"get1", metadata !"", metadata !2, i32 5, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get1, null, null} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"ss3.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get2", metadata !"get2", metadata !"", metadata !2, i32 8, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get2, null, null} ; [ DW_TAG_subprogram ] +!7 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get3", metadata !"get3", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get3, null, null} ; [ DW_TAG_subprogram ] +!8 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get4", metadata !"get4", metadata !"", metadata !2, i32 14, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get4, null, null} ; [ DW_TAG_subprogram ] +!9 = metadata !{i32 589870, i32 0, metadata !2, metadata !"get5", metadata !"get5", metadata !"", metadata !2, i32 17, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, i32 (i32)* @get5, null, null} ; [ DW_TAG_subprogram ] +!10 = metadata !{i32 590081, metadata !1, metadata !"a", metadata !2, i32 16777221, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!11 = metadata !{i32 590080, metadata !12, metadata !"b", metadata !2, i32 5, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!12 = metadata !{i32 589835, metadata !1, i32 5, i32 19, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!13 = metadata !{i32 590081, metadata !6, metadata !"a", metadata !2, i32 16777224, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 590080, metadata !15, metadata !"b", metadata !2, i32 8, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!15 = metadata !{i32 589835, metadata !6, i32 8, i32 17, metadata !2, i32 1} ; [ DW_TAG_lexical_block ] +!16 = metadata !{i32 590081, metadata !7, metadata !"a", metadata !2, i32 16777227, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!17 = metadata !{i32 590080, metadata !18, metadata !"b", metadata !2, i32 11, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!18 = metadata !{i32 589835, metadata !7, i32 11, i32 19, metadata !2, i32 2} ; [ DW_TAG_lexical_block ] +!19 = metadata !{i32 590081, metadata !8, metadata !"a", metadata !2, i32 16777230, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 590080, metadata !21, metadata !"b", metadata !2, i32 14, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!21 = metadata !{i32 589835, metadata !8, i32 14, i32 19, metadata !2, i32 3} ; [ DW_TAG_lexical_block ] +!22 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x5", metadata !"x5", metadata !"", metadata !2, i32 16, metadata !5, i32 0, i32 1, i32* @x5} ; [ DW_TAG_variable ] +!23 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x4", metadata !"x4", metadata !"", metadata !2, i32 13, metadata !5, i32 1, i32 1, i32* @x4} ; [ DW_TAG_variable ] +!24 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x3", metadata !"x3", metadata !"", metadata !2, i32 10, metadata !5, i32 1, i32 1, i32* @x3} ; [ DW_TAG_variable ] +!25 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x2", metadata !"x2", metadata !"", metadata !2, i32 7, metadata !5, i32 1, i32 1, i32* @x2} ; [ DW_TAG_variable ] +!26 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x1", metadata !"x1", metadata !"", metadata !2, i32 4, metadata !5, i32 1, i32 1, i32* @x1} ; [ DW_TAG_variable ] +!27 = metadata !{i32 590081, metadata !9, metadata !"a", metadata !2, i32 16777233, metadata !5, i32 0} ; [ DW_TAG_arg_variable ] +!28 = metadata !{i32 590080, metadata !29, metadata !"b", metadata !2, i32 17, metadata !5, i32 0} ; [ DW_TAG_auto_variable ] +!29 = metadata !{i32 589835, metadata !9, i32 17, i32 19, metadata !2, i32 4} ; [ DW_TAG_lexical_block ] +!30 = metadata !{i32 5, i32 16, metadata !1, null} +!31 = metadata !{i32 5, i32 32, metadata !12, null} +!32 = metadata !{i32 8, i32 14, metadata !6, null} +!33 = metadata !{i32 8, i32 29, metadata !15, null} +!34 = metadata !{i32 11, i32 16, metadata !7, null} +!35 = metadata !{i32 11, i32 32, metadata !18, null} +!36 = metadata !{i32 14, i32 16, metadata !8, null} +!37 = metadata !{i32 14, i32 32, metadata !21, null} +!38 = metadata !{i32 17, i32 16, metadata !9, null} +!39 = metadata !{i32 17, i32 32, metadata !29, null} diff --git a/test/CodeGen/ARM/2011-08-12-vmovqqqq-pseudo.ll b/test/CodeGen/ARM/2011-08-12-vmovqqqq-pseudo.ll new file mode 100644 index 0000000..3cbc4cd --- /dev/null +++ b/test/CodeGen/ARM/2011-08-12-vmovqqqq-pseudo.ll @@ -0,0 +1,12 @@ +; RUN: llc %s -mtriple=thumbv7-apple-darwin -verify-machineinstrs -mcpu=cortex-a9 -O0 -o - +; Make sure that the VMOVQQQQ pseudo instruction is handled properly +; by codegen. + +define void @test_vmovqqqq_pseudo() nounwind ssp { +entry: + %vld3_lane = call { <8 x i16>, <8 x i16>, <8 x i16> } @llvm.arm.neon.vld3lane.v8i16(i8* undef, <8 x i16> undef, <8 x i16> undef, <8 x i16> zeroinitializer, i32 7, i32 2) + store { <8 x i16>, <8 x i16>, <8 x i16> } %vld3_lane, { <8 x i16>, <8 x i16>, <8 x i16> }* undef + ret void +} + +declare { <8 x i16>, <8 x i16>, <8 x i16> } @llvm.arm.neon.vld3lane.v8i16(i8*, <8 x i16>, <8 x i16>, <8 x i16>, i32, i32) nounwind readonly diff --git a/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll b/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll new file mode 100644 index 0000000..17264ee --- /dev/null +++ b/test/CodeGen/ARM/2011-08-25-ldmia_ret.ll @@ -0,0 +1,100 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a9 | FileCheck %s +; Test that ldmia_ret preserves implicit operands for return values. +; +; This CFG is reduced from a benchmark miscompile. With current +; if-conversion heuristics, one of the return paths is if-converted +; into sw.bb18 resulting in an ldmia_ret in the middle of the +; block. The postra scheduler needs to know that the return implicitly +; uses the return register, otherwise its antidep breaker scavenges +; the register in order to hoist the constant load required to test +; the switch. + +declare i32 @getint() +declare i1 @getbool() +declare void @foo(i32) +declare i32 @bar(i32) + +define i32 @test(i32 %in1, i32 %in2) nounwind { +entry: + %call = tail call zeroext i1 @getbool() nounwind + br i1 %call, label %sw.bb18, label %sw.bb2 + +sw.bb2: ; preds = %entry + %cmp = tail call zeroext i1 @getbool() nounwind + br i1 %cmp, label %sw.epilog58, label %land.lhs.true + +land.lhs.true: ; preds = %sw.bb2 + %cmp13 = tail call zeroext i1 @getbool() nounwind + br i1 %cmp13, label %if.then, label %sw.epilog58 + +if.then: ; preds = %land.lhs.true + tail call void @foo(i32 %in1) nounwind + br label %sw.epilog58 + +; load the return value +; CHECK: movs [[RRET:r.]], #2 +; hoist the switch constant without clobbering RRET +; CHECK: movw +; CHECK-NOT: [[RRET]] +; CHECK: , #63707 +; CHECK-NOT: [[RRET]] +; CHECK: tst +; If-convert the return +; CHECK: it ne +; Fold the CSR+return into a pop +; CHECK: popne {r4, r5, r7, pc} +sw.bb18: + %call20 = tail call i32 @bar(i32 %in2) nounwind + switch i32 %call20, label %sw.default56 [ + i32 168, label %sw.bb21 + i32 165, label %sw.bb21 + i32 261, label %sw.epilog58 + i32 188, label %sw.epilog58 + i32 187, label %sw.epilog58 + i32 186, label %sw.epilog58 + i32 185, label %sw.epilog58 + i32 184, label %sw.epilog58 + i32 175, label %sw.epilog58 + i32 174, label %sw.epilog58 + i32 173, label %sw.epilog58 + i32 172, label %sw.epilog58 + i32 171, label %sw.epilog58 + i32 167, label %sw.epilog58 + i32 166, label %sw.epilog58 + i32 164, label %sw.epilog58 + i32 163, label %sw.epilog58 + i32 161, label %sw.epilog58 + i32 160, label %sw.epilog58 + i32 -1, label %sw.bb33 + ] + +sw.bb21: ; preds = %sw.bb18, %sw.bb18 + tail call void @foo(i32 %in2) nounwind + %call28 = tail call i32 @getint() nounwind + %tobool = icmp eq i32 %call28, 0 + br i1 %tobool, label %if.then29, label %sw.epilog58 + +if.then29: ; preds = %sw.bb21 + tail call void @foo(i32 %in2) nounwind + br label %sw.epilog58 + +sw.bb33: ; preds = %sw.bb18 + %cmp42 = tail call zeroext i1 @getbool() nounwind + br i1 %cmp42, label %sw.default56, label %land.lhs.true44 + +land.lhs.true44: ; preds = %sw.bb33 + %call50 = tail call i32 @getint() nounwind + %cmp51 = icmp slt i32 %call50, 0 + br i1 %cmp51, label %if.then53, label %sw.default56 + +if.then53: ; preds = %land.lhs.true44 + tail call void @foo(i32 %in2) nounwind + br label %sw.default56 + +sw.default56: ; preds = %sw.bb33, %land.lhs.true44, %if.then53, %sw.bb18 + br label %sw.epilog58 + +sw.epilog58: + %retval.0 = phi i32 [ 4, %sw.default56 ], [ 2, %sw.bb21 ], [ 2, %if.then29 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb18 ], [ 2, %sw.bb2 ], [ 2, %land.lhs.true ], [ 2, %if.then ] + ret i32 %retval.0 +} diff --git a/test/CodeGen/ARM/2011-08-29-SchedCycle.ll b/test/CodeGen/ARM/2011-08-29-SchedCycle.ll new file mode 100644 index 0000000..be188ef --- /dev/null +++ b/test/CodeGen/ARM/2011-08-29-SchedCycle.ll @@ -0,0 +1,45 @@ +; RUN: llc %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -o - + +; When a i64 sub is expanded to subc + sube. +; libcall #1 +; \ +; \ subc +; \ / \ +; \ / \ +; \ / libcall #2 +; sube +; +; If the libcalls are not serialized (i.e. both have chains which are dag +; entry), legalizer can serialize them in arbitrary orders. If it's +; unlucky, it can force libcall #2 before libcall #1 in the above case. +; +; subc +; | +; libcall #2 +; | +; libcall #1 +; | +; sube +; +; However since subc and sube are "glued" together, this ends up being a +; cycle when the scheduler combine subc and sube as a single scheduling +; unit. +; +; The right solution is to fix LegalizeType too chains the libcalls together. +; However, LegalizeType is not processing nodes in order. The fix now is to +; fix subc / sube (and addc / adde) to use physical register dependency instead. +; rdar://10019576 + +define void @t() nounwind { +entry: + %tmp = load i64* undef, align 4 + %tmp5 = udiv i64 %tmp, 30 + %tmp13 = and i64 %tmp5, 64739244643450880 + %tmp16 = sub i64 0, %tmp13 + %tmp19 = and i64 %tmp16, 63 + %tmp20 = urem i64 %tmp19, 3 + %tmp22 = and i64 %tmp16, -272346829004752 + store i64 %tmp22, i64* undef, align 4 + store i64 %tmp20, i64* undef, align 4 + ret void +} diff --git a/test/CodeGen/ARM/2011-08-29-ldr_pre_imm.ll b/test/CodeGen/ARM/2011-08-29-ldr_pre_imm.ll new file mode 100644 index 0000000..6647ed8 --- /dev/null +++ b/test/CodeGen/ARM/2011-08-29-ldr_pre_imm.ll @@ -0,0 +1,34 @@ +; RUN: llc -O3 -mtriple=armv6-apple-darwin -relocation-model=pic < %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:64-n32" + +define void @compdecomp() nounwind { +entry: + %heap = alloca [256 x i32], align 4 + br i1 undef, label %bb25.lr.ph, label %bb17 + +bb17: ; preds = %bb17, %entry + br label %bb17 + +bb25.lr.ph: ; preds = %entry + %0 = sdiv i32 undef, 2 + br label %bb5.i + +bb.i: ; preds = %bb5.i + %1 = shl nsw i32 %k_addr.0.i, 1 + %.sum8.i = add i32 %1, -1 + %2 = getelementptr inbounds [256 x i32]* %heap, i32 0, i32 %.sum8.i + %3 = load i32* %2, align 4 + br i1 false, label %bb5.i, label %bb4.i + +bb4.i: ; preds = %bb.i + %.sum10.i = add i32 %k_addr.0.i, -1 + %4 = getelementptr inbounds [256 x i32]* %heap, i32 0, i32 %.sum10.i + store i32 %3, i32* %4, align 4 + br label %bb5.i + +bb5.i: ; preds = %bb5.i, %bb4.i, %bb.i, %bb25.lr.ph + %k_addr.0.i = phi i32 [ %1, %bb4.i ], [ undef, %bb25.lr.ph ], [ undef, %bb5.i ], [ undef, %bb.i ] + %5 = icmp slt i32 %0, %k_addr.0.i + br i1 %5, label %bb5.i, label %bb.i +} diff --git a/test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll b/test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll new file mode 100644 index 0000000..8fe9102 --- /dev/null +++ b/test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple=armv7-- < %s -mattr=-neon + +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:64:128-a0:0:64-n32" +target triple = "armv7-none-linux-gnueabi" + +@x1 = common global <3 x i16> zeroinitializer +@y1 = common global <3 x i16> zeroinitializer +@z1 = common global <3 x i16> zeroinitializer +@x2 = common global <4 x i16> zeroinitializer +@y2 = common global <4 x i16> zeroinitializer +@z2 = common global <4 x i16> zeroinitializer + +define void @f() { + %1 = load <3 x i16>* @x1 + %2 = load <3 x i16>* @y1 + %3 = sdiv <3 x i16> %1, %2 + store <3 x i16> %3, <3 x i16>* @z1 + %4 = load <4 x i16>* @x2 + %5 = load <4 x i16>* @y2 + %6 = sdiv <4 x i16> %4, %5 + store <4 x i16> %6, <4 x i16>* @z2 + ret void +} diff --git a/test/CodeGen/ARM/2011-09-19-cpsr.ll b/test/CodeGen/ARM/2011-09-19-cpsr.ll new file mode 100644 index 0000000..749a6d2 --- /dev/null +++ b/test/CodeGen/ARM/2011-09-19-cpsr.ll @@ -0,0 +1,54 @@ +; RUN: llc -march=thumb -mcpu=cortex-a8 < %s +; rdar://problem/10137436: sqlite3 miscompile +; +; CHECK: subs +; CHECK: cmp +; CHECK: it + +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32" +target triple = "thumbv7-apple-ios4.0.0" + +declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind + +define hidden fastcc i32 @sqlite3VdbeExec(i32* %p) nounwind { +entry: + br label %sqlite3VarintLen.exit7424 + +sqlite3VarintLen.exit7424: ; preds = %do.body.i7423 + br label %do.body.i + +do.body.i: ; preds = %do.body.i, %sqlite3VarintLen.exit7424 + br i1 undef, label %do.body.i, label %sqlite3VarintLen.exit + +sqlite3VarintLen.exit: ; preds = %do.body.i + %sub2322 = add i64 undef, undef + br i1 undef, label %too_big, label %if.end2327 + +if.end2327: ; preds = %sqlite3VarintLen.exit + br i1 undef, label %if.end2341, label %no_mem + +if.end2341: ; preds = %if.end2327 + br label %for.body2355 + +for.body2355: ; preds = %for.body2355, %if.end2341 + %add2366 = add nsw i32 undef, undef + br i1 undef, label %for.body2377, label %for.body2355 + +for.body2377: ; preds = %for.body2355 + %conv23836154 = zext i32 %add2366 to i64 + %sub2384 = sub i64 %sub2322, %conv23836154 + %conv2385 = trunc i64 %sub2384 to i32 + %len.0.i = select i1 undef, i32 %conv2385, i32 undef + %sub.i7384 = sub nsw i32 %len.0.i, 0 + %call.i.i7385 = call i8* @__memset_chk(i8* undef, i32 0, i32 %sub.i7384, i32 undef) nounwind + unreachable + +too_big: ; preds = %sqlite3VarintLen.exit + unreachable + +no_mem: ; preds = %if.end2327, %for.body, %entry.no_mem_crit_edge + unreachable + +sqlite3ErrStr.exit: ; preds = %if.then82 + unreachable +} diff --git a/test/CodeGen/ARM/2011-09-28-CMovCombineBug.ll b/test/CodeGen/ARM/2011-09-28-CMovCombineBug.ll new file mode 100644 index 0000000..c6f4a93 --- /dev/null +++ b/test/CodeGen/ARM/2011-09-28-CMovCombineBug.ll @@ -0,0 +1,30 @@ +; RUN: llc -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 < %s + +; rdar://10196296 +; ARM target specific dag combine created a cycle in DAG. + +define void @t() nounwind ssp { + %1 = load i64* undef, align 4 + %2 = shl i32 5, 0 + %3 = zext i32 %2 to i64 + %4 = and i64 %1, %3 + %5 = lshr i64 %4, undef + switch i64 %5, label %8 [ + i64 0, label %9 + i64 1, label %6 + i64 4, label %9 + i64 5, label %7 + ] + +; <label>:6 ; preds = %0 + unreachable + +; <label>:7 ; preds = %0 + unreachable + +; <label>:8 ; preds = %0 + unreachable + +; <label>:9 ; preds = %0, %0 + ret void +} diff --git a/test/CodeGen/ARM/atomic-64bit.ll b/test/CodeGen/ARM/atomic-64bit.ll new file mode 100644 index 0000000..e9609ac --- /dev/null +++ b/test/CodeGen/ARM/atomic-64bit.ll @@ -0,0 +1,128 @@ +; RUN: llc < %s -mtriple=armv7-apple-ios | FileCheck %s + +define i64 @test1(i64* %ptr, i64 %val) { +; CHECK: test1 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: adds r0, r2 +; CHECK: adc r1, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw add i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test2(i64* %ptr, i64 %val) { +; CHECK: test2 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: subs r0, r2 +; CHECK: sbc r1, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw sub i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test3(i64* %ptr, i64 %val) { +; CHECK: test3 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: and r0, r2 +; CHECK: and r1, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw and i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test4(i64* %ptr, i64 %val) { +; CHECK: test4 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: orr r0, r2 +; CHECK: orr r1, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw or i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test5(i64* %ptr, i64 %val) { +; CHECK: test5 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: eor r0, r2 +; CHECK: eor r1, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw xor i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test6(i64* %ptr, i64 %val) { +; CHECK: test6 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = atomicrmw xchg i64* %ptr, i64 %val seq_cst + ret i64 %r +} + +define i64 @test7(i64* %ptr, i64 %val1, i64 %val2) { +; CHECK: test7 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: cmp r2 +; CHECK: cmpeq r3 +; CHECK: bne +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = cmpxchg i64* %ptr, i64 %val1, i64 %val2 seq_cst + ret i64 %r +} + +; Compiles down to cmpxchg +; FIXME: Should compile to a single ldrexd +define i64 @test8(i64* %ptr) { +; CHECK: test8 +; CHECK: ldrexd r2, r3 +; CHECK: cmp r2 +; CHECK: cmpeq r3 +; CHECK: bne +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + %r = load atomic i64* %ptr seq_cst, align 8 + ret i64 %r +} + +; Compiles down to atomicrmw xchg; there really isn't any more efficient +; way to write it. +define void @test9(i64* %ptr, i64 %val) { +; CHECK: test9 +; CHECK: dmb ish +; CHECK: ldrexd r2, r3 +; CHECK: strexd {{[a-z0-9]+}}, r0, r1 +; CHECK: cmp +; CHECK: bne +; CHECK: dmb ish + store atomic i64 %val, i64* %ptr seq_cst, align 8 + ret void +} diff --git a/test/CodeGen/ARM/atomic-cmp.ll b/test/CodeGen/ARM/atomic-cmp.ll index f31aa7b..82726da 100644 --- a/test/CodeGen/ARM/atomic-cmp.ll +++ b/test/CodeGen/ARM/atomic-cmp.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s -check-prefix=ARM -; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s -check-prefix=T2 +; RUN: llc < %s -mtriple=armv7-apple-darwin -verify-machineinstrs | FileCheck %s -check-prefix=ARM +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -verify-machineinstrs | FileCheck %s -check-prefix=T2 ; rdar://8964854 define i8 @t(i8* %a, i8 %b, i8 %c) nounwind { @@ -10,8 +10,6 @@ define i8 @t(i8* %a, i8 %b, i8 %c) nounwind { ; T2: t: ; T2: ldrexb ; T2: strexb - %tmp0 = tail call i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* %a, i8 %b, i8 %c) + %tmp0 = cmpxchg i8* %a, i8 %b, i8 %c monotonic ret i8 %tmp0 } - -declare i8 @llvm.atomic.cmp.swap.i8.p0i8(i8* nocapture, i8, i8) nounwind diff --git a/test/CodeGen/ARM/atomic-load-store.ll b/test/CodeGen/ARM/atomic-load-store.ll new file mode 100644 index 0000000..12a8fe4 --- /dev/null +++ b/test/CodeGen/ARM/atomic-load-store.ll @@ -0,0 +1,56 @@ +; RUN: llc < %s -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s -check-prefix=ARM +; RUN: llc < %s -mtriple=armv7-apple-ios -O0 | FileCheck %s -check-prefix=ARM +; RUN: llc < %s -mtriple=thumbv7-apple-ios | FileCheck %s -check-prefix=THUMBTWO +; RUN: llc < %s -mtriple=thumbv6-apple-ios | FileCheck %s -check-prefix=THUMBONE + +define void @test1(i32* %ptr, i32 %val1) { +; ARM: test1 +; ARM: dmb ish +; ARM-NEXT: str +; ARM-NEXT: dmb ish +; THUMBONE: test1 +; THUMBONE: __sync_lock_test_and_set_4 +; THUMBTWO: test1 +; THUMBTWO: dmb ish +; THUMBTWO-NEXT: str +; THUMBTWO-NEXT: dmb ish + store atomic i32 %val1, i32* %ptr seq_cst, align 4 + ret void +} + +define i32 @test2(i32* %ptr) { +; ARM: test2 +; ARM: ldr +; ARM-NEXT: dmb ish +; THUMBONE: test2 +; THUMBONE: __sync_val_compare_and_swap_4 +; THUMBTWO: test2 +; THUMBTWO: ldr +; THUMBTWO-NEXT: dmb ish + %val = load atomic i32* %ptr seq_cst, align 4 + ret i32 %val +} + +define void @test3(i8* %ptr1, i8* %ptr2) { +; ARM: test3 +; ARM: ldrb +; ARM: strb +; THUMBTWO: test3 +; THUMBTWO: ldrb +; THUMBTWO: strb +; THUMBONE: test3 +; THUMBONE: ldrb +; THUMBONE: strb + %val = load atomic i8* %ptr1 unordered, align 1 + store atomic i8 %val, i8* %ptr2 unordered, align 1 + ret void +} + +define void @test4(i8* %ptr1, i8* %ptr2) { +; THUMBONE: test4 +; THUMBONE: ___sync_val_compare_and_swap_1 +; THUMBONE: ___sync_lock_test_and_set_1 + %val = load atomic i8* %ptr1 seq_cst, align 1 + store atomic i8 %val, i8* %ptr2 seq_cst, align 1 + ret void +} diff --git a/test/CodeGen/ARM/atomic-op.ll b/test/CodeGen/ARM/atomic-op.ll index 03940e3..02ce5a1 100644 --- a/test/CodeGen/ARM/atomic-op.ll +++ b/test/CodeGen/ARM/atomic-op.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -mtriple=armv7-apple-darwin10 | FileCheck %s -; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 | FileCheck %s +; RUN: llc < %s -mtriple=armv7-apple-darwin10 -verify-machineinstrs | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -verify-machineinstrs | FileCheck %s define void @func(i32 %argc, i8** %argv) nounwind { entry: @@ -24,80 +24,58 @@ entry: ; CHECK: ldrex ; CHECK: add ; CHECK: strex - call i32 @llvm.atomic.load.add.i32.p0i32( i32* %val1, i32 %tmp ) ; <i32>:0 [#uses=1] + %0 = atomicrmw add i32* %val1, i32 %tmp monotonic store i32 %0, i32* %old ; CHECK: ldrex ; CHECK: sub ; CHECK: strex - call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %val2, i32 30 ) ; <i32>:1 [#uses=1] + %1 = atomicrmw sub i32* %val2, i32 30 monotonic store i32 %1, i32* %old ; CHECK: ldrex ; CHECK: add ; CHECK: strex - call i32 @llvm.atomic.load.add.i32.p0i32( i32* %val2, i32 1 ) ; <i32>:2 [#uses=1] + %2 = atomicrmw add i32* %val2, i32 1 monotonic store i32 %2, i32* %old ; CHECK: ldrex ; CHECK: sub ; CHECK: strex - call i32 @llvm.atomic.load.sub.i32.p0i32( i32* %val2, i32 1 ) ; <i32>:3 [#uses=1] + %3 = atomicrmw sub i32* %val2, i32 1 monotonic store i32 %3, i32* %old ; CHECK: ldrex ; CHECK: and ; CHECK: strex - call i32 @llvm.atomic.load.and.i32.p0i32( i32* %andt, i32 4080 ) ; <i32>:4 [#uses=1] + %4 = atomicrmw and i32* %andt, i32 4080 monotonic store i32 %4, i32* %old ; CHECK: ldrex ; CHECK: or ; CHECK: strex - call i32 @llvm.atomic.load.or.i32.p0i32( i32* %ort, i32 4080 ) ; <i32>:5 [#uses=1] + %5 = atomicrmw or i32* %ort, i32 4080 monotonic store i32 %5, i32* %old ; CHECK: ldrex ; CHECK: eor ; CHECK: strex - call i32 @llvm.atomic.load.xor.i32.p0i32( i32* %xort, i32 4080 ) ; <i32>:6 [#uses=1] + %6 = atomicrmw xor i32* %xort, i32 4080 monotonic store i32 %6, i32* %old ; CHECK: ldrex ; CHECK: cmp ; CHECK: strex - call i32 @llvm.atomic.load.min.i32.p0i32( i32* %val2, i32 16 ) ; <i32>:7 [#uses=1] + %7 = atomicrmw min i32* %val2, i32 16 monotonic store i32 %7, i32* %old %neg = sub i32 0, 1 ; <i32> [#uses=1] ; CHECK: ldrex ; CHECK: cmp ; CHECK: strex - call i32 @llvm.atomic.load.min.i32.p0i32( i32* %val2, i32 %neg ) ; <i32>:8 [#uses=1] + %8 = atomicrmw min i32* %val2, i32 %neg monotonic store i32 %8, i32* %old ; CHECK: ldrex ; CHECK: cmp ; CHECK: strex - call i32 @llvm.atomic.load.max.i32.p0i32( i32* %val2, i32 1 ) ; <i32>:9 [#uses=1] + %9 = atomicrmw max i32* %val2, i32 1 monotonic store i32 %9, i32* %old ; CHECK: ldrex ; CHECK: cmp ; CHECK: strex - call i32 @llvm.atomic.load.max.i32.p0i32( i32* %val2, i32 0 ) ; <i32>:10 [#uses=1] + %10 = atomicrmw max i32* %val2, i32 0 monotonic store i32 %10, i32* %old ret void } - -declare i32 @llvm.atomic.load.add.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.sub.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.and.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.or.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.xor.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.min.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.max.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.umax.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.load.umin.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.swap.i32.p0i32(i32*, i32) nounwind - -declare i32 @llvm.atomic.cmp.swap.i32.p0i32(i32*, i32, i32) nounwind diff --git a/test/CodeGen/ARM/avoid-cpsr-rmw.ll b/test/CodeGen/ARM/avoid-cpsr-rmw.ll index d0c4f3a..92aff70 100644 --- a/test/CodeGen/ARM/avoid-cpsr-rmw.ll +++ b/test/CodeGen/ARM/avoid-cpsr-rmw.ll @@ -6,9 +6,9 @@ define i32 @t(i32 %a, i32 %b, i32 %c, i32 %d) nounwind readnone { entry: ; CHECK: t: -; CHECK: muls r2, r3, r2 -; CHECK-NEXT: mul r0, r0, r1 -; CHECK-NEXT: muls r0, r2, r0 +; CHECK: muls [[REG:(r[0-9]+)]], r2, r3 +; CHECK-NEXT: mul [[REG2:(r[0-9]+)]], r0, r1 +; CHECK-NEXT: muls r0, [[REG2]], [[REG]] %0 = mul nsw i32 %a, %b %1 = mul nsw i32 %c, %d %2 = mul nsw i32 %0, %1 diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll index e01750b..f78d998 100644 --- a/test/CodeGen/ARM/call-tc.ll +++ b/test/CodeGen/ARM/call-tc.ll @@ -1,6 +1,10 @@ ; RUN: llc < %s -mtriple=armv6-apple-darwin -mattr=+vfp2 -arm-tail-calls | FileCheck %s -check-prefix=CHECKV6 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -relocation-model=pic -mattr=+vfp2 -arm-tail-calls | FileCheck %s -check-prefix=CHECKELF ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-tail-calls | FileCheck %s -check-prefix=CHECKT2D +; RUN: llc < %s -mtriple=thumbv7-apple-ios5.0 | FileCheck %s -check-prefix=CHECKT2D + +; Enable tailcall optimization for iOS 5.0 +; rdar://9120031 @t = weak global i32 ()* null ; <i32 ()**> [#uses=1] diff --git a/test/CodeGen/ARM/carry.ll b/test/CodeGen/ARM/carry.ll index 06b459e..f84774d 100644 --- a/test/CodeGen/ARM/carry.ll +++ b/test/CodeGen/ARM/carry.ll @@ -35,3 +35,13 @@ entry: %dw = add i64 %ch, %bw ret i64 %dw } + +; rdar://10073745 +define i64 @f4(i64 %x) nounwind readnone { +entry: +; CHECK: f4: +; CHECK: rsbs r +; CHECK: rsc r + %0 = sub nsw i64 0, %x + ret i64 %0 +} diff --git a/test/CodeGen/ARM/crash-greedy-v6.ll b/test/CodeGen/ARM/crash-greedy-v6.ll new file mode 100644 index 0000000..fd42254 --- /dev/null +++ b/test/CodeGen/ARM/crash-greedy-v6.ll @@ -0,0 +1,32 @@ +; RUN: llc -disable-fp-elim -relocation-model=pic < %s +target triple = "armv6-apple-ios" + +; Reduced from 177.mesa. This test causes a live range split before an LDR_POST instruction. +; That requires leaveIntvBefore to be very accurate about the redefined value number. +define internal void @sample_nearest_3d(i8* nocapture %tObj, i32 %n, float* nocapture %s, float* nocapture %t, float* nocapture %u, float* nocapture %lambda, i8* nocapture %red, i8* nocapture %green, i8* nocapture %blue, i8* nocapture %alpha) nounwind ssp { +entry: + br i1 undef, label %for.end, label %for.body.lr.ph + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body, %for.body.lr.ph + %i.031 = phi i32 [ 0, %for.body.lr.ph ], [ %0, %for.body ] + %arrayidx11 = getelementptr float* %t, i32 %i.031 + %arrayidx15 = getelementptr float* %u, i32 %i.031 + %arrayidx19 = getelementptr i8* %red, i32 %i.031 + %arrayidx22 = getelementptr i8* %green, i32 %i.031 + %arrayidx25 = getelementptr i8* %blue, i32 %i.031 + %arrayidx28 = getelementptr i8* %alpha, i32 %i.031 + %tmp12 = load float* %arrayidx11, align 4 + tail call fastcc void @sample_3d_nearest(i8* %tObj, i8* undef, float undef, float %tmp12, float undef, i8* %arrayidx19, i8* %arrayidx22, i8* %arrayidx25, i8* %arrayidx28) + %0 = add i32 %i.031, 1 + %exitcond = icmp eq i32 %0, %n + br i1 %exitcond, label %for.end, label %for.body + +for.end: ; preds = %for.body, %entry + ret void +} + +declare fastcc void @sample_3d_nearest(i8* nocapture, i8* nocapture, float, float, float, i8* nocapture, i8* nocapture, i8* nocapture, i8* nocapture) nounwind ssp + diff --git a/test/CodeGen/ARM/crash.ll b/test/CodeGen/ARM/crash.ll index 4b6876d..0f6f33e 100644 --- a/test/CodeGen/ARM/crash.ll +++ b/test/CodeGen/ARM/crash.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -verify-arm-pseudo-expand ; <rdar://problem/8529919> %struct.foo = type { i32, i32 } @@ -27,3 +27,45 @@ bb3: exit: ret void } + +; PR10520 - REG_SEQUENCE with implicit-def operands. +define arm_aapcs_vfpcc void @foo() nounwind align 2 { +bb: + %tmp = shufflevector <2 x i64> undef, <2 x i64> undef, <1 x i32> <i32 1> + %tmp8 = bitcast <1 x i64> %tmp to <2 x float> + %tmp9 = shufflevector <2 x float> %tmp8, <2 x float> %tmp8, <4 x i32> <i32 1, i32 1, i32 1, i32 1> + %tmp10 = fmul <4 x float> undef, %tmp9 + %tmp11 = fadd <4 x float> %tmp10, undef + %tmp12 = fadd <4 x float> undef, %tmp11 + %tmp13 = bitcast <4 x float> %tmp12 to i128 + %tmp14 = bitcast i128 %tmp13 to <4 x float> + %tmp15 = bitcast <4 x float> %tmp14 to i128 + %tmp16 = bitcast i128 %tmp15 to <4 x float> + %tmp17 = bitcast <4 x float> %tmp16 to i128 + %tmp18 = bitcast i128 %tmp17 to <4 x float> + %tmp19 = bitcast <4 x float> %tmp18 to i128 + %tmp20 = bitcast i128 %tmp19 to <4 x float> + store <4 x float> %tmp20, <4 x float>* undef, align 16 + ret void +} + +; PR10520, second bug. NEONMoveFixPass needs to preserve implicit operands. +define arm_aapcs_vfpcc void @pr10520_2() nounwind align 2 { +bb: + %tmp76 = shufflevector <2 x i64> zeroinitializer, <2 x i64> zeroinitializer, <1 x i32> <i32 1> + %tmp77 = bitcast <1 x i64> %tmp76 to <2 x float> + %tmp78 = shufflevector <2 x float> %tmp77, <2 x float> %tmp77, <4 x i32> zeroinitializer + %tmp81 = fmul <4 x float> undef, %tmp78 + %tmp82 = fadd <4 x float> %tmp81, undef + %tmp85 = fadd <4 x float> %tmp82, undef + %tmp86 = bitcast <4 x float> %tmp85 to i128 + %tmp136 = bitcast i128 %tmp86 to <4 x float> + %tmp137 = bitcast <4 x float> %tmp136 to i128 + %tmp138 = bitcast i128 %tmp137 to <4 x float> + %tmp139 = bitcast <4 x float> %tmp138 to i128 + %tmp152 = bitcast i128 %tmp139 to <4 x float> + %tmp153 = bitcast <4 x float> %tmp152 to i128 + %tmp154 = bitcast i128 %tmp153 to <4 x float> + store <4 x float> %tmp154, <4 x float>* undef, align 16 + ret void +} diff --git a/test/CodeGen/ARM/debug-info-arg.ll b/test/CodeGen/ARM/debug-info-arg.ll new file mode 100644 index 0000000..b0270f9 --- /dev/null +++ b/test/CodeGen/ARM/debug-info-arg.ll @@ -0,0 +1,65 @@ +; RUN: llc < %s | FileCheck %s +; Test to check argument y's debug info uses FI +; Radar 10048772 +target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32" +target triple = "thumbv7-apple-macosx10.7.0" + +%struct.tag_s = type { i32, i32, i32 } + +define void @foo(%struct.tag_s* nocapture %this, %struct.tag_s* %c, i64 %x, i64 %y, %struct.tag_s* nocapture %ptr1, %struct.tag_s* nocapture %ptr2) nounwind ssp { + tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %this}, i64 0, metadata !5), !dbg !20 + tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %c}, i64 0, metadata !13), !dbg !21 + tail call void @llvm.dbg.value(metadata !{i64 %x}, i64 0, metadata !14), !dbg !22 + tail call void @llvm.dbg.value(metadata !{i64 %y}, i64 0, metadata !17), !dbg !23 +;CHECK: @DEBUG_VALUE: foo:y <- R7+4294967295 + tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr1}, i64 0, metadata !18), !dbg !24 + tail call void @llvm.dbg.value(metadata !{%struct.tag_s* %ptr2}, i64 0, metadata !19), !dbg !25 + %1 = icmp eq %struct.tag_s* %c, null, !dbg !26 + br i1 %1, label %3, label %2, !dbg !26 + +; <label>:2 ; preds = %0 + tail call void @foobar(i64 %x, i64 %y) nounwind, !dbg !28 + br label %3, !dbg !28 + +; <label>:3 ; preds = %0, %2 + ret void, !dbg !29 +} + +declare void @foobar(i64, i64) + +declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1} +!llvm.dbg.lv.foo = !{!5, !13, !14, !17, !18, !19} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !"Apple clang version 3.0 (tags/Apple/clang-211.10.1) (based on LLVM 3.0svn)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 11, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 true, void (%struct.tag_s*, %struct.tag_s*, i64, i64, %struct.tag_s*, %struct.tag_s*)* @foo, null, null} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"one.c", metadata !"/Volumes/Athwagate/R10048772", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{null} +!5 = metadata !{i32 590081, metadata !1, metadata !"this", metadata !2, i32 16777227, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!6 = metadata !{i32 589839, metadata !0, metadata !"", null, i32 0, i64 32, i64 32, i64 0, i32 0, metadata !7} ; [ DW_TAG_pointer_type ] +!7 = metadata !{i32 589843, metadata !0, metadata !"tag_s", metadata !2, i32 5, i64 96, i64 32, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_structure_type ] +!8 = metadata !{metadata !9, metadata !11, metadata !12} +!9 = metadata !{i32 589837, metadata !7, metadata !"x", metadata !2, i32 6, i64 32, i64 32, i64 0, i32 0, metadata !10} ; [ DW_TAG_member ] +!10 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!11 = metadata !{i32 589837, metadata !7, metadata !"y", metadata !2, i32 7, i64 32, i64 32, i64 32, i32 0, metadata !10} ; [ DW_TAG_member ] +!12 = metadata !{i32 589837, metadata !7, metadata !"z", metadata !2, i32 8, i64 32, i64 32, i64 64, i32 0, metadata !10} ; [ DW_TAG_member ] +!13 = metadata !{i32 590081, metadata !1, metadata !"c", metadata !2, i32 33554443, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!14 = metadata !{i32 590081, metadata !1, metadata !"x", metadata !2, i32 50331659, metadata !15, i32 0} ; [ DW_TAG_arg_variable ] +!15 = metadata !{i32 589846, metadata !0, metadata !"UInt64", metadata !2, i32 1, i64 0, i64 0, i64 0, i32 0, metadata !16} ; [ DW_TAG_typedef ] +!16 = metadata !{i32 589860, metadata !0, metadata !"long long unsigned int", null, i32 0, i64 64, i64 32, i64 0, i32 0, i32 7} ; [ DW_TAG_base_type ] +!17 = metadata !{i32 590081, metadata !1, metadata !"y", metadata !2, i32 67108875, metadata !15, i32 0} ; [ DW_TAG_arg_variable ] +!18 = metadata !{i32 590081, metadata !1, metadata !"ptr1", metadata !2, i32 83886091, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!19 = metadata !{i32 590081, metadata !1, metadata !"ptr2", metadata !2, i32 100663307, metadata !6, i32 0} ; [ DW_TAG_arg_variable ] +!20 = metadata !{i32 11, i32 24, metadata !1, null} +!21 = metadata !{i32 11, i32 44, metadata !1, null} +!22 = metadata !{i32 11, i32 54, metadata !1, null} +!23 = metadata !{i32 11, i32 64, metadata !1, null} +!24 = metadata !{i32 11, i32 81, metadata !1, null} +!25 = metadata !{i32 11, i32 101, metadata !1, null} +!26 = metadata !{i32 12, i32 3, metadata !27, null} +!27 = metadata !{i32 589835, metadata !1, i32 11, i32 107, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] +!28 = metadata !{i32 13, i32 5, metadata !27, null} +!29 = metadata !{i32 14, i32 1, metadata !27, null} diff --git a/test/CodeGen/ARM/debug-info-blocks.ll b/test/CodeGen/ARM/debug-info-blocks.ll index 519c40e..2c59316 100644 --- a/test/CodeGen/ARM/debug-info-blocks.ll +++ b/test/CodeGen/ARM/debug-info-blocks.ll @@ -1,5 +1,5 @@ ; RUN: llc -O0 < %s | FileCheck %s -; CHECK: @DEBUG_VALUE: mydata <- [sp+#8]+#0 +; CHECK: @DEBUG_VALUE: mydata <- [sp+#4]+#0 ; Radar 9331779 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" target triple = "thumbv7-apple-macosx10.7.0" diff --git a/test/CodeGen/ARM/debug-info-sreg2.ll b/test/CodeGen/ARM/debug-info-sreg2.ll index 16aeab3..ee777ce 100644 --- a/test/CodeGen/ARM/debug-info-sreg2.ll +++ b/test/CodeGen/ARM/debug-info-sreg2.ll @@ -5,9 +5,9 @@ target triple = "thumbv7-apple-macosx10.6.7" ;CHECK: Ldebug_loc0: ;CHECK-NEXT: .long Ltmp1 -;CHECK-NEXT: .long Ltmp3 -;CHECK-NEXT: Lset9 = Ltmp10-Ltmp9 @ Loc expr size -;CHECK-NEXT: .short Lset9 +;CHECK-NEXT: .long Ltmp2 +;CHECK-NEXT: Lset8 = Ltmp10-Ltmp9 @ Loc expr size +;CHECK-NEXT: .short Lset8 ;CHECK-NEXT: Ltmp9: ;CHECK-NEXT: .byte 144 @ DW_OP_regx for S register diff --git a/test/CodeGen/ARM/divmod.ll b/test/CodeGen/ARM/divmod.ll new file mode 100644 index 0000000..49c4103 --- /dev/null +++ b/test/CodeGen/ARM/divmod.ll @@ -0,0 +1,58 @@ +; RUN: llc < %s -mtriple=arm-apple-ios5.0 | FileCheck %s + +define void @foo(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { +entry: +; CHECK: foo: +; CHECK: bl ___divmodsi4 +; CHECK-NOT: bl ___divmodsi4 + %div = sdiv i32 %x, %y + store i32 %div, i32* %P, align 4 + %rem = srem i32 %x, %y + %arrayidx6 = getelementptr inbounds i32* %P, i32 1 + store i32 %rem, i32* %arrayidx6, align 4 + ret void +} + +define void @bar(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { +entry: +; CHECK: bar: +; CHECK: bl ___udivmodsi4 +; CHECK-NOT: bl ___udivmodsi4 + %div = udiv i32 %x, %y + store i32 %div, i32* %P, align 4 + %rem = urem i32 %x, %y + %arrayidx6 = getelementptr inbounds i32* %P, i32 1 + store i32 %rem, i32* %arrayidx6, align 4 + ret void +} + +; rdar://9280991 +@flags = external unnamed_addr global i32 +@tabsize = external unnamed_addr global i32 + +define void @do_indent(i32 %cols) nounwind { +entry: +; CHECK: do_indent: + %0 = load i32* @flags, align 4 + %1 = and i32 %0, 67108864 + %2 = icmp eq i32 %1, 0 + br i1 %2, label %bb1, label %bb + +bb: +; CHECK: bl ___divmodsi4 + %3 = load i32* @tabsize, align 4 + %4 = srem i32 %cols, %3 + %5 = sdiv i32 %cols, %3 + %6 = tail call i32 @llvm.objectsize.i32(i8* null, i1 false) + %7 = tail call i8* @__memset_chk(i8* null, i32 9, i32 %5, i32 %6) nounwind + br label %bb1 + +bb1: + %line_indent_len.0 = phi i32 [ %4, %bb ], [ 0, %entry ] + %8 = getelementptr inbounds i8* null, i32 %line_indent_len.0 + store i8 0, i8* %8, align 1 + ret void +} + +declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readnone +declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind diff --git a/test/CodeGen/ARM/elf-lcomm-align.ll b/test/CodeGen/ARM/elf-lcomm-align.ll new file mode 100644 index 0000000..4679299 --- /dev/null +++ b/test/CodeGen/ARM/elf-lcomm-align.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=arm-linux-gnueabi -O0 | FileCheck %s +; run with -O0 to avoid arm global merging. + +@c = internal global i8 0, align 1 +@x = internal global i32 0, align 4 + +; CHECK: .lcomm c,1 +; .lcomm doesn't support alignment. +; CHECK: .local x +; CHECK-NEXT: .comm x,4,4 + +define i32 @foo() nounwind { + ret i32 sub (i32 ptrtoint (i8* @c to i32), i32 ptrtoint (i32* @x to i32)) +} diff --git a/test/CodeGen/ARM/fabss.ll b/test/CodeGen/ARM/fabss.ll index 51efe51..45c322d 100644 --- a/test/CodeGen/ARM/fabss.ll +++ b/test/CodeGen/ARM/fabss.ll @@ -22,6 +22,8 @@ declare float @fabsf(float) ; NFP0: vabs.f32 s1, s1 ; CORTEXA8: test: -; CORTEXA8: vabs.f32 d1, d1 +; CORTEXA8: vadd.f32 [[D1:d[0-9]+]] +; CORTEXA8: vabs.f32 {{d[0-9]+}}, [[D1]] + ; CORTEXA9: test: ; CORTEXA9: vabs.f32 s{{.}}, s{{.}} diff --git a/test/CodeGen/ARM/fast-isel.ll b/test/CodeGen/ARM/fast-isel.ll index eb0c5c8..465e85f 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 -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM -; RUN: llc < %s -O0 -fast-isel-abort -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-darwin | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefix=THUMB ; Very basic fast-isel functionality. define i32 @add(i32 %a, i32 %b) nounwind { diff --git a/test/CodeGen/ARM/fp_convert.ll b/test/CodeGen/ARM/fp_convert.ll index 86c06f1..7002cec 100644 --- a/test/CodeGen/ARM/fp_convert.ll +++ b/test/CodeGen/ARM/fp_convert.ll @@ -7,7 +7,8 @@ define i32 @test1(float %a, float %b) { ; VFP2: test1: ; VFP2: vcvt.s32.f32 s{{.}}, s{{.}} ; NEON: test1: -; NEON: vcvt.s32.f32 d0, d0 +; NEON: vadd.f32 [[D0:d[0-9]+]] +; NEON: vcvt.s32.f32 d0, [[D0]] entry: %0 = fadd float %a, %b %1 = fptosi float %0 to i32 @@ -18,7 +19,8 @@ define i32 @test2(float %a, float %b) { ; VFP2: test2: ; VFP2: vcvt.u32.f32 s{{.}}, s{{.}} ; NEON: test2: -; NEON: vcvt.u32.f32 d0, d0 +; NEON: vadd.f32 [[D0:d[0-9]+]] +; NEON: vcvt.u32.f32 d0, [[D0]] entry: %0 = fadd float %a, %b %1 = fptoui float %0 to i32 diff --git a/test/CodeGen/ARM/fpmem.ll b/test/CodeGen/ARM/fpmem.ll index c3cff18..3833933 100644 --- a/test/CodeGen/ARM/fpmem.ll +++ b/test/CodeGen/ARM/fpmem.ll @@ -14,6 +14,24 @@ define float @f2(float* %v, float %u) { ret float %tmp1 } +define float @f2offset(float* %v, float %u) { +; CHECK: f2offset: +; CHECK: vldr.32{{.*}}, #4] + %addr = getelementptr float* %v, i32 1 + %tmp = load float* %addr + %tmp1 = fadd float %tmp, %u + ret float %tmp1 +} + +define float @f2noffset(float* %v, float %u) { +; CHECK: f2noffset: +; CHECK: vldr.32{{.*}}, #-4] + %addr = getelementptr float* %v, i32 -1 + %tmp = load float* %addr + %tmp1 = fadd float %tmp, %u + ret float %tmp1 +} + define void @f3(float %a, float %b, float* %v) { ; CHECK: f3: ; CHECK: vstr.32{{.*}}[ diff --git a/test/CodeGen/ARM/hidden-vis-2.ll b/test/CodeGen/ARM/hidden-vis-2.ll index 90f5308..8bb2c6e 100644 --- a/test/CodeGen/ARM/hidden-vis-2.ll +++ b/test/CodeGen/ARM/hidden-vis-2.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s +; RUN: llc < %s -relocation-model=dynamic-no-pic -mtriple=arm-apple-darwin | FileCheck %s @x = weak hidden global i32 0 ; <i32*> [#uses=1] diff --git a/test/CodeGen/ARM/hidden-vis-3.ll b/test/CodeGen/ARM/hidden-vis-3.ll index fc8b2fe..3bc3312 100644 --- a/test/CodeGen/ARM/hidden-vis-3.ll +++ b/test/CodeGen/ARM/hidden-vis-3.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin9 | FileCheck %s +; RUN: llc < %s -relocation-model=dynamic-no-pic -mtriple=arm-apple-darwin9 | FileCheck %s @x = external hidden global i32 ; <i32*> [#uses=1] @y = extern_weak hidden global i32 ; <i32*> [#uses=1] diff --git a/test/CodeGen/ARM/iabs.ll b/test/CodeGen/ARM/iabs.ll index c01c041..89e309d 100644 --- a/test/CodeGen/ARM/iabs.ll +++ b/test/CodeGen/ARM/iabs.ll @@ -1,8 +1,8 @@ ; RUN: llc < %s -march=arm -mattr=+v4t | FileCheck %s ;; Integer absolute value, should produce something as good as: ARM: -;; add r3, r0, r0, asr #31 -;; eor r0, r3, r0, asr #31 +;; movs r0, r0 +;; rsbmi r0, r0, #0 ;; bx lr define i32 @test(i32 %a) { @@ -10,7 +10,7 @@ define i32 @test(i32 %a) { %b = icmp sgt i32 %a, -1 %abs = select i1 %b, i32 %a, i32 %tmp1neg ret i32 %abs -; CHECK: add r1, r0, r0, asr #31 -; CHECK: eor r0, r1, r0, asr #31 +; CHECK: movs r0, r0 +; CHECK: rsbmi r0, r0, #0 ; CHECK: bx lr } diff --git a/test/CodeGen/ARM/ifcvt4.ll b/test/CodeGen/ARM/ifcvt4.ll index f28c61b..d247f14 100644 --- a/test/CodeGen/ARM/ifcvt4.ll +++ b/test/CodeGen/ARM/ifcvt4.ll @@ -1,8 +1,10 @@ -; RUN: llc < %s -march=arm -; RUN: llc < %s -march=arm | grep subgt | count 1 -; RUN: llc < %s -march=arm | grep suble | count 1 -; FIXME: Check for # of unconditional branch after adding branch folding post ifcvt. +; RUN: llc < %s -march=arm | FileCheck %s +; Do not if-convert when branches go to the different loops. +; CHECK: t: +; CHECK-NOT: subgt +; CHECK-NOT: suble +; Don't use define i32 @t(i32 %a, i32 %b) { entry: %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1] diff --git a/test/CodeGen/ARM/indirectbr.ll b/test/CodeGen/ARM/indirectbr.ll index 25a0f93..341c33f 100644 --- a/test/CodeGen/ARM/indirectbr.ll +++ b/test/CodeGen/ARM/indirectbr.ll @@ -22,7 +22,6 @@ bb2: ; preds = %entry, %bb3 %gotovar.4.0 = phi i8* [ %gotovar.4.0.pre, %bb3 ], [ %0, %entry ] ; <i8*> [#uses=1] ; ARM: bx ; THUMB: mov pc, -; THUMB2: mov pc, indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1] bb3: ; preds = %entry diff --git a/test/CodeGen/ARM/inlineasm3.ll b/test/CodeGen/ARM/inlineasm3.ll index 853585d..cb5243c 100644 --- a/test/CodeGen/ARM/inlineasm3.ll +++ b/test/CodeGen/ARM/inlineasm3.ll @@ -98,3 +98,15 @@ entry: %0 = tail call i32 asm "movw $0, $1", "=r,j"(i32 27182) nounwind ret i32 %0 } + +; Radar 9866494 + +define void @t10(i8* %f, i32 %g) nounwind { +entry: +; CHECK: t10 +; CHECK: str r1, [r0] + %f.addr = alloca i8*, align 4 + store i8* %f, i8** %f.addr, align 4 + call void asm "str $1, $0", "=*Q,r"(i8** %f.addr, i32 %g) nounwind + ret void +} diff --git a/test/CodeGen/ARM/inlineasm4.ll b/test/CodeGen/ARM/inlineasm4.ll new file mode 100644 index 0000000..9ed4b99 --- /dev/null +++ b/test/CodeGen/ARM/inlineasm4.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -march=arm | FileCheck %s + +define double @f(double %x) { +entry: + %0 = tail call double asm "mov ${0:R}, #4\0A", "=&r"() + ret double %0 +; CHECK: f: +; CHECK: mov r1, #4 +} + +define double @g(double %x) { +entry: + %0 = tail call double asm "mov ${0:Q}, #4\0A", "=&r"() + ret double %0 +; CHECK: g: +; CHECK: mov r0, #4 +} diff --git a/test/CodeGen/ARM/lsr-on-unrolled-loops.ll b/test/CodeGen/ARM/lsr-on-unrolled-loops.ll index c1318ec..4737901 100644 --- a/test/CodeGen/ARM/lsr-on-unrolled-loops.ll +++ b/test/CodeGen/ARM/lsr-on-unrolled-loops.ll @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=thumbv7-apple-darwin10 -mcpu=cortex-a8 < %s | FileCheck %s +; RUN: llc -mtriple=thumbv7-apple-darwin10 -mcpu=cortex-a8 -enable-lsr-nested < %s | FileCheck %s ; LSR should recognize that this is an unrolled loop which can use ; constant offset addressing, so that each of the following stores @@ -8,6 +8,9 @@ ; CHECK: vstr.32 s{{.*}}, [{{(r[0-9]+)|(lr)}}, #64] ; CHECK: vstr.32 s{{.*}}, [{{(r[0-9]+)|(lr)}}, #96] +; We can also save a register in the outer loop, but that requires +; performing LSR on the outer loop. + target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32" %0 = type { %1*, %3*, %6*, i8*, i32, i32, %8*, i32, i32, i32, i32, i32, i32, i32, double, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8**, i32, i32, i32, i32, i32, [64 x i32]*, [4 x %9*], [4 x %10*], [4 x %10*], i32, %11*, i32, i32, [16 x i8], [16 x i8], [16 x i8], i32, i32, i8, i8, i8, i16, i16, i32, i8, i32, %12*, i32, i32, i32, i32, i8*, i32, [4 x %11*], i32, i32, i32, [10 x i32], i32, i32, i32, i32, i32, %13*, %14*, %15*, %16*, %17*, %18*, %19*, %20*, %21*, %22*, %23* } @@ -37,107 +40,107 @@ target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32- define void @test(%0* nocapture %a0, %11* nocapture %a1, i16* nocapture %a2, i8** nocapture %a3, i32 %a4) nounwind { bb: - %t = alloca [64 x float], align 4 + %t = alloca [64 x float], align 4 %t5 = getelementptr inbounds %0* %a0, i32 0, i32 65 - %t6 = load i8** %t5, align 4 + %t6 = load i8** %t5, align 4 %t7 = getelementptr inbounds %11* %a1, i32 0, i32 20 - %t8 = load i8** %t7, align 4 + %t8 = load i8** %t7, align 4 br label %bb9 -bb9: +bb9: %t10 = phi i32 [ 0, %bb ], [ %t157, %bb156 ] - %t11 = add i32 %t10, 8 + %t11 = add i32 %t10, 8 %t12 = getelementptr [64 x float]* %t, i32 0, i32 %t11 - %t13 = add i32 %t10, 16 + %t13 = add i32 %t10, 16 %t14 = getelementptr [64 x float]* %t, i32 0, i32 %t13 - %t15 = add i32 %t10, 24 + %t15 = add i32 %t10, 24 %t16 = getelementptr [64 x float]* %t, i32 0, i32 %t15 - %t17 = add i32 %t10, 32 + %t17 = add i32 %t10, 32 %t18 = getelementptr [64 x float]* %t, i32 0, i32 %t17 - %t19 = add i32 %t10, 40 + %t19 = add i32 %t10, 40 %t20 = getelementptr [64 x float]* %t, i32 0, i32 %t19 - %t21 = add i32 %t10, 48 + %t21 = add i32 %t10, 48 %t22 = getelementptr [64 x float]* %t, i32 0, i32 %t21 - %t23 = add i32 %t10, 56 + %t23 = add i32 %t10, 56 %t24 = getelementptr [64 x float]* %t, i32 0, i32 %t23 %t25 = getelementptr [64 x float]* %t, i32 0, i32 %t10 - %t26 = shl i32 %t10, 5 - %t27 = or i32 %t26, 8 - %t28 = getelementptr i8* %t8, i32 %t27 - %t29 = bitcast i8* %t28 to float* - %t30 = or i32 %t26, 16 - %t31 = getelementptr i8* %t8, i32 %t30 - %t32 = bitcast i8* %t31 to float* - %t33 = or i32 %t26, 24 - %t34 = getelementptr i8* %t8, i32 %t33 - %t35 = bitcast i8* %t34 to float* - %t36 = or i32 %t26, 4 - %t37 = getelementptr i8* %t8, i32 %t36 - %t38 = bitcast i8* %t37 to float* - %t39 = or i32 %t26, 12 - %t40 = getelementptr i8* %t8, i32 %t39 - %t41 = bitcast i8* %t40 to float* - %t42 = or i32 %t26, 20 - %t43 = getelementptr i8* %t8, i32 %t42 - %t44 = bitcast i8* %t43 to float* - %t45 = or i32 %t26, 28 - %t46 = getelementptr i8* %t8, i32 %t45 - %t47 = bitcast i8* %t46 to float* - %t48 = getelementptr i8* %t8, i32 %t26 - %t49 = bitcast i8* %t48 to float* - %t50 = shl i32 %t10, 3 - %t51 = or i32 %t50, 1 - %t52 = getelementptr i16* %a2, i32 %t51 - %t53 = or i32 %t50, 2 - %t54 = getelementptr i16* %a2, i32 %t53 - %t55 = or i32 %t50, 3 - %t56 = getelementptr i16* %a2, i32 %t55 - %t57 = or i32 %t50, 4 - %t58 = getelementptr i16* %a2, i32 %t57 - %t59 = or i32 %t50, 5 - %t60 = getelementptr i16* %a2, i32 %t59 - %t61 = or i32 %t50, 6 - %t62 = getelementptr i16* %a2, i32 %t61 - %t63 = or i32 %t50, 7 - %t64 = getelementptr i16* %a2, i32 %t63 - %t65 = getelementptr i16* %a2, i32 %t50 - %t66 = load i16* %t52, align 2 - %t67 = icmp eq i16 %t66, 0 - %t68 = load i16* %t54, align 2 - %t69 = icmp eq i16 %t68, 0 - %t70 = and i1 %t67, %t69 + %t26 = shl i32 %t10, 5 + %t27 = or i32 %t26, 8 + %t28 = getelementptr i8* %t8, i32 %t27 + %t29 = bitcast i8* %t28 to float* + %t30 = or i32 %t26, 16 + %t31 = getelementptr i8* %t8, i32 %t30 + %t32 = bitcast i8* %t31 to float* + %t33 = or i32 %t26, 24 + %t34 = getelementptr i8* %t8, i32 %t33 + %t35 = bitcast i8* %t34 to float* + %t36 = or i32 %t26, 4 + %t37 = getelementptr i8* %t8, i32 %t36 + %t38 = bitcast i8* %t37 to float* + %t39 = or i32 %t26, 12 + %t40 = getelementptr i8* %t8, i32 %t39 + %t41 = bitcast i8* %t40 to float* + %t42 = or i32 %t26, 20 + %t43 = getelementptr i8* %t8, i32 %t42 + %t44 = bitcast i8* %t43 to float* + %t45 = or i32 %t26, 28 + %t46 = getelementptr i8* %t8, i32 %t45 + %t47 = bitcast i8* %t46 to float* + %t48 = getelementptr i8* %t8, i32 %t26 + %t49 = bitcast i8* %t48 to float* + %t50 = shl i32 %t10, 3 + %t51 = or i32 %t50, 1 + %t52 = getelementptr i16* %a2, i32 %t51 + %t53 = or i32 %t50, 2 + %t54 = getelementptr i16* %a2, i32 %t53 + %t55 = or i32 %t50, 3 + %t56 = getelementptr i16* %a2, i32 %t55 + %t57 = or i32 %t50, 4 + %t58 = getelementptr i16* %a2, i32 %t57 + %t59 = or i32 %t50, 5 + %t60 = getelementptr i16* %a2, i32 %t59 + %t61 = or i32 %t50, 6 + %t62 = getelementptr i16* %a2, i32 %t61 + %t63 = or i32 %t50, 7 + %t64 = getelementptr i16* %a2, i32 %t63 + %t65 = getelementptr i16* %a2, i32 %t50 + %t66 = load i16* %t52, align 2 + %t67 = icmp eq i16 %t66, 0 + %t68 = load i16* %t54, align 2 + %t69 = icmp eq i16 %t68, 0 + %t70 = and i1 %t67, %t69 br i1 %t70, label %bb71, label %bb91 -bb71: - %t72 = load i16* %t56, align 2 - %t73 = icmp eq i16 %t72, 0 +bb71: + %t72 = load i16* %t56, align 2 + %t73 = icmp eq i16 %t72, 0 br i1 %t73, label %bb74, label %bb91 -bb74: - %t75 = load i16* %t58, align 2 - %t76 = icmp eq i16 %t75, 0 +bb74: + %t75 = load i16* %t58, align 2 + %t76 = icmp eq i16 %t75, 0 br i1 %t76, label %bb77, label %bb91 -bb77: - %t78 = load i16* %t60, align 2 - %t79 = icmp eq i16 %t78, 0 +bb77: + %t78 = load i16* %t60, align 2 + %t79 = icmp eq i16 %t78, 0 br i1 %t79, label %bb80, label %bb91 -bb80: - %t81 = load i16* %t62, align 2 - %t82 = icmp eq i16 %t81, 0 +bb80: + %t81 = load i16* %t62, align 2 + %t82 = icmp eq i16 %t81, 0 br i1 %t82, label %bb83, label %bb91 -bb83: - %t84 = load i16* %t64, align 2 - %t85 = icmp eq i16 %t84, 0 +bb83: + %t84 = load i16* %t64, align 2 + %t85 = icmp eq i16 %t84, 0 br i1 %t85, label %bb86, label %bb91 -bb86: - %t87 = load i16* %t65, align 2 - %t88 = sitofp i16 %t87 to float - %t89 = load float* %t49, align 4 - %t90 = fmul float %t88, %t89 +bb86: + %t87 = load i16* %t65, align 2 + %t88 = sitofp i16 %t87 to float + %t89 = load float* %t49, align 4 + %t90 = fmul float %t88, %t89 store float %t90, float* %t25, align 4 store float %t90, float* %t12, align 4 store float %t90, float* %t14, align 4 @@ -148,235 +151,235 @@ bb86: store float %t90, float* %t24, align 4 br label %bb156 -bb91: - %t92 = load i16* %t65, align 2 - %t93 = sitofp i16 %t92 to float - %t94 = load float* %t49, align 4 - %t95 = fmul float %t93, %t94 - %t96 = sitofp i16 %t68 to float - %t97 = load float* %t29, align 4 - %t98 = fmul float %t96, %t97 - %t99 = load i16* %t58, align 2 - %t100 = sitofp i16 %t99 to float - %t101 = load float* %t32, align 4 - %t102 = fmul float %t100, %t101 - %t103 = load i16* %t62, align 2 - %t104 = sitofp i16 %t103 to float - %t105 = load float* %t35, align 4 - %t106 = fmul float %t104, %t105 - %t107 = fadd float %t95, %t102 - %t108 = fsub float %t95, %t102 - %t109 = fadd float %t98, %t106 - %t110 = fsub float %t98, %t106 +bb91: + %t92 = load i16* %t65, align 2 + %t93 = sitofp i16 %t92 to float + %t94 = load float* %t49, align 4 + %t95 = fmul float %t93, %t94 + %t96 = sitofp i16 %t68 to float + %t97 = load float* %t29, align 4 + %t98 = fmul float %t96, %t97 + %t99 = load i16* %t58, align 2 + %t100 = sitofp i16 %t99 to float + %t101 = load float* %t32, align 4 + %t102 = fmul float %t100, %t101 + %t103 = load i16* %t62, align 2 + %t104 = sitofp i16 %t103 to float + %t105 = load float* %t35, align 4 + %t106 = fmul float %t104, %t105 + %t107 = fadd float %t95, %t102 + %t108 = fsub float %t95, %t102 + %t109 = fadd float %t98, %t106 + %t110 = fsub float %t98, %t106 %t111 = fmul float %t110, 0x3FF6A09E60000000 - %t112 = fsub float %t111, %t109 - %t113 = fadd float %t107, %t109 - %t114 = fsub float %t107, %t109 - %t115 = fadd float %t108, %t112 - %t116 = fsub float %t108, %t112 - %t117 = sitofp i16 %t66 to float - %t118 = load float* %t38, align 4 - %t119 = fmul float %t117, %t118 - %t120 = load i16* %t56, align 2 - %t121 = sitofp i16 %t120 to float - %t122 = load float* %t41, align 4 - %t123 = fmul float %t121, %t122 - %t124 = load i16* %t60, align 2 - %t125 = sitofp i16 %t124 to float - %t126 = load float* %t44, align 4 - %t127 = fmul float %t125, %t126 - %t128 = load i16* %t64, align 2 - %t129 = sitofp i16 %t128 to float - %t130 = load float* %t47, align 4 - %t131 = fmul float %t129, %t130 - %t132 = fadd float %t127, %t123 - %t133 = fsub float %t127, %t123 - %t134 = fadd float %t119, %t131 - %t135 = fsub float %t119, %t131 - %t136 = fadd float %t134, %t132 - %t137 = fsub float %t134, %t132 + %t112 = fsub float %t111, %t109 + %t113 = fadd float %t107, %t109 + %t114 = fsub float %t107, %t109 + %t115 = fadd float %t108, %t112 + %t116 = fsub float %t108, %t112 + %t117 = sitofp i16 %t66 to float + %t118 = load float* %t38, align 4 + %t119 = fmul float %t117, %t118 + %t120 = load i16* %t56, align 2 + %t121 = sitofp i16 %t120 to float + %t122 = load float* %t41, align 4 + %t123 = fmul float %t121, %t122 + %t124 = load i16* %t60, align 2 + %t125 = sitofp i16 %t124 to float + %t126 = load float* %t44, align 4 + %t127 = fmul float %t125, %t126 + %t128 = load i16* %t64, align 2 + %t129 = sitofp i16 %t128 to float + %t130 = load float* %t47, align 4 + %t131 = fmul float %t129, %t130 + %t132 = fadd float %t127, %t123 + %t133 = fsub float %t127, %t123 + %t134 = fadd float %t119, %t131 + %t135 = fsub float %t119, %t131 + %t136 = fadd float %t134, %t132 + %t137 = fsub float %t134, %t132 %t138 = fmul float %t137, 0x3FF6A09E60000000 - %t139 = fadd float %t133, %t135 + %t139 = fadd float %t133, %t135 %t140 = fmul float %t139, 0x3FFD906BC0000000 %t141 = fmul float %t135, 0x3FF1517A80000000 - %t142 = fsub float %t141, %t140 + %t142 = fsub float %t141, %t140 %t143 = fmul float %t133, 0xC004E7AEA0000000 - %t144 = fadd float %t143, %t140 - %t145 = fsub float %t144, %t136 - %t146 = fsub float %t138, %t145 - %t147 = fadd float %t142, %t146 - %t148 = fadd float %t113, %t136 + %t144 = fadd float %t143, %t140 + %t145 = fsub float %t144, %t136 + %t146 = fsub float %t138, %t145 + %t147 = fadd float %t142, %t146 + %t148 = fadd float %t113, %t136 store float %t148, float* %t25, align 4 - %t149 = fsub float %t113, %t136 + %t149 = fsub float %t113, %t136 store float %t149, float* %t24, align 4 - %t150 = fadd float %t115, %t145 + %t150 = fadd float %t115, %t145 store float %t150, float* %t12, align 4 - %t151 = fsub float %t115, %t145 + %t151 = fsub float %t115, %t145 store float %t151, float* %t22, align 4 - %t152 = fadd float %t116, %t146 + %t152 = fadd float %t116, %t146 store float %t152, float* %t14, align 4 - %t153 = fsub float %t116, %t146 + %t153 = fsub float %t116, %t146 store float %t153, float* %t20, align 4 - %t154 = fadd float %t114, %t147 + %t154 = fadd float %t114, %t147 store float %t154, float* %t18, align 4 - %t155 = fsub float %t114, %t147 + %t155 = fsub float %t114, %t147 store float %t155, float* %t16, align 4 br label %bb156 -bb156: - %t157 = add i32 %t10, 1 - %t158 = icmp eq i32 %t157, 8 +bb156: + %t157 = add i32 %t10, 1 + %t158 = icmp eq i32 %t157, 8 br i1 %t158, label %bb159, label %bb9 -bb159: - %t160 = add i32 %a4, 7 - %t161 = add i32 %a4, 1 - %t162 = add i32 %a4, 6 - %t163 = add i32 %a4, 2 - %t164 = add i32 %a4, 5 - %t165 = add i32 %a4, 4 - %t166 = add i32 %a4, 3 +bb159: + %t160 = add i32 %a4, 7 + %t161 = add i32 %a4, 1 + %t162 = add i32 %a4, 6 + %t163 = add i32 %a4, 2 + %t164 = add i32 %a4, 5 + %t165 = add i32 %a4, 4 + %t166 = add i32 %a4, 3 br label %bb167 -bb167: +bb167: %t168 = phi i32 [ 0, %bb159 ], [ %t293, %bb167 ] %t169 = getelementptr i8** %a3, i32 %t168 - %t170 = shl i32 %t168, 3 - %t171 = or i32 %t170, 4 + %t170 = shl i32 %t168, 3 + %t171 = or i32 %t170, 4 %t172 = getelementptr [64 x float]* %t, i32 0, i32 %t171 - %t173 = or i32 %t170, 2 + %t173 = or i32 %t170, 2 %t174 = getelementptr [64 x float]* %t, i32 0, i32 %t173 - %t175 = or i32 %t170, 6 + %t175 = or i32 %t170, 6 %t176 = getelementptr [64 x float]* %t, i32 0, i32 %t175 - %t177 = or i32 %t170, 5 + %t177 = or i32 %t170, 5 %t178 = getelementptr [64 x float]* %t, i32 0, i32 %t177 - %t179 = or i32 %t170, 3 + %t179 = or i32 %t170, 3 %t180 = getelementptr [64 x float]* %t, i32 0, i32 %t179 - %t181 = or i32 %t170, 1 + %t181 = or i32 %t170, 1 %t182 = getelementptr [64 x float]* %t, i32 0, i32 %t181 - %t183 = or i32 %t170, 7 + %t183 = or i32 %t170, 7 %t184 = getelementptr [64 x float]* %t, i32 0, i32 %t183 %t185 = getelementptr [64 x float]* %t, i32 0, i32 %t170 - %t186 = load i8** %t169, align 4 + %t186 = load i8** %t169, align 4 %t187 = getelementptr inbounds i8* %t186, i32 %a4 - %t188 = load float* %t185, align 4 - %t189 = load float* %t172, align 4 - %t190 = fadd float %t188, %t189 - %t191 = fsub float %t188, %t189 - %t192 = load float* %t174, align 4 - %t193 = load float* %t176, align 4 - %t194 = fadd float %t192, %t193 - %t195 = fsub float %t192, %t193 + %t188 = load float* %t185, align 4 + %t189 = load float* %t172, align 4 + %t190 = fadd float %t188, %t189 + %t191 = fsub float %t188, %t189 + %t192 = load float* %t174, align 4 + %t193 = load float* %t176, align 4 + %t194 = fadd float %t192, %t193 + %t195 = fsub float %t192, %t193 %t196 = fmul float %t195, 0x3FF6A09E60000000 - %t197 = fsub float %t196, %t194 - %t198 = fadd float %t190, %t194 - %t199 = fsub float %t190, %t194 - %t200 = fadd float %t191, %t197 - %t201 = fsub float %t191, %t197 - %t202 = load float* %t178, align 4 - %t203 = load float* %t180, align 4 - %t204 = fadd float %t202, %t203 - %t205 = fsub float %t202, %t203 - %t206 = load float* %t182, align 4 - %t207 = load float* %t184, align 4 - %t208 = fadd float %t206, %t207 - %t209 = fsub float %t206, %t207 - %t210 = fadd float %t208, %t204 - %t211 = fsub float %t208, %t204 + %t197 = fsub float %t196, %t194 + %t198 = fadd float %t190, %t194 + %t199 = fsub float %t190, %t194 + %t200 = fadd float %t191, %t197 + %t201 = fsub float %t191, %t197 + %t202 = load float* %t178, align 4 + %t203 = load float* %t180, align 4 + %t204 = fadd float %t202, %t203 + %t205 = fsub float %t202, %t203 + %t206 = load float* %t182, align 4 + %t207 = load float* %t184, align 4 + %t208 = fadd float %t206, %t207 + %t209 = fsub float %t206, %t207 + %t210 = fadd float %t208, %t204 + %t211 = fsub float %t208, %t204 %t212 = fmul float %t211, 0x3FF6A09E60000000 - %t213 = fadd float %t205, %t209 + %t213 = fadd float %t205, %t209 %t214 = fmul float %t213, 0x3FFD906BC0000000 %t215 = fmul float %t209, 0x3FF1517A80000000 - %t216 = fsub float %t215, %t214 + %t216 = fsub float %t215, %t214 %t217 = fmul float %t205, 0xC004E7AEA0000000 - %t218 = fadd float %t217, %t214 - %t219 = fsub float %t218, %t210 - %t220 = fsub float %t212, %t219 - %t221 = fadd float %t216, %t220 - %t222 = fadd float %t198, %t210 - %t223 = fptosi float %t222 to i32 - %t224 = add nsw i32 %t223, 4 - %t225 = lshr i32 %t224, 3 - %t226 = and i32 %t225, 1023 - %t227 = add i32 %t226, 128 + %t218 = fadd float %t217, %t214 + %t219 = fsub float %t218, %t210 + %t220 = fsub float %t212, %t219 + %t221 = fadd float %t216, %t220 + %t222 = fadd float %t198, %t210 + %t223 = fptosi float %t222 to i32 + %t224 = add nsw i32 %t223, 4 + %t225 = lshr i32 %t224, 3 + %t226 = and i32 %t225, 1023 + %t227 = add i32 %t226, 128 %t228 = getelementptr inbounds i8* %t6, i32 %t227 - %t229 = load i8* %t228, align 1 + %t229 = load i8* %t228, align 1 store i8 %t229, i8* %t187, align 1 - %t230 = fsub float %t198, %t210 - %t231 = fptosi float %t230 to i32 - %t232 = add nsw i32 %t231, 4 - %t233 = lshr i32 %t232, 3 - %t234 = and i32 %t233, 1023 - %t235 = add i32 %t234, 128 + %t230 = fsub float %t198, %t210 + %t231 = fptosi float %t230 to i32 + %t232 = add nsw i32 %t231, 4 + %t233 = lshr i32 %t232, 3 + %t234 = and i32 %t233, 1023 + %t235 = add i32 %t234, 128 %t236 = getelementptr inbounds i8* %t6, i32 %t235 - %t237 = load i8* %t236, align 1 + %t237 = load i8* %t236, align 1 %t238 = getelementptr inbounds i8* %t186, i32 %t160 store i8 %t237, i8* %t238, align 1 - %t239 = fadd float %t200, %t219 - %t240 = fptosi float %t239 to i32 - %t241 = add nsw i32 %t240, 4 - %t242 = lshr i32 %t241, 3 - %t243 = and i32 %t242, 1023 - %t244 = add i32 %t243, 128 + %t239 = fadd float %t200, %t219 + %t240 = fptosi float %t239 to i32 + %t241 = add nsw i32 %t240, 4 + %t242 = lshr i32 %t241, 3 + %t243 = and i32 %t242, 1023 + %t244 = add i32 %t243, 128 %t245 = getelementptr inbounds i8* %t6, i32 %t244 - %t246 = load i8* %t245, align 1 + %t246 = load i8* %t245, align 1 %t247 = getelementptr inbounds i8* %t186, i32 %t161 store i8 %t246, i8* %t247, align 1 - %t248 = fsub float %t200, %t219 - %t249 = fptosi float %t248 to i32 - %t250 = add nsw i32 %t249, 4 - %t251 = lshr i32 %t250, 3 - %t252 = and i32 %t251, 1023 - %t253 = add i32 %t252, 128 + %t248 = fsub float %t200, %t219 + %t249 = fptosi float %t248 to i32 + %t250 = add nsw i32 %t249, 4 + %t251 = lshr i32 %t250, 3 + %t252 = and i32 %t251, 1023 + %t253 = add i32 %t252, 128 %t254 = getelementptr inbounds i8* %t6, i32 %t253 - %t255 = load i8* %t254, align 1 + %t255 = load i8* %t254, align 1 %t256 = getelementptr inbounds i8* %t186, i32 %t162 store i8 %t255, i8* %t256, align 1 - %t257 = fadd float %t201, %t220 - %t258 = fptosi float %t257 to i32 - %t259 = add nsw i32 %t258, 4 - %t260 = lshr i32 %t259, 3 - %t261 = and i32 %t260, 1023 - %t262 = add i32 %t261, 128 + %t257 = fadd float %t201, %t220 + %t258 = fptosi float %t257 to i32 + %t259 = add nsw i32 %t258, 4 + %t260 = lshr i32 %t259, 3 + %t261 = and i32 %t260, 1023 + %t262 = add i32 %t261, 128 %t263 = getelementptr inbounds i8* %t6, i32 %t262 - %t264 = load i8* %t263, align 1 + %t264 = load i8* %t263, align 1 %t265 = getelementptr inbounds i8* %t186, i32 %t163 store i8 %t264, i8* %t265, align 1 - %t266 = fsub float %t201, %t220 - %t267 = fptosi float %t266 to i32 - %t268 = add nsw i32 %t267, 4 - %t269 = lshr i32 %t268, 3 - %t270 = and i32 %t269, 1023 - %t271 = add i32 %t270, 128 + %t266 = fsub float %t201, %t220 + %t267 = fptosi float %t266 to i32 + %t268 = add nsw i32 %t267, 4 + %t269 = lshr i32 %t268, 3 + %t270 = and i32 %t269, 1023 + %t271 = add i32 %t270, 128 %t272 = getelementptr inbounds i8* %t6, i32 %t271 - %t273 = load i8* %t272, align 1 + %t273 = load i8* %t272, align 1 %t274 = getelementptr inbounds i8* %t186, i32 %t164 store i8 %t273, i8* %t274, align 1 - %t275 = fadd float %t199, %t221 - %t276 = fptosi float %t275 to i32 - %t277 = add nsw i32 %t276, 4 - %t278 = lshr i32 %t277, 3 - %t279 = and i32 %t278, 1023 - %t280 = add i32 %t279, 128 + %t275 = fadd float %t199, %t221 + %t276 = fptosi float %t275 to i32 + %t277 = add nsw i32 %t276, 4 + %t278 = lshr i32 %t277, 3 + %t279 = and i32 %t278, 1023 + %t280 = add i32 %t279, 128 %t281 = getelementptr inbounds i8* %t6, i32 %t280 - %t282 = load i8* %t281, align 1 + %t282 = load i8* %t281, align 1 %t283 = getelementptr inbounds i8* %t186, i32 %t165 store i8 %t282, i8* %t283, align 1 - %t284 = fsub float %t199, %t221 - %t285 = fptosi float %t284 to i32 - %t286 = add nsw i32 %t285, 4 - %t287 = lshr i32 %t286, 3 - %t288 = and i32 %t287, 1023 - %t289 = add i32 %t288, 128 + %t284 = fsub float %t199, %t221 + %t285 = fptosi float %t284 to i32 + %t286 = add nsw i32 %t285, 4 + %t287 = lshr i32 %t286, 3 + %t288 = and i32 %t287, 1023 + %t289 = add i32 %t288, 128 %t290 = getelementptr inbounds i8* %t6, i32 %t289 - %t291 = load i8* %t290, align 1 + %t291 = load i8* %t290, align 1 %t292 = getelementptr inbounds i8* %t186, i32 %t166 store i8 %t291, i8* %t292, align 1 - %t293 = add nsw i32 %t168, 1 - %t294 = icmp eq i32 %t293, 8 + %t293 = add nsw i32 %t168, 1 + %t294 = icmp eq i32 %t293, 8 br i1 %t294, label %bb295, label %bb167 -bb295: +bb295: ret void } diff --git a/test/CodeGen/ARM/lsr-unfolded-offset.ll b/test/CodeGen/ARM/lsr-unfolded-offset.ll index 61b25bb..bf26a96 100644 --- a/test/CodeGen/ARM/lsr-unfolded-offset.ll +++ b/test/CodeGen/ARM/lsr-unfolded-offset.ll @@ -4,12 +4,11 @@ ; register pressure and therefore spilling. There is more room for improvement ; here. -; CHECK: sub sp, #{{32|28|24}} +; CHECK: sub sp, #{{40|32|28|24}} ; CHECK: %for.inc ; CHECK: ldr{{(.w)?}} r{{.*}}, [sp, # ; CHECK: ldr{{(.w)?}} r{{.*}}, [sp, # -; CHECK: ldr{{(.w)?}} r{{.*}}, [sp, # ; CHECK: add target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32" diff --git a/test/CodeGen/ARM/mulhi.ll b/test/CodeGen/ARM/mulhi.ll index 148f291..932004c 100644 --- a/test/CodeGen/ARM/mulhi.ll +++ b/test/CodeGen/ARM/mulhi.ll @@ -1,9 +1,16 @@ -; RUN: llc < %s -march=arm -mattr=+v6 -; RUN: llc < %s -march=arm -mattr=+v6 | \ -; RUN: grep smmul | count 1 -; RUN: llc < %s -march=arm | grep umull | count 1 +; RUN: llc < %s -march=arm -mattr=+v6 | FileCheck %s -check-prefix=V6 +; RUN: llc < %s -march=arm | FileCheck %s -check-prefix=V4 +; RUN: llc < %s -march=thumb -mcpu=cortex-m3 | FileCheck %s -check-prefix=M3 -define i32 @smulhi(i32 %x, i32 %y) { +define i32 @smulhi(i32 %x, i32 %y) nounwind { +; V6: smulhi: +; V6: smmul + +; V4: smulhi: +; V4: smull + +; M3: smulhi: +; M3: smull %tmp = sext i32 %x to i64 ; <i64> [#uses=1] %tmp1 = sext i32 %y to i64 ; <i64> [#uses=1] %tmp2 = mul i64 %tmp1, %tmp ; <i64> [#uses=1] @@ -12,7 +19,15 @@ define i32 @smulhi(i32 %x, i32 %y) { ret i32 %tmp3.upgrd.1 } -define i32 @umulhi(i32 %x, i32 %y) { +define i32 @umulhi(i32 %x, i32 %y) nounwind { +; V6: umulhi: +; V6: umull + +; V4: umulhi: +; V4: umull + +; M3: umulhi: +; M3: umull %tmp = zext i32 %x to i64 ; <i64> [#uses=1] %tmp1 = zext i32 %y to i64 ; <i64> [#uses=1] %tmp2 = mul i64 %tmp1, %tmp ; <i64> [#uses=1] @@ -20,3 +35,20 @@ define i32 @umulhi(i32 %x, i32 %y) { %tmp3.upgrd.2 = trunc i64 %tmp3 to i32 ; <i32> [#uses=1] ret i32 %tmp3.upgrd.2 } + +; rdar://r10152911 +define i32 @t3(i32 %a) nounwind { +; V6: t3: +; V6: smmla + +; V4: t3: +; V4: smull + +; M3: t3: +; M3-NOT: smmla +; M3: smull +entry: + %tmp1 = mul nsw i32 %a, 3 + %tmp2 = sdiv i32 %tmp1, 23 + ret i32 %tmp2 +} diff --git a/test/CodeGen/ARM/select.ll b/test/CodeGen/ARM/select.ll index d1493ee..f1bd7ee 100644 --- a/test/CodeGen/ARM/select.ll +++ b/test/CodeGen/ARM/select.ll @@ -76,12 +76,12 @@ define double @f7(double %a, double %b) { ; block generated, odds are good that we have close to the ideal code for this: ; ; CHECK-NEON: _f8: -; CHECK-NEON: movw [[REGISTER_1:r[0-9]+]], #1123 -; CHECK-NEON-NEXT: movs [[REGISTER_2:r[0-9]+]], #0 -; CHECK-NEON-NEXT: cmp r0, [[REGISTER_1]] -; CHECK-NEON-NEXT: it eq -; CHECK-NEON-NEXT: moveq [[REGISTER_2]], #4 -; CHECK-NEON-NEXT: adr [[REGISTER_3:r[0-9]+]], #LCPI +; CHECK-NEON: adr r2, LCPI7_0 +; CHECK-NEON-NEXT: movw r3, #1123 +; CHECK-NEON-NEXT: adds r1, r2, #4 +; CHECK-NEON-NEXT: cmp r0, r3 +; CHECK-NEON-NEXT: it ne +; CHECK-NEON-NEXT: movne r1, r2 ; CHECK-NEON-NEXT: ldr ; CHECK-NEON: bx diff --git a/test/CodeGen/ARM/shifter_operand.ll b/test/CodeGen/ARM/shifter_operand.ll index f0e2d10..964cef0 100644 --- a/test/CodeGen/ARM/shifter_operand.ll +++ b/test/CodeGen/ARM/shifter_operand.ll @@ -54,13 +54,12 @@ declare i8* @malloc(...) define fastcc void @test4(i16 %addr) nounwind { entry: ; A8: test4: -; A8: ldr r2, [r0, r1, lsl #2] -; A8: str r2, [r0, r1, lsl #2] +; A8: ldr [[REG:r[0-9]+]], [r0, r1, lsl #2] +; A8: str [[REG]], [r0, r1, lsl #2] ; A9: test4: -; A9: add r0, r0, r{{[0-9]+}}, lsl #2 -; A9: ldr r1, [r0] -; A9: str r1, [r0] +; A9: ldr [[REG:r[0-9]+]], [r0, r1, lsl #2] +; A9: str [[REG]], [r0, r1, lsl #2] %0 = tail call i8* (...)* @malloc(i32 undef) nounwind %1 = bitcast i8* %0 to i32* %2 = sext i16 %addr to i32 diff --git a/test/CodeGen/ARM/str_pre-2.ll b/test/CodeGen/ARM/str_pre-2.ll index b24f75a..f4e3a44 100644 --- a/test/CodeGen/ARM/str_pre-2.ll +++ b/test/CodeGen/ARM/str_pre-2.ll @@ -7,8 +7,8 @@ define i64 @t(i64 %a) nounwind readonly { entry: -; CHECK: str lr, [sp, #-4]! -; CHECK: ldr lr, [sp], #4 +; CHECK: push {lr} +; CHECK: pop {lr} %0 = load i64** @b, align 4 %1 = load i64* %0, align 4 %2 = mul i64 %1, %a diff --git a/test/CodeGen/ARM/subreg-remat.ll b/test/CodeGen/ARM/subreg-remat.ll new file mode 100644 index 0000000..993d7ec --- /dev/null +++ b/test/CodeGen/ARM/subreg-remat.ll @@ -0,0 +1,52 @@ +; RUN: llc < %s -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 -pre-RA-sched=source | FileCheck %s +target triple = "thumbv7-apple-ios" +; <rdar://problem/10032939> +; +; The vector %v2 is built like this: +; +; %vreg6:ssub_1<def> = VMOVSR %vreg0<kill>, pred:14, pred:%noreg, %vreg6<imp-def>; DPR_VFP2:%vreg6 GPR:%vreg0 +; %vreg6:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg; mem:LD4[ConstantPool] DPR_VFP2:%vreg6 +; +; When %vreg6 spills, the VLDRS constant pool load cannot be rematerialized +; since it implicitly reads the ssub_1 sub-register. +; +; CHECK: f1 +; CHECK: vmov s1, r0 +; CHECK: vldr.32 s0, LCPI +; The vector must be spilled: +; CHECK: vstr.64 d0, +; CHECK: asm clobber d0 +; And reloaded after the asm: +; CHECK: vldr.64 [[D16:d[0-9]+]], +; CHECK: vstr.64 [[D16]], [r1] +define void @f1(float %x, <2 x float>* %p) { + %v1 = insertelement <2 x float> undef, float %x, i32 1 + %v2 = insertelement <2 x float> %v1, float 0x400921FB60000000, i32 0 + %y = call double asm sideeffect "asm clobber $0", "=w,0,~{d1},~{d2},~{d3},~{d4},~{d5},~{d6},~{d7},~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15},~{d16},~{d17},~{d18},~{d19},~{d20},~{d21},~{d22},~{d23},~{d24},~{d25},~{d26},~{d27},~{d28},~{d29},~{d30},~{d31}"(<2 x float> %v2) nounwind + store <2 x float> %v2, <2 x float>* %p, align 8 + ret void +} + +; On the other hand, when the partial redef doesn't read the full register +; because the bits are undef, we should rematerialize. The vector is now built +; like this: +; +; %vreg2:ssub_0<def> = VLDRS <cp#0>, 0, pred:14, pred:%noreg, %vreg2<imp-def>; mem:LD4[ConstantPool] +; +; The extra <imp-def> operand indicates that the instruction fully defines the +; virtual register. It doesn't read the old value. +; +; CHECK: f2 +; CHECK: vldr.32 s0, LCPI +; The vector must not be spilled: +; CHECK-NOT: vstr.64 +; CHECK: asm clobber d0 +; But instead rematerialize after the asm: +; CHECK: vldr.32 [[S0:s[0-9]+]], LCPI +; CHECK: vstr.64 [[D0:d[0-9]+]], [r0] +define void @f2(<2 x float>* %p) { + %v2 = insertelement <2 x float> undef, float 0x400921FB60000000, i32 0 + %y = call double asm sideeffect "asm clobber $0", "=w,0,~{d1},~{d2},~{d3},~{d4},~{d5},~{d6},~{d7},~{d8},~{d9},~{d10},~{d11},~{d12},~{d13},~{d14},~{d15},~{d16},~{d17},~{d18},~{d19},~{d20},~{d21},~{d22},~{d23},~{d24},~{d25},~{d26},~{d27},~{d28},~{d29},~{d30},~{d31}"(<2 x float> %v2) nounwind + store <2 x float> %v2, <2 x float>* %p, align 8 + ret void +} diff --git a/test/CodeGen/ARM/sxt_rot.ll b/test/CodeGen/ARM/sxt_rot.ll index 355fee3..656cd93 100644 --- a/test/CodeGen/ARM/sxt_rot.ll +++ b/test/CodeGen/ARM/sxt_rot.ll @@ -1,29 +1,30 @@ -; RUN: llc < %s -march=arm -mattr=+v6 | \ -; RUN: grep sxtb | count 2 -; RUN: llc < %s -march=arm -mattr=+v6 | \ -; RUN: grep sxtb | grep ror | count 1 -; RUN: llc < %s -march=arm -mattr=+v6 | \ -; RUN: grep sxtab | count 1 +; RUN: llc < %s -march=arm -mattr=+v6 | FileCheck %s define i32 @test0(i8 %A) { - %B = sext i8 %A to i32 - ret i32 %B +; CHECK: test0 +; CHECK: sxtb r0, r0 + %B = sext i8 %A to i32 + ret i32 %B } define signext i8 @test1(i32 %A) { - %B = lshr i32 %A, 8 - %C = shl i32 %A, 24 - %D = or i32 %B, %C - %E = trunc i32 %D to i8 - ret i8 %E +; CHECK: test1 +; CHECK: sxtb r0, r0, ror #8 + %B = lshr i32 %A, 8 + %C = shl i32 %A, 24 + %D = or i32 %B, %C + %E = trunc i32 %D to i8 + ret i8 %E } define signext i32 @test2(i32 %A, i32 %X) { - %B = lshr i32 %A, 8 - %C = shl i32 %A, 24 - %D = or i32 %B, %C - %E = trunc i32 %D to i8 - %F = sext i8 %E to i32 - %G = add i32 %F, %X - ret i32 %G +; CHECK: test2 +; CHECK: sxtab r0, r1, r0 + %B = lshr i32 %A, 8 + %C = shl i32 %A, 24 + %D = or i32 %B, %C + %E = trunc i32 %D to i8 + %F = sext i8 %E to i32 + %G = add i32 %F, %X + ret i32 %G } diff --git a/test/CodeGen/ARM/tail-opts.ll b/test/CodeGen/ARM/tail-opts.ll index 5b3dce3..3dc77e2 100644 --- a/test/CodeGen/ARM/tail-opts.ll +++ b/test/CodeGen/ARM/tail-opts.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -mtriple=arm-apple-darwin -mcpu=cortex-a8 -asm-verbose=false | FileCheck %s +; RUN: llc < %s -mtriple=arm-apple-darwin -relocation-model=dynamic-no-pic -mcpu=cortex-a8 -asm-verbose=false | FileCheck %s declare void @bar(i32) declare void @car(i32) diff --git a/test/CodeGen/ARM/thumb2-it-block.ll b/test/CodeGen/ARM/thumb2-it-block.ll new file mode 100644 index 0000000..28fd469 --- /dev/null +++ b/test/CodeGen/ARM/thumb2-it-block.ll @@ -0,0 +1,20 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; PR11107 + +define i32 @test(i32 %a, i32 %b) { +entry: +; CHECK: movs.w +; CHECK-NEXT: it mi +; CHECK-NEXT: rsbmi +; CHECK-NEXT: movs.w +; CHECK-NEXT: it mi +; CHECK-NEXT: rsbmi + %cmp1 = icmp slt i32 %a, 0 + %sub1 = sub nsw i32 0, %a + %abs1 = select i1 %cmp1, i32 %sub1, i32 %a + %cmp2 = icmp slt i32 %b, 0 + %sub2 = sub nsw i32 0, %b + %abs2 = select i1 %cmp2, i32 %sub2, i32 %b + %add = add nsw i32 %abs1, %abs2 + ret i32 %add +} diff --git a/test/CodeGen/ARM/va_arg.ll b/test/CodeGen/ARM/va_arg.ll index bb40453..af477b4 100644 --- a/test/CodeGen/ARM/va_arg.ll +++ b/test/CodeGen/ARM/va_arg.ll @@ -30,6 +30,7 @@ entry: %ap1 = bitcast i8** %ap to i8* ; <i8*> [#uses=2] call void @llvm.va_start(i8* %ap1) %0 = va_arg i8** %ap, i32 ; <i32> [#uses=0] + store i32 %0, i32* undef %1 = va_arg i8** %ap, double ; <double> [#uses=1] call void @llvm.va_end(i8* %ap1) ret double %1 diff --git a/test/CodeGen/ARM/vext.ll b/test/CodeGen/ARM/vext.ll index 49a042b..65b5913 100644 --- a/test/CodeGen/ARM/vext.ll +++ b/test/CodeGen/ARM/vext.ll @@ -133,3 +133,20 @@ define <8 x i16> @test_illegal(<8 x i16>* %A, <8 x i16>* %B) nounwind { %tmp3 = shufflevector <8 x i16> %tmp1, <8 x i16> %tmp2, <8 x i32> <i32 0, i32 7, i32 5, i32 13, i32 3, i32 2, i32 2, i32 9> ret <8 x i16> %tmp3 } + +; PR11129 +; Make sure this doesn't crash +define arm_aapcscc void @test_elem_mismatch(<2 x i64>* nocapture %src, <4 x i16>* nocapture %dest) nounwind { +; CHECK: test_elem_mismatch: +; CHECK: vstr.64 + %tmp0 = load <2 x i64>* %src, align 16 + %tmp1 = bitcast <2 x i64> %tmp0 to <4 x i32> + %tmp2 = extractelement <4 x i32> %tmp1, i32 0 + %tmp3 = extractelement <4 x i32> %tmp1, i32 2 + %tmp4 = trunc i32 %tmp2 to i16 + %tmp5 = trunc i32 %tmp3 to i16 + %tmp6 = insertelement <4 x i16> undef, i16 %tmp4, i32 0 + %tmp7 = insertelement <4 x i16> %tmp6, i16 %tmp5, i32 1 + store <4 x i16> %tmp7, <4 x i16>* %dest, align 4 + ret void +} diff --git a/test/CodeGen/ARM/widen-vmovs.ll b/test/CodeGen/ARM/widen-vmovs.ll new file mode 100644 index 0000000..8fd99ba --- /dev/null +++ b/test/CodeGen/ARM/widen-vmovs.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -widen-vmovs -mcpu=cortex-a8 -verify-machineinstrs | FileCheck %s +target triple = "thumbv7-apple-ios" + +; The 0.0 constant is loaded from the constant pool and kept in a register. +; CHECK: %entry +; CHECK: vldr.32 s +; The float loop variable is initialized with a vmovs from the constant register. +; The vmovs is first widened to a vmovd, and then converted to a vorr because of the v2f32 vadd.f32. +; CHECK: vorr [[DL:d[0-9]+]], [[DN:d[0-9]+]] +; CHECK: , [[DN]] +; CHECK: %for.body.i +; CHECK: vadd.f32 [[DL]], [[DL]], [[DN]] +; +; This test is verifying: +; - The VMOVS widening is happening. +; - Register liveness is verified. +; - The execution domain switch to vorr works across basic blocks. + +define void @Mm() nounwind { +entry: + br label %for.body4 + +for.body4: + br label %for.body.i + +for.body.i: + %tmp3.i = phi float [ 0.000000e+00, %for.body4 ], [ %add.i, %for.body.i ] + %add.i = fadd float %tmp3.i, 0.000000e+00 + %exitcond.i = icmp eq i32 undef, 41 + br i1 %exitcond.i, label %rInnerproduct.exit, label %for.body.i + +rInnerproduct.exit: + store float %add.i, float* undef, align 4 + br label %for.body4 +} |