Add SwiftShader dump from Feb 6 2013
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-07-17-CrossRegClassCopy.ll b/src/LLVM/test/CodeGen/Thumb2/2009-07-17-CrossRegClassCopy.ll new file mode 100644 index 0000000..76ffe2a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-07-17-CrossRegClassCopy.ll
@@ -0,0 +1,35 @@ +; RUN: llc < %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:64:64-v128:128:128-a0:0:32" +target triple = "thumbv6t2-elf" + %struct.dwarf_cie = type <{ i32, i32, i8, [0 x i8], [3 x i8] }> + +declare i8* @read_sleb128(i8*, i32* nocapture) nounwind + +define i32 @get_cie_encoding(%struct.dwarf_cie* %cie) nounwind { +entry: + br i1 undef, label %bb1, label %bb13 + +bb1: ; preds = %entry + %tmp38 = add i32 undef, 10 ; <i32> [#uses=1] + br label %bb.i + +bb.i: ; preds = %bb.i, %bb1 + %indvar.i = phi i32 [ 0, %bb1 ], [ %2, %bb.i ] ; <i32> [#uses=3] + %tmp39 = add i32 %indvar.i, %tmp38 ; <i32> [#uses=1] + %p_addr.0.i = getelementptr i8* undef, i32 %tmp39 ; <i8*> [#uses=1] + %0 = load i8* %p_addr.0.i, align 1 ; <i8> [#uses=1] + %1 = icmp slt i8 %0, 0 ; <i1> [#uses=1] + %2 = add i32 %indvar.i, 1 ; <i32> [#uses=1] + br i1 %1, label %bb.i, label %read_uleb128.exit + +read_uleb128.exit: ; preds = %bb.i + %.sum40 = add i32 %indvar.i, undef ; <i32> [#uses=1] + %.sum31 = add i32 %.sum40, 2 ; <i32> [#uses=1] + %scevgep.i = getelementptr %struct.dwarf_cie* %cie, i32 0, i32 3, i32 %.sum31 ; <i8*> [#uses=1] + %3 = call i8* @read_sleb128(i8* %scevgep.i, i32* undef) ; <i8*> [#uses=0] + unreachable + +bb13: ; preds = %entry + ret i32 0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll new file mode 100644 index 0000000..4e1394f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-07-21-ISelBug.ll
@@ -0,0 +1,36 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+vfp2,+thumb2 | FileCheck %s +; rdar://7076238 + +@"\01LC" = external constant [36 x i8], align 1 ; <[36 x i8]*> [#uses=1] + +define i32 @t(i32, ...) nounwind { +entry: +; CHECK: t: +; CHECK: add r7, sp, #12 + %1 = load i8** undef, align 4 ; <i8*> [#uses=3] + %2 = getelementptr i8* %1, i32 4 ; <i8*> [#uses=1] + %3 = getelementptr i8* %1, i32 8 ; <i8*> [#uses=1] + %4 = bitcast i8* %2 to i32* ; <i32*> [#uses=1] + %5 = load i32* %4, align 4 ; <i32> [#uses=1] + %6 = trunc i32 %5 to i8 ; <i8> [#uses=1] + %7 = getelementptr i8* %1, i32 12 ; <i8*> [#uses=1] + %8 = bitcast i8* %3 to i32* ; <i32*> [#uses=1] + %9 = load i32* %8, align 4 ; <i32> [#uses=1] + %10 = trunc i32 %9 to i16 ; <i16> [#uses=1] + %11 = bitcast i8* %7 to i32* ; <i32*> [#uses=1] + %12 = load i32* %11, align 4 ; <i32> [#uses=1] + %13 = trunc i32 %12 to i16 ; <i16> [#uses=1] + %14 = load i32* undef, align 4 ; <i32> [#uses=2] + %15 = sext i8 %6 to i32 ; <i32> [#uses=2] + %16 = sext i16 %10 to i32 ; <i32> [#uses=2] + %17 = sext i16 %13 to i32 ; <i32> [#uses=2] + %18 = call i32 (i8*, ...)* @printf(i8* getelementptr ([36 x i8]* @"\01LC", i32 0, i32 0), i32 -128, i32 0, i32 %15, i32 %16, i32 %17, i32 0, i32 %14) nounwind ; <i32> [#uses=0] + %19 = add i32 0, %15 ; <i32> [#uses=1] + %20 = add i32 %19, %16 ; <i32> [#uses=1] + %21 = add i32 %20, %14 ; <i32> [#uses=1] + %22 = add i32 %21, %17 ; <i32> [#uses=1] + %23 = add i32 %22, 0 ; <i32> [#uses=1] + ret i32 %23 +} + +declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-07-23-CPIslandBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-07-23-CPIslandBug.ll new file mode 100644 index 0000000..4357366 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-07-23-CPIslandBug.ll
@@ -0,0 +1,22 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mattr=+vfp2,+thumb2 +; rdar://7083961 + +define i32 @value(i64 %b1, i64 %b2) nounwind readonly { +entry: + %0 = icmp eq i32 undef, 0 ; <i1> [#uses=1] + %mod.0.ph.ph = select i1 %0, float -1.000000e+00, float 1.000000e+00 ; <float> [#uses=1] + br label %bb7 + +bb7: ; preds = %bb7, %entry + br i1 undef, label %bb86.preheader, label %bb7 + +bb86.preheader: ; preds = %bb7 + %1 = fmul float %mod.0.ph.ph, 5.000000e+00 ; <float> [#uses=0] + br label %bb79 + +bb79: ; preds = %bb79, %bb86.preheader + br i1 undef, label %bb119, label %bb79 + +bb119: ; preds = %bb79 + ret i32 undef +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-07-30-PEICrash.ll b/src/LLVM/test/CodeGen/Thumb2/2009-07-30-PEICrash.ll new file mode 100644 index 0000000..3e07618 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-07-30-PEICrash.ll
@@ -0,0 +1,193 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim + + %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.JHUFF_TBL = type { [17 x i8], [256 x i8], i32 } + %struct.JQUANT_TBL = type { [64 x i16], i32 } + %struct.__sFILEX = type opaque + %struct.__sbuf = type { i8*, i32 } + %struct.anon = type { [8 x i32], [48 x i8] } + %struct.backing_store_info = type { void (%struct.jpeg_common_struct*, %struct.backing_store_info*, i8*, i32, i32)*, void (%struct.jpeg_common_struct*, %struct.backing_store_info*, i8*, i32, i32)*, void (%struct.jpeg_common_struct*, %struct.backing_store_info*)*, %struct.FILE*, [64 x i8] } + %struct.jpeg_color_deconverter = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i8***, i32, i8**, i32)* } + %struct.jpeg_color_quantizer = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8**, i8**, i32)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)* } + %struct.jpeg_common_struct = type { %struct.jpeg_error_mgr*, %struct.jpeg_memory_mgr*, %struct.jpeg_progress_mgr*, i32, i32 } + %struct.jpeg_component_info = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.JQUANT_TBL*, i8* } + %struct.jpeg_d_coef_controller = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*, i8***)*, %struct.jvirt_barray_control** } + %struct.jpeg_d_main_controller = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8**, i32*, i32)* } + %struct.jpeg_d_post_controller = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8***, i32*, i32, i8**, i32*, i32)* } + %struct.jpeg_decomp_master = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32 } + %struct.jpeg_decompress_struct = type { %struct.jpeg_error_mgr*, %struct.jpeg_memory_mgr*, %struct.jpeg_progress_mgr*, i32, i32, %struct.jpeg_source_mgr*, 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 %struct.JQUANT_TBL*], [4 x %struct.JHUFF_TBL*], [4 x %struct.JHUFF_TBL*], i32, %struct.jpeg_component_info*, i32, i32, [16 x i8], [16 x i8], [16 x i8], i32, i32, i8, i16, i16, i32, i8, i32, i32, i32, i32, i32, i8*, i32, [4 x %struct.jpeg_component_info*], i32, i32, i32, [10 x i32], i32, i32, i32, i32, i32, %struct.jpeg_decomp_master*, %struct.jpeg_d_main_controller*, %struct.jpeg_d_coef_controller*, %struct.jpeg_d_post_controller*, %struct.jpeg_input_controller*, %struct.jpeg_marker_reader*, %struct.jpeg_entropy_decoder*, %struct.jpeg_inverse_dct*, %struct.jpeg_upsampler*, %struct.jpeg_color_deconverter*, %struct.jpeg_color_quantizer* } + %struct.jpeg_entropy_decoder = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*, [64 x i16]**)* } + %struct.jpeg_error_mgr = type { void (%struct.jpeg_common_struct*)*, void (%struct.jpeg_common_struct*, i32)*, void (%struct.jpeg_common_struct*)*, void (%struct.jpeg_common_struct*, i8*)*, void (%struct.jpeg_common_struct*)*, i32, %struct.anon, i32, i32, i8**, i32, i8**, i32, i32 } + %struct.jpeg_input_controller = type { i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32, i32 } + %struct.jpeg_inverse_dct = type { void (%struct.jpeg_decompress_struct*)*, [10 x void (%struct.jpeg_decompress_struct*, %struct.jpeg_component_info*, i16*, i8**, i32)*] } + %struct.jpeg_marker_reader = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, [16 x i32 (%struct.jpeg_decompress_struct*)*], i32, i32, i32, i32 } + %struct.jpeg_memory_mgr = type { i8* (%struct.jpeg_common_struct*, i32, i32)*, i8* (%struct.jpeg_common_struct*, i32, i32)*, i8** (%struct.jpeg_common_struct*, i32, i32, i32)*, [64 x i16]** (%struct.jpeg_common_struct*, i32, i32, i32)*, %struct.jvirt_sarray_control* (%struct.jpeg_common_struct*, i32, i32, i32, i32, i32)*, %struct.jvirt_barray_control* (%struct.jpeg_common_struct*, i32, i32, i32, i32, i32)*, void (%struct.jpeg_common_struct*)*, i8** (%struct.jpeg_common_struct*, %struct.jvirt_sarray_control*, i32, i32, i32)*, [64 x i16]** (%struct.jpeg_common_struct*, %struct.jvirt_barray_control*, i32, i32, i32)*, void (%struct.jpeg_common_struct*, i32)*, void (%struct.jpeg_common_struct*)*, i32 } + %struct.jpeg_progress_mgr = type { void (%struct.jpeg_common_struct*)*, i32, i32, i32, i32 } + %struct.jpeg_source_mgr = type { i8*, i32, void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i32)*, i32 (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*)* } + %struct.jpeg_upsampler = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i8***, i32*, i32, i8**, i32*, i32)*, i32 } + %struct.jvirt_barray_control = type { [64 x i16]**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.jvirt_barray_control*, %struct.backing_store_info } + %struct.jvirt_sarray_control = type { i8**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.jvirt_sarray_control*, %struct.backing_store_info } + +define void @jpeg_idct_float(%struct.jpeg_decompress_struct* nocapture %cinfo, %struct.jpeg_component_info* nocapture %compptr, i16* nocapture %coef_block, i8** nocapture %output_buf, i32 %output_col) nounwind { +entry: + %workspace = alloca [64 x float], align 4 ; <[64 x float]*> [#uses=11] + %0 = load i8** undef, align 4 ; <i8*> [#uses=5] + br label %bb + +bb: ; preds = %bb, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=11] + %tmp39 = add i32 %indvar, 8 ; <i32> [#uses=0] + %tmp41 = add i32 %indvar, 16 ; <i32> [#uses=2] + %scevgep42 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp41 ; <float*> [#uses=1] + %tmp43 = add i32 %indvar, 24 ; <i32> [#uses=1] + %scevgep44 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp43 ; <float*> [#uses=1] + %tmp45 = add i32 %indvar, 32 ; <i32> [#uses=1] + %scevgep46 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp45 ; <float*> [#uses=1] + %tmp47 = add i32 %indvar, 40 ; <i32> [#uses=1] + %scevgep48 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp47 ; <float*> [#uses=1] + %tmp49 = add i32 %indvar, 48 ; <i32> [#uses=1] + %scevgep50 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp49 ; <float*> [#uses=1] + %tmp51 = add i32 %indvar, 56 ; <i32> [#uses=1] + %scevgep52 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp51 ; <float*> [#uses=1] + %wsptr.119 = getelementptr [64 x float]* %workspace, i32 0, i32 %indvar ; <float*> [#uses=1] + %tmp54 = shl i32 %indvar, 2 ; <i32> [#uses=1] + %scevgep76 = getelementptr i8* undef, i32 %tmp54 ; <i8*> [#uses=1] + %quantptr.118 = bitcast i8* %scevgep76 to float* ; <float*> [#uses=1] + %scevgep79 = getelementptr i16* %coef_block, i32 %tmp41 ; <i16*> [#uses=0] + %inptr.117 = getelementptr i16* %coef_block, i32 %indvar ; <i16*> [#uses=1] + %1 = load i16* null, align 2 ; <i16> [#uses=1] + %2 = load i16* undef, align 2 ; <i16> [#uses=1] + %3 = load i16* %inptr.117, align 2 ; <i16> [#uses=1] + %4 = sitofp i16 %3 to float ; <float> [#uses=1] + %5 = load float* %quantptr.118, align 4 ; <float> [#uses=1] + %6 = fmul float %4, %5 ; <float> [#uses=1] + %7 = fsub float %6, undef ; <float> [#uses=2] + %8 = fmul float undef, 0x3FF6A09E60000000 ; <float> [#uses=1] + %9 = fsub float %8, 0.000000e+00 ; <float> [#uses=2] + %10 = fadd float undef, 0.000000e+00 ; <float> [#uses=2] + %11 = fadd float %7, %9 ; <float> [#uses=2] + %12 = fsub float %7, %9 ; <float> [#uses=2] + %13 = sitofp i16 %1 to float ; <float> [#uses=1] + %14 = fmul float %13, undef ; <float> [#uses=2] + %15 = sitofp i16 %2 to float ; <float> [#uses=1] + %16 = load float* undef, align 4 ; <float> [#uses=1] + %17 = fmul float %15, %16 ; <float> [#uses=1] + %18 = fadd float %14, undef ; <float> [#uses=2] + %19 = fsub float %14, undef ; <float> [#uses=2] + %20 = fadd float undef, %17 ; <float> [#uses=2] + %21 = fadd float %20, %18 ; <float> [#uses=3] + %22 = fsub float %20, %18 ; <float> [#uses=1] + %23 = fmul float %22, 0x3FF6A09E60000000 ; <float> [#uses=1] + %24 = fadd float %19, undef ; <float> [#uses=1] + %25 = fmul float %24, 0x3FFD906BC0000000 ; <float> [#uses=2] + %26 = fmul float undef, 0x3FF1517A80000000 ; <float> [#uses=1] + %27 = fsub float %26, %25 ; <float> [#uses=1] + %28 = fmul float %19, 0xC004E7AEA0000000 ; <float> [#uses=1] + %29 = fadd float %28, %25 ; <float> [#uses=1] + %30 = fsub float %29, %21 ; <float> [#uses=3] + %31 = fsub float %23, %30 ; <float> [#uses=3] + %32 = fadd float %27, %31 ; <float> [#uses=1] + %33 = fadd float %10, %21 ; <float> [#uses=1] + store float %33, float* %wsptr.119, align 4 + %34 = fsub float %10, %21 ; <float> [#uses=1] + store float %34, float* %scevgep52, align 4 + %35 = fadd float %11, %30 ; <float> [#uses=1] + store float %35, float* null, align 4 + %36 = fsub float %11, %30 ; <float> [#uses=1] + store float %36, float* %scevgep50, align 4 + %37 = fadd float %12, %31 ; <float> [#uses=1] + store float %37, float* %scevgep42, align 4 + %38 = fsub float %12, %31 ; <float> [#uses=1] + store float %38, float* %scevgep48, align 4 + %39 = fadd float undef, %32 ; <float> [#uses=1] + store float %39, float* %scevgep46, align 4 + store float undef, float* %scevgep44, align 4 + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 undef, label %bb6, label %bb + +bb6: ; preds = %bb + %.sum10 = add i32 %output_col, 1 ; <i32> [#uses=1] + %.sum8 = add i32 %output_col, 6 ; <i32> [#uses=1] + %.sum6 = add i32 %output_col, 2 ; <i32> [#uses=1] + %.sum = add i32 %output_col, 3 ; <i32> [#uses=1] + br label %bb8 + +bb8: ; preds = %bb8, %bb6 + %ctr.116 = phi i32 [ 0, %bb6 ], [ %88, %bb8 ] ; <i32> [#uses=3] + %scevgep = getelementptr i8** %output_buf, i32 %ctr.116 ; <i8**> [#uses=1] + %tmp = shl i32 %ctr.116, 3 ; <i32> [#uses=5] + %tmp2392 = or i32 %tmp, 4 ; <i32> [#uses=1] + %scevgep24 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp2392 ; <float*> [#uses=1] + %tmp2591 = or i32 %tmp, 2 ; <i32> [#uses=1] + %scevgep26 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp2591 ; <float*> [#uses=1] + %tmp2790 = or i32 %tmp, 6 ; <i32> [#uses=1] + %scevgep28 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp2790 ; <float*> [#uses=1] + %tmp3586 = or i32 %tmp, 7 ; <i32> [#uses=0] + %wsptr.215 = getelementptr [64 x float]* %workspace, i32 0, i32 %tmp ; <float*> [#uses=1] + %40 = load i8** %scevgep, align 4 ; <i8*> [#uses=4] + %41 = load float* %wsptr.215, align 4 ; <float> [#uses=1] + %42 = load float* %scevgep24, align 4 ; <float> [#uses=1] + %43 = fadd float %41, %42 ; <float> [#uses=1] + %44 = load float* %scevgep26, align 4 ; <float> [#uses=1] + %45 = load float* %scevgep28, align 4 ; <float> [#uses=1] + %46 = fadd float %44, %45 ; <float> [#uses=1] + %47 = fsub float %43, %46 ; <float> [#uses=2] + %48 = fsub float undef, 0.000000e+00 ; <float> [#uses=1] + %49 = fadd float 0.000000e+00, undef ; <float> [#uses=1] + %50 = fptosi float %49 to i32 ; <i32> [#uses=1] + %51 = add i32 %50, 4 ; <i32> [#uses=1] + %52 = lshr i32 %51, 3 ; <i32> [#uses=1] + %53 = and i32 %52, 1023 ; <i32> [#uses=1] + %.sum14 = add i32 %53, 128 ; <i32> [#uses=1] + %54 = getelementptr i8* %0, i32 %.sum14 ; <i8*> [#uses=1] + %55 = load i8* %54, align 1 ; <i8> [#uses=1] + store i8 %55, i8* null, align 1 + %56 = getelementptr i8* %40, i32 %.sum10 ; <i8*> [#uses=1] + store i8 0, i8* %56, align 1 + %57 = load i8* null, align 1 ; <i8> [#uses=1] + %58 = getelementptr i8* %40, i32 %.sum8 ; <i8*> [#uses=1] + store i8 %57, i8* %58, align 1 + %59 = fadd float undef, %48 ; <float> [#uses=1] + %60 = fptosi float %59 to i32 ; <i32> [#uses=1] + %61 = add i32 %60, 4 ; <i32> [#uses=1] + %62 = lshr i32 %61, 3 ; <i32> [#uses=1] + %63 = and i32 %62, 1023 ; <i32> [#uses=1] + %.sum7 = add i32 %63, 128 ; <i32> [#uses=1] + %64 = getelementptr i8* %0, i32 %.sum7 ; <i8*> [#uses=1] + %65 = load i8* %64, align 1 ; <i8> [#uses=1] + %66 = getelementptr i8* %40, i32 %.sum6 ; <i8*> [#uses=1] + store i8 %65, i8* %66, align 1 + %67 = fptosi float undef to i32 ; <i32> [#uses=1] + %68 = add i32 %67, 4 ; <i32> [#uses=1] + %69 = lshr i32 %68, 3 ; <i32> [#uses=1] + %70 = and i32 %69, 1023 ; <i32> [#uses=1] + %.sum5 = add i32 %70, 128 ; <i32> [#uses=1] + %71 = getelementptr i8* %0, i32 %.sum5 ; <i8*> [#uses=1] + %72 = load i8* %71, align 1 ; <i8> [#uses=1] + store i8 %72, i8* undef, align 1 + %73 = fadd float %47, undef ; <float> [#uses=1] + %74 = fptosi float %73 to i32 ; <i32> [#uses=1] + %75 = add i32 %74, 4 ; <i32> [#uses=1] + %76 = lshr i32 %75, 3 ; <i32> [#uses=1] + %77 = and i32 %76, 1023 ; <i32> [#uses=1] + %.sum3 = add i32 %77, 128 ; <i32> [#uses=1] + %78 = getelementptr i8* %0, i32 %.sum3 ; <i8*> [#uses=1] + %79 = load i8* %78, align 1 ; <i8> [#uses=1] + store i8 %79, i8* undef, align 1 + %80 = fsub float %47, undef ; <float> [#uses=1] + %81 = fptosi float %80 to i32 ; <i32> [#uses=1] + %82 = add i32 %81, 4 ; <i32> [#uses=1] + %83 = lshr i32 %82, 3 ; <i32> [#uses=1] + %84 = and i32 %83, 1023 ; <i32> [#uses=1] + %.sum1 = add i32 %84, 128 ; <i32> [#uses=1] + %85 = getelementptr i8* %0, i32 %.sum1 ; <i8*> [#uses=1] + %86 = load i8* %85, align 1 ; <i8> [#uses=1] + %87 = getelementptr i8* %40, i32 %.sum ; <i8*> [#uses=1] + store i8 %86, i8* %87, align 1 + %88 = add i32 %ctr.116, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %88, 8 ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb8 + +return: ; preds = %bb8 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-01-WrongLDRBOpc.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-01-WrongLDRBOpc.ll new file mode 100644 index 0000000..095aecc --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-01-WrongLDRBOpc.ll
@@ -0,0 +1,85 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim | FileCheck %s + +@csize = external global [100 x [20 x [4 x i8]]] ; <[100 x [20 x [4 x i8]]]*> [#uses=1] +@vsize = external global [100 x [20 x [4 x i8]]] ; <[100 x [20 x [4 x i8]]]*> [#uses=1] +@cll = external global [20 x [10 x i8]] ; <[20 x [10 x i8]]*> [#uses=1] +@lefline = external global [100 x [20 x i32]] ; <[100 x [20 x i32]]*> [#uses=1] +@sep = external global [20 x i32] ; <[20 x i32]*> [#uses=1] + +define void @main(i32 %argc, i8** %argv) noreturn nounwind { +; CHECK: main: +; CHECK: ldrb +entry: + %nb.i.i.i = alloca [25 x i8], align 1 ; <[25 x i8]*> [#uses=0] + %line.i.i.i = alloca [200 x i8], align 1 ; <[200 x i8]*> [#uses=1] + %line.i = alloca [1024 x i8], align 1 ; <[1024 x i8]*> [#uses=0] + br i1 undef, label %bb.i.i, label %bb4.preheader.i + +bb.i.i: ; preds = %entry + unreachable + +bb4.preheader.i: ; preds = %entry + br i1 undef, label %tbl.exit, label %bb.i.preheader + +bb.i.preheader: ; preds = %bb4.preheader.i + %line3.i.i.i = getelementptr [200 x i8]* %line.i.i.i, i32 0, i32 0 ; <i8*> [#uses=1] + br label %bb.i + +bb.i: ; preds = %bb4.backedge.i, %bb.i.preheader + br i1 undef, label %bb3.i, label %bb4.backedge.i + +bb3.i: ; preds = %bb.i + br i1 undef, label %bb2.i184.i.i, label %bb.i183.i.i + +bb.i183.i.i: ; preds = %bb.i183.i.i, %bb3.i + br i1 undef, label %bb2.i184.i.i, label %bb.i183.i.i + +bb2.i184.i.i: ; preds = %bb.i183.i.i, %bb3.i + br i1 undef, label %bb5.i185.i.i, label %bb35.preheader.i.i.i + +bb35.preheader.i.i.i: ; preds = %bb2.i184.i.i + %0 = load i8* %line3.i.i.i, align 1 ; <i8> [#uses=1] + %1 = icmp eq i8 %0, 59 ; <i1> [#uses=1] + br i1 %1, label %bb36.i.i.i, label %bb9.i186.i.i + +bb5.i185.i.i: ; preds = %bb2.i184.i.i + br label %bb.i171.i.i + +bb9.i186.i.i: ; preds = %bb35.preheader.i.i.i + unreachable + +bb36.i.i.i: ; preds = %bb35.preheader.i.i.i + br label %bb.i171.i.i + +bb.i171.i.i: ; preds = %bb3.i176.i.i, %bb36.i.i.i, %bb5.i185.i.i + %2 = phi i32 [ %4, %bb3.i176.i.i ], [ 0, %bb36.i.i.i ], [ 0, %bb5.i185.i.i ] ; <i32> [#uses=6] + %scevgep16.i.i.i = getelementptr [20 x i32]* @sep, i32 0, i32 %2 ; <i32*> [#uses=1] + %scevgep18.i.i.i = getelementptr [20 x [10 x i8]]* @cll, i32 0, i32 %2, i32 0 ; <i8*> [#uses=0] + store i32 -1, i32* %scevgep16.i.i.i, align 4 + br label %bb1.i175.i.i + +bb1.i175.i.i: ; preds = %bb1.i175.i.i, %bb.i171.i.i + %i.03.i172.i.i = phi i32 [ 0, %bb.i171.i.i ], [ %3, %bb1.i175.i.i ] ; <i32> [#uses=4] + %scevgep11.i.i.i = getelementptr [100 x [20 x i32]]* @lefline, i32 0, i32 %i.03.i172.i.i, i32 %2 ; <i32*> [#uses=1] + %scevgep12.i.i.i = getelementptr [100 x [20 x [4 x i8]]]* @vsize, i32 0, i32 %i.03.i172.i.i, i32 %2, i32 0 ; <i8*> [#uses=1] + %scevgep13.i.i.i = getelementptr [100 x [20 x [4 x i8]]]* @csize, i32 0, i32 %i.03.i172.i.i, i32 %2, i32 0 ; <i8*> [#uses=0] + store i8 0, i8* %scevgep12.i.i.i, align 1 + store i32 0, i32* %scevgep11.i.i.i, align 4 + store i32 108, i32* undef, align 4 + %3 = add i32 %i.03.i172.i.i, 1 ; <i32> [#uses=2] + %exitcond.i174.i.i = icmp eq i32 %3, 100 ; <i1> [#uses=1] + br i1 %exitcond.i174.i.i, label %bb3.i176.i.i, label %bb1.i175.i.i + +bb3.i176.i.i: ; preds = %bb1.i175.i.i + %4 = add i32 %2, 1 ; <i32> [#uses=1] + br i1 undef, label %bb5.i177.i.i, label %bb.i171.i.i + +bb5.i177.i.i: ; preds = %bb3.i176.i.i + unreachable + +bb4.backedge.i: ; preds = %bb.i + br i1 undef, label %tbl.exit, label %bb.i + +tbl.exit: ; preds = %bb4.backedge.i, %bb4.preheader.i + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll new file mode 100644 index 0000000..0b56103 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll
@@ -0,0 +1,46 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim + + %0 = type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16)*, i32 } ; type %0 + %1 = type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16*)*, i32 } ; type %1 + %2 = type { void (%"struct.xalanc_1_8::FormatterToXML"*, %"struct.xalanc_1_8::XalanDOMString"*)*, i32 } ; type %2 + %3 = type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16*, i32, i32)*, i32 } ; type %3 + %4 = type { void (%"struct.xalanc_1_8::FormatterToXML"*)*, i32 } ; type %4 + %"struct.std::CharVectorType" = type { %"struct.std::_Vector_base<char,std::allocator<char> >" } + %"struct.std::_Bit_const_iterator" = type { %"struct.std::_Bit_iterator_base" } + %"struct.std::_Bit_iterator_base" = type { i32*, i32 } + %"struct.std::_Bvector_base<std::allocator<bool> >" = type { %"struct.std::_Bvector_base<std::allocator<bool> >::_Bvector_impl" } + %"struct.std::_Bvector_base<std::allocator<bool> >::_Bvector_impl" = type { %"struct.std::_Bit_const_iterator", %"struct.std::_Bit_const_iterator", i32* } + %"struct.std::_Vector_base<char,std::allocator<char> >" = type { %"struct.std::_Vector_base<char,std::allocator<char> >::_Vector_impl" } + %"struct.std::_Vector_base<char,std::allocator<char> >::_Vector_impl" = type { i8*, i8*, i8* } + %"struct.std::_Vector_base<short unsigned int,std::allocator<short unsigned int> >" = type { %"struct.std::_Vector_base<short unsigned int,std::allocator<short unsigned int> >::_Vector_impl" } + %"struct.std::_Vector_base<short unsigned int,std::allocator<short unsigned int> >::_Vector_impl" = type { i16*, i16*, i16* } + %"struct.std::basic_ostream<char,std::char_traits<char> >.base" = type { i32 (...)** } + %"struct.std::vector<bool,std::allocator<bool> >" = type { %"struct.std::_Bvector_base<std::allocator<bool> >" } + %"struct.std::vector<short unsigned int,std::allocator<short unsigned int> >" = type { %"struct.std::_Vector_base<short unsigned int,std::allocator<short unsigned int> >" } + %"struct.xalanc_1_8::FormatterListener" = type { %"struct.std::basic_ostream<char,std::char_traits<char> >.base", %"struct.std::basic_ostream<char,std::char_traits<char> >.base"*, i32 } + %"struct.xalanc_1_8::FormatterToXML" = type { %"struct.xalanc_1_8::FormatterListener", %"struct.std::basic_ostream<char,std::char_traits<char> >.base"*, %"struct.xalanc_1_8::XalanOutputStream"*, i16, [256 x i16], [256 x i16], i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", i32, i32, %"struct.std::vector<bool,std::allocator<bool> >", %"struct.xalanc_1_8::XalanDOMString", i8, i8, i8, i8, i8, %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.std::vector<short unsigned int,std::allocator<short unsigned int> >", i32, %"struct.std::CharVectorType", %"struct.std::vector<bool,std::allocator<bool> >", %0, %1, %2, %3, %0, %1, %2, %3, %4, i16*, i32 } + %"struct.xalanc_1_8::XalanDOMString" = type { %"struct.std::vector<short unsigned int,std::allocator<short unsigned int> >", i32 } + %"struct.xalanc_1_8::XalanOutputStream" = type { i32 (...)**, i32, %"struct.std::basic_ostream<char,std::char_traits<char> >.base"*, i32, %"struct.std::vector<short unsigned int,std::allocator<short unsigned int> >", %"struct.xalanc_1_8::XalanDOMString", i8, i8, %"struct.std::CharVectorType" } + +declare void @_ZN10xalanc_1_814FormatterToXML17writeParentTagEndEv(%"struct.xalanc_1_8::FormatterToXML"*) + +define void @_ZN10xalanc_1_814FormatterToXML5cdataEPKtj(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 %length) { +entry: + %0 = getelementptr %"struct.xalanc_1_8::FormatterToXML"* %this, i32 0, i32 13 ; <i8*> [#uses=1] + br i1 undef, label %bb4, label %bb + +bb: ; preds = %entry + store i8 0, i8* %0, align 1 + %1 = getelementptr %"struct.xalanc_1_8::FormatterToXML"* %this, i32 0, i32 0, i32 0, i32 0 ; <i32 (...)***> [#uses=1] + %2 = load i32 (...)*** %1, align 4 ; <i32 (...)**> [#uses=1] + %3 = getelementptr i32 (...)** %2, i32 11 ; <i32 (...)**> [#uses=1] + %4 = load i32 (...)** %3, align 4 ; <i32 (...)*> [#uses=1] + %5 = bitcast i32 (...)* %4 to void (%"struct.xalanc_1_8::FormatterToXML"*, i16*, i32)* ; <void (%"struct.xalanc_1_8::FormatterToXML"*, i16*, i32)*> [#uses=1] + tail call void %5(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 %length) + ret void + +bb4: ; preds = %entry + tail call void @_ZN10xalanc_1_814FormatterToXML17writeParentTagEndEv(%"struct.xalanc_1_8::FormatterToXML"* %this) + tail call void undef(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 0, i32 %length, i8 zeroext undef) + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerAssert.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerAssert.ll new file mode 100644 index 0000000..acff261 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerAssert.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabi +; PR4681 + + %struct.FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct.FILE*, i32, i32, i32, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i32, i32, [40 x i8] } + %struct._IO_marker = type { %struct._IO_marker*, %struct.FILE*, i32 } +@.str2 = external constant [30 x i8], align 1 ; <[30 x i8]*> [#uses=1] + +define i32 @__mf_heuristic_check(i32 %ptr, i32 %ptr_high) nounwind { +entry: + br i1 undef, label %bb1, label %bb + +bb: ; preds = %entry + unreachable + +bb1: ; preds = %entry + br i1 undef, label %bb9, label %bb2 + +bb2: ; preds = %bb1 + %0 = call i8* @llvm.frameaddress(i32 0) ; <i8*> [#uses=1] + %1 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* noalias undef, i8* noalias getelementptr ([30 x i8]* @.str2, i32 0, i32 0), i8* %0, i8* null) nounwind ; <i32> [#uses=0] + unreachable + +bb9: ; preds = %bb1 + ret i32 undef +} + +declare i8* @llvm.frameaddress(i32) nounwind readnone + +declare i32 @fprintf(%struct.FILE* noalias nocapture, i8* noalias nocapture, ...) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll new file mode 100644 index 0000000..28ac28b --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-CoalescerBug.ll
@@ -0,0 +1,153 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim + + %0 = type { %struct.GAP } ; type %0 + %1 = type { i16, i8, i8 } ; type %1 + %2 = type { [2 x i32], [2 x i32] } ; type %2 + %3 = type { %struct.rec* } ; type %3 + %4 = type { i8, i8, i16, i8, i8, i8, i8 } ; type %4 + %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.FILE_POS = type { i8, i8, i16, i32 } + %struct.FIRST_UNION = type { %struct.FILE_POS } + %struct.FOURTH_UNION = type { %struct.STYLE } + %struct.GAP = type { i8, i8, i16 } + %struct.LIST = type { %struct.rec*, %struct.rec* } + %struct.SECOND_UNION = type { %1 } + %struct.STYLE = type { %0, %0, i16, i16, i32 } + %struct.THIRD_UNION = type { %2 } + %struct.__sFILEX = type opaque + %struct.__sbuf = type { i8*, i32 } + %struct.head_type = type { [2 x %struct.LIST], %struct.FIRST_UNION, %struct.SECOND_UNION, %struct.THIRD_UNION, %struct.FOURTH_UNION, %struct.rec*, %3, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, i32 } + %struct.rec = type { %struct.head_type } +@.str24239 = external constant [20 x i8], align 1 ; <[20 x i8]*> [#uses=1] +@no_file_pos = external global %4 ; <%4*> [#uses=1] +@zz_tmp = external global %struct.rec* ; <%struct.rec**> [#uses=1] +@.str81872 = external constant [10 x i8], align 1 ; <[10 x i8]*> [#uses=1] +@out_fp = external global %struct.FILE* ; <%struct.FILE**> [#uses=2] +@cpexists = external global i32 ; <i32*> [#uses=2] +@.str212784 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@.str1822946 = external constant [8 x i8], align 1 ; <[8 x i8]*> [#uses=1] +@.str1842948 = external constant [11 x i8], align 1 ; <[11 x i8]*> [#uses=1] + +declare i32 @fprintf(%struct.FILE* nocapture, i8* nocapture, ...) nounwind + +declare i32 @"\01_fwrite"(i8*, i32, i32, i8*) + +declare %struct.FILE* @OpenIncGraphicFile(i8*, i8 zeroext, %struct.rec** nocapture, %struct.FILE_POS*, i32* nocapture) nounwind + +declare void @Error(i32, i32, i8*, i32, %struct.FILE_POS*, ...) nounwind + +declare i8* @fgets(i8*, i32, %struct.FILE* nocapture) nounwind + +define void @PS_PrintGraphicInclude(%struct.rec* %x, i32 %colmark, i32 %rowmark) nounwind { +entry: + br label %bb5 + +bb5: ; preds = %bb5, %entry + %.pn = phi %struct.rec* [ %y.0, %bb5 ], [ undef, %entry ] ; <%struct.rec*> [#uses=1] + %y.0.in = getelementptr %struct.rec* %.pn, i32 0, i32 0, i32 0, i32 1, i32 0 ; <%struct.rec**> [#uses=1] + %y.0 = load %struct.rec** %y.0.in ; <%struct.rec*> [#uses=2] + br i1 undef, label %bb5, label %bb6 + +bb6: ; preds = %bb5 + %0 = call %struct.FILE* @OpenIncGraphicFile(i8* undef, i8 zeroext 0, %struct.rec** undef, %struct.FILE_POS* null, i32* undef) nounwind ; <%struct.FILE*> [#uses=1] + br i1 false, label %bb.i, label %FontHalfXHeight.exit + +bb.i: ; preds = %bb6 + br label %FontHalfXHeight.exit + +FontHalfXHeight.exit: ; preds = %bb.i, %bb6 + br i1 undef, label %bb.i1, label %FontSize.exit + +bb.i1: ; preds = %FontHalfXHeight.exit + br label %FontSize.exit + +FontSize.exit: ; preds = %bb.i1, %FontHalfXHeight.exit + %1 = load i32* undef, align 4 ; <i32> [#uses=1] + %2 = icmp ult i32 0, undef ; <i1> [#uses=1] + br i1 %2, label %bb.i5, label %FontName.exit + +bb.i5: ; preds = %FontSize.exit + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 1, i32 2, i8* getelementptr ([20 x i8]* @.str24239, i32 0, i32 0), i32 0, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*), i8* getelementptr ([10 x i8]* @.str81872, i32 0, i32 0)) nounwind + br label %FontName.exit + +FontName.exit: ; preds = %bb.i5, %FontSize.exit + %3 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* undef, i8* getelementptr ([8 x i8]* @.str1822946, i32 0, i32 0), i32 %1, i8* undef) nounwind ; <i32> [#uses=0] + %4 = call i32 @"\01_fwrite"(i8* getelementptr ([11 x i8]* @.str1842948, i32 0, i32 0), i32 1, i32 10, i8* undef) nounwind ; <i32> [#uses=0] + %5 = sub i32 %colmark, undef ; <i32> [#uses=1] + %6 = sub i32 %rowmark, undef ; <i32> [#uses=1] + %7 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %8 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %7, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 %5, i32 %6) nounwind ; <i32> [#uses=0] + store i32 0, i32* @cpexists, align 4 + %9 = getelementptr %struct.rec* %y.0, i32 0, i32 0, i32 3, i32 0, i32 0, i32 1 ; <i32*> [#uses=1] + %10 = load i32* %9, align 4 ; <i32> [#uses=1] + %11 = sub i32 0, %10 ; <i32> [#uses=1] + %12 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %13 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %12, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 undef, i32 %11) nounwind ; <i32> [#uses=0] + store i32 0, i32* @cpexists, align 4 + br label %bb100.outer.outer + +bb100.outer.outer: ; preds = %bb79.critedge, %bb1.i3, %FontName.exit + %x_addr.0.ph.ph = phi %struct.rec* [ %x, %FontName.exit ], [ null, %bb79.critedge ], [ null, %bb1.i3 ] ; <%struct.rec*> [#uses=1] + %14 = getelementptr %struct.rec* %x_addr.0.ph.ph, i32 0, i32 0, i32 1, i32 0 ; <%struct.FILE_POS*> [#uses=0] + br label %bb100.outer + +bb.i80: ; preds = %bb3.i85 + br i1 undef, label %bb2.i84, label %bb2.i51 + +bb2.i84: ; preds = %bb100.outer, %bb.i80 + br i1 undef, label %bb3.i77, label %bb3.i85 + +bb3.i85: ; preds = %bb2.i84 + br i1 false, label %StringBeginsWith.exit88, label %bb.i80 + +StringBeginsWith.exit88: ; preds = %bb3.i85 + br i1 undef, label %bb3.i77, label %bb2.i51 + +bb2.i.i68: ; preds = %bb3.i77 + br label %bb3.i77 + +bb3.i77: ; preds = %bb2.i.i68, %StringBeginsWith.exit88, %bb2.i84 + br i1 false, label %bb1.i58, label %bb2.i.i68 + +bb1.i58: ; preds = %bb3.i77 + unreachable + +bb.i47: ; preds = %bb3.i52 + br i1 undef, label %bb2.i51, label %bb2.i.i15.critedge + +bb2.i51: ; preds = %bb.i47, %StringBeginsWith.exit88, %bb.i80 + %15 = load i8* undef, align 1 ; <i8> [#uses=0] + br i1 false, label %StringBeginsWith.exit55thread-split, label %bb3.i52 + +bb3.i52: ; preds = %bb2.i51 + br i1 false, label %StringBeginsWith.exit55, label %bb.i47 + +StringBeginsWith.exit55thread-split: ; preds = %bb2.i51 + br label %StringBeginsWith.exit55 + +StringBeginsWith.exit55: ; preds = %StringBeginsWith.exit55thread-split, %bb3.i52 + br label %bb2.i41 + +bb2.i41: ; preds = %bb2.i41, %StringBeginsWith.exit55 + br label %bb2.i41 + +bb2.i.i15.critedge: ; preds = %bb.i47 + %16 = call i8* @fgets(i8* undef, i32 512, %struct.FILE* %0) nounwind ; <i8*> [#uses=0] + %iftmp.560.0 = select i1 undef, i32 2, i32 0 ; <i32> [#uses=1] + br label %bb100.outer + +bb2.i8: ; preds = %bb100.outer + br i1 undef, label %bb1.i3, label %bb79.critedge + +bb1.i3: ; preds = %bb2.i8 + br label %bb100.outer.outer + +bb79.critedge: ; preds = %bb2.i8 + store %struct.rec* null, %struct.rec** @zz_tmp, align 4 + br label %bb100.outer.outer + +bb100.outer: ; preds = %bb2.i.i15.critedge, %bb100.outer.outer + %state.0.ph = phi i32 [ 0, %bb100.outer.outer ], [ %iftmp.560.0, %bb2.i.i15.critedge ] ; <i32> [#uses=1] + %cond = icmp eq i32 %state.0.ph, 1 ; <i1> [#uses=1] + br i1 %cond, label %bb2.i8, label %bb2.i84 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-ScavengerAssert.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-ScavengerAssert.ll new file mode 100644 index 0000000..88accf8 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-ScavengerAssert.ll
@@ -0,0 +1,508 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim -O3 + + %0 = type { i16, i8, i8 } ; type %0 + %1 = type { [2 x i32], [2 x i32] } ; type %1 + %2 = type { %struct.GAP } ; type %2 + %3 = type { %struct.rec* } ; type %3 + %4 = type { i8, i8, i16, i8, i8, i8, i8 } ; type %4 + %5 = type { i8, i8, i8, i8 } ; type %5 + %struct.COMPOSITE = type { i8, i16, i16 } + %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.FILE_POS = type { i8, i8, i16, i32 } + %struct.FIRST_UNION = type { %struct.FILE_POS } + %struct.FONT_INFO = type { %struct.metrics*, i8*, i16*, %struct.COMPOSITE*, i32, %struct.rec*, %struct.rec*, i16, i16, i16*, i8*, i8*, i16* } + %struct.FOURTH_UNION = type { %struct.STYLE } + %struct.GAP = type { i8, i8, i16 } + %struct.LIST = type { %struct.rec*, %struct.rec* } + %struct.SECOND_UNION = type { %0 } + %struct.STYLE = type { %2, %2, i16, i16, i32 } + %struct.THIRD_UNION = type { %1 } + %struct.__sFILEX = type opaque + %struct.__sbuf = type { i8*, i32 } + %struct.head_type = type { [2 x %struct.LIST], %struct.FIRST_UNION, %struct.SECOND_UNION, %struct.THIRD_UNION, %struct.FOURTH_UNION, %struct.rec*, %3, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, %struct.rec*, i32 } + %struct.metrics = type { i16, i16, i16, i16, i16 } + %struct.rec = type { %struct.head_type } +@.str24239 = external constant [20 x i8], align 1 ; <[20 x i8]*> [#uses=1] +@no_file_pos = external global %4 ; <%4*> [#uses=1] +@.str19294 = external constant [9 x i8], align 1 ; <[9 x i8]*> [#uses=1] +@zz_lengths = external global [150 x i8] ; <[150 x i8]*> [#uses=1] +@next_free.4772 = external global i8** ; <i8***> [#uses=3] +@top_free.4773 = external global i8** ; <i8***> [#uses=2] +@.str1575 = external constant [32 x i8], align 1 ; <[32 x i8]*> [#uses=1] +@zz_free = external global [524 x %struct.rec*] ; <[524 x %struct.rec*]*> [#uses=2] +@zz_hold = external global %struct.rec* ; <%struct.rec**> [#uses=5] +@zz_tmp = external global %struct.rec* ; <%struct.rec**> [#uses=2] +@zz_res = external global %struct.rec* ; <%struct.rec**> [#uses=2] +@xx_link = external global %struct.rec* ; <%struct.rec**> [#uses=2] +@font_count = external global i32 ; <i32*> [#uses=1] +@.str81872 = external constant [10 x i8], align 1 ; <[10 x i8]*> [#uses=1] +@.str101874 = external constant [30 x i8], align 1 ; <[30 x i8]*> [#uses=1] +@.str111875 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@.str141878 = external constant [27 x i8], align 1 ; <[27 x i8]*> [#uses=1] +@out_fp = external global %struct.FILE* ; <%struct.FILE**> [#uses=3] +@.str192782 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@cpexists = external global i32 ; <i32*> [#uses=2] +@.str212784 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@currentfont = external global i32 ; <i32*> [#uses=3] +@wordcount = external global i32 ; <i32*> [#uses=1] +@needs = external global %struct.rec* ; <%struct.rec**> [#uses=1] +@.str742838 = external constant [6 x i8], align 1 ; <[6 x i8]*> [#uses=1] +@.str752839 = external constant [10 x i8], align 1 ; <[10 x i8]*> [#uses=1] +@.str1802944 = external constant [40 x i8], align 1 ; <[40 x i8]*> [#uses=1] +@.str1822946 = external constant [8 x i8], align 1 ; <[8 x i8]*> [#uses=1] +@.str1842948 = external constant [11 x i8], align 1 ; <[11 x i8]*> [#uses=1] +@.str1852949 = external constant [23 x i8], align 1 ; <[23 x i8]*> [#uses=1] +@.str1872951 = external constant [17 x i8], align 1 ; <[17 x i8]*> [#uses=1] +@.str1932957 = external constant [26 x i8], align 1 ; <[26 x i8]*> [#uses=1] + +declare i32 @fprintf(%struct.FILE* nocapture, i8* nocapture, ...) nounwind + +declare i32 @"\01_fwrite"(i8*, i32, i32, i8*) + +declare i32 @remove(i8* nocapture) nounwind + +declare %struct.FILE* @OpenIncGraphicFile(i8*, i8 zeroext, %struct.rec** nocapture, %struct.FILE_POS*, i32* nocapture) nounwind + +declare %struct.rec* @MakeWord(i32, i8* nocapture, %struct.FILE_POS*) nounwind + +declare void @Error(i32, i32, i8*, i32, %struct.FILE_POS*, ...) nounwind + +declare i32 @"\01_fputs"(i8*, %struct.FILE*) + +declare noalias i8* @calloc(i32, i32) nounwind + +declare i8* @fgets(i8*, i32, %struct.FILE* nocapture) nounwind + +define void @PS_PrintGraphicInclude(%struct.rec* %x, i32 %colmark, i32 %rowmark) nounwind { +entry: + %buff = alloca [512 x i8], align 4 ; <[512 x i8]*> [#uses=5] + %0 = getelementptr %struct.rec* %x, i32 0, i32 0, i32 1, i32 0, i32 0 ; <i8*> [#uses=2] + %1 = load i8* %0, align 4 ; <i8> [#uses=1] + %2 = add i8 %1, -94 ; <i8> [#uses=1] + %3 = icmp ugt i8 %2, 1 ; <i1> [#uses=1] + br i1 %3, label %bb, label %bb1 + +bb: ; preds = %entry + br label %bb1 + +bb1: ; preds = %bb, %entry + %4 = getelementptr %struct.rec* %x, i32 0, i32 0, i32 2 ; <%struct.SECOND_UNION*> [#uses=1] + %5 = bitcast %struct.SECOND_UNION* %4 to %5* ; <%5*> [#uses=1] + %6 = getelementptr %5* %5, i32 0, i32 1 ; <i8*> [#uses=1] + %7 = load i8* %6, align 1 ; <i8> [#uses=1] + %8 = icmp eq i8 %7, 0 ; <i1> [#uses=1] + br i1 %8, label %bb2, label %bb3 + +bb2: ; preds = %bb1 + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 1, i32 2, i8* getelementptr ([20 x i8]* @.str24239, i32 0, i32 0), i32 0, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*), i8* getelementptr ([40 x i8]* @.str1802944, i32 0, i32 0)) nounwind + br label %bb3 + +bb3: ; preds = %bb2, %bb1 + %9 = load %struct.rec** undef, align 4 ; <%struct.rec*> [#uses=0] + br label %bb5 + +bb5: ; preds = %bb5, %bb3 + %y.0 = load %struct.rec** null ; <%struct.rec*> [#uses=2] + br i1 false, label %bb5, label %bb6 + +bb6: ; preds = %bb5 + %10 = load i8* %0, align 4 ; <i8> [#uses=1] + %11 = getelementptr %struct.rec* %y.0, i32 0, i32 0, i32 1, i32 0 ; <%struct.FILE_POS*> [#uses=1] + %12 = call %struct.FILE* @OpenIncGraphicFile(i8* undef, i8 zeroext %10, %struct.rec** null, %struct.FILE_POS* %11, i32* undef) nounwind ; <%struct.FILE*> [#uses=4] + br i1 false, label %bb7, label %bb8 + +bb7: ; preds = %bb6 + unreachable + +bb8: ; preds = %bb6 + %13 = and i32 undef, 4095 ; <i32> [#uses=2] + %14 = load i32* @currentfont, align 4 ; <i32> [#uses=0] + br i1 false, label %bb10, label %bb9 + +bb9: ; preds = %bb8 + %15 = icmp ult i32 0, %13 ; <i1> [#uses=1] + br i1 %15, label %bb.i, label %FontHalfXHeight.exit + +bb.i: ; preds = %bb9 + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 1, i32 2, i8* getelementptr ([20 x i8]* @.str24239, i32 0, i32 0), i32 0, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*), i8* getelementptr ([17 x i8]* @.str111875, i32 0, i32 0)) nounwind + %.pre186 = load i32* @currentfont, align 4 ; <i32> [#uses=1] + br label %FontHalfXHeight.exit + +FontHalfXHeight.exit: ; preds = %bb.i, %bb9 + %16 = phi i32 [ %.pre186, %bb.i ], [ %13, %bb9 ] ; <i32> [#uses=1] + br i1 false, label %bb.i1, label %bb1.i + +bb.i1: ; preds = %FontHalfXHeight.exit + br label %bb1.i + +bb1.i: ; preds = %bb.i1, %FontHalfXHeight.exit + br i1 undef, label %bb2.i, label %FontSize.exit + +bb2.i: ; preds = %bb1.i + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 37, i32 61, i8* getelementptr ([30 x i8]* @.str101874, i32 0, i32 0), i32 1, %struct.FILE_POS* null) nounwind + unreachable + +FontSize.exit: ; preds = %bb1.i + %17 = getelementptr %struct.FONT_INFO* undef, i32 %16, i32 5 ; <%struct.rec**> [#uses=0] + %18 = load i32* undef, align 4 ; <i32> [#uses=1] + %19 = load i32* @currentfont, align 4 ; <i32> [#uses=2] + %20 = load i32* @font_count, align 4 ; <i32> [#uses=1] + %21 = icmp ult i32 %20, %19 ; <i1> [#uses=1] + br i1 %21, label %bb.i5, label %FontName.exit + +bb.i5: ; preds = %FontSize.exit + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 1, i32 2, i8* getelementptr ([20 x i8]* @.str24239, i32 0, i32 0), i32 0, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*), i8* getelementptr ([10 x i8]* @.str81872, i32 0, i32 0)) nounwind + br label %FontName.exit + +FontName.exit: ; preds = %bb.i5, %FontSize.exit + %22 = phi %struct.FONT_INFO* [ undef, %bb.i5 ], [ undef, %FontSize.exit ] ; <%struct.FONT_INFO*> [#uses=1] + %23 = getelementptr %struct.FONT_INFO* %22, i32 %19, i32 5 ; <%struct.rec**> [#uses=0] + %24 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* undef, i8* getelementptr ([8 x i8]* @.str1822946, i32 0, i32 0), i32 %18, i8* null) nounwind ; <i32> [#uses=0] + br label %bb10 + +bb10: ; preds = %FontName.exit, %bb8 + %25 = call i32 @"\01_fwrite"(i8* getelementptr ([11 x i8]* @.str1842948, i32 0, i32 0), i32 1, i32 10, i8* undef) nounwind ; <i32> [#uses=0] + %26 = sub i32 %rowmark, undef ; <i32> [#uses=1] + %27 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %28 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %27, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 undef, i32 %26) nounwind ; <i32> [#uses=0] + store i32 0, i32* @cpexists, align 4 + %29 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* undef, i8* getelementptr ([17 x i8]* @.str192782, i32 0, i32 0), double 2.000000e+01, double 2.000000e+01) nounwind ; <i32> [#uses=0] + %30 = getelementptr %struct.rec* %y.0, i32 0, i32 0, i32 3, i32 0, i32 0, i32 0 ; <i32*> [#uses=1] + %31 = load i32* %30, align 4 ; <i32> [#uses=1] + %32 = sub i32 0, %31 ; <i32> [#uses=1] + %33 = load i32* undef, align 4 ; <i32> [#uses=1] + %34 = sub i32 0, %33 ; <i32> [#uses=1] + %35 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %36 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %35, i8* getelementptr ([17 x i8]* @.str212784, i32 0, i32 0), i32 %32, i32 %34) nounwind ; <i32> [#uses=0] + store i32 0, i32* @cpexists, align 4 + %37 = load %struct.rec** null, align 4 ; <%struct.rec*> [#uses=1] + %38 = getelementptr %struct.rec* %37, i32 0, i32 0, i32 4 ; <%struct.FOURTH_UNION*> [#uses=1] + %39 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* undef, i8* getelementptr ([23 x i8]* @.str1852949, i32 0, i32 0), %struct.FOURTH_UNION* %38) nounwind ; <i32> [#uses=0] + %buff14 = getelementptr [512 x i8]* %buff, i32 0, i32 0 ; <i8*> [#uses=5] + %40 = call i8* @fgets(i8* %buff14, i32 512, %struct.FILE* %12) nounwind ; <i8*> [#uses=0] + %iftmp.506.0 = select i1 undef, i32 2, i32 0 ; <i32> [#uses=1] + %41 = getelementptr [512 x i8]* %buff, i32 0, i32 26 ; <i8*> [#uses=1] + br label %bb100.outer.outer + +bb100.outer.outer: ; preds = %bb83, %bb10 + %state.0.ph.ph = phi i32 [ %iftmp.506.0, %bb10 ], [ undef, %bb83 ] ; <i32> [#uses=1] + %x_addr.0.ph.ph = phi %struct.rec* [ %x, %bb10 ], [ %71, %bb83 ] ; <%struct.rec*> [#uses=1] + %42 = getelementptr %struct.rec* %x_addr.0.ph.ph, i32 0, i32 0, i32 1, i32 0 ; <%struct.FILE_POS*> [#uses=0] + br label %bb100.outer + +bb.i80: ; preds = %bb3.i85 + %43 = icmp eq i8 %44, %46 ; <i1> [#uses=1] + %indvar.next.i79 = add i32 %indvar.i81, 1 ; <i32> [#uses=1] + br i1 %43, label %bb2.i84, label %bb2.i51 + +bb2.i84: ; preds = %bb100.outer, %bb.i80 + %indvar.i81 = phi i32 [ %indvar.next.i79, %bb.i80 ], [ 0, %bb100.outer ] ; <i32> [#uses=3] + %pp.0.i82 = getelementptr [27 x i8]* @.str141878, i32 0, i32 %indvar.i81 ; <i8*> [#uses=2] + %sp.0.i83 = getelementptr [512 x i8]* %buff, i32 0, i32 %indvar.i81 ; <i8*> [#uses=1] + %44 = load i8* %sp.0.i83, align 1 ; <i8> [#uses=2] + %45 = icmp eq i8 %44, 0 ; <i1> [#uses=1] + br i1 %45, label %StringBeginsWith.exit88thread-split, label %bb3.i85 + +bb3.i85: ; preds = %bb2.i84 + %46 = load i8* %pp.0.i82, align 1 ; <i8> [#uses=3] + %47 = icmp eq i8 %46, 0 ; <i1> [#uses=1] + br i1 %47, label %StringBeginsWith.exit88, label %bb.i80 + +StringBeginsWith.exit88thread-split: ; preds = %bb2.i84 + %.pr = load i8* %pp.0.i82 ; <i8> [#uses=1] + br label %StringBeginsWith.exit88 + +StringBeginsWith.exit88: ; preds = %StringBeginsWith.exit88thread-split, %bb3.i85 + %48 = phi i8 [ %.pr, %StringBeginsWith.exit88thread-split ], [ %46, %bb3.i85 ] ; <i8> [#uses=1] + %phitmp91 = icmp eq i8 %48, 0 ; <i1> [#uses=1] + br i1 %phitmp91, label %bb3.i77, label %bb2.i51 + +bb2.i.i68: ; preds = %bb3.i77 + br i1 false, label %bb2.i51, label %bb2.i75 + +bb2.i75: ; preds = %bb2.i.i68 + br label %bb3.i77 + +bb3.i77: ; preds = %bb2.i75, %StringBeginsWith.exit88 + %sp.0.i76 = getelementptr [512 x i8]* %buff, i32 0, i32 undef ; <i8*> [#uses=1] + %49 = load i8* %sp.0.i76, align 1 ; <i8> [#uses=1] + %50 = icmp eq i8 %49, 0 ; <i1> [#uses=1] + br i1 %50, label %bb24, label %bb2.i.i68 + +bb24: ; preds = %bb3.i77 + %51 = call %struct.rec* @MakeWord(i32 11, i8* %41, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*)) nounwind ; <%struct.rec*> [#uses=0] + %52 = load i8* getelementptr ([150 x i8]* @zz_lengths, i32 0, i32 0), align 4 ; <i8> [#uses=1] + %53 = zext i8 %52 to i32 ; <i32> [#uses=2] + %54 = getelementptr [524 x %struct.rec*]* @zz_free, i32 0, i32 %53 ; <%struct.rec**> [#uses=2] + %55 = load %struct.rec** %54, align 4 ; <%struct.rec*> [#uses=3] + %56 = icmp eq %struct.rec* %55, null ; <i1> [#uses=1] + br i1 %56, label %bb27, label %bb28 + +bb27: ; preds = %bb24 + br i1 undef, label %bb.i56, label %GetMemory.exit62 + +bb.i56: ; preds = %bb27 + br i1 undef, label %bb1.i58, label %bb2.i60 + +bb1.i58: ; preds = %bb.i56 + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 31, i32 1, i8* getelementptr ([32 x i8]* @.str1575, i32 0, i32 0), i32 1, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*)) nounwind + br label %bb2.i60 + +bb2.i60: ; preds = %bb1.i58, %bb.i56 + %.pre1.i59 = phi i8** [ undef, %bb1.i58 ], [ undef, %bb.i56 ] ; <i8**> [#uses=1] + store i8** undef, i8*** @top_free.4773, align 4 + br label %GetMemory.exit62 + +GetMemory.exit62: ; preds = %bb2.i60, %bb27 + %57 = phi i8** [ %.pre1.i59, %bb2.i60 ], [ undef, %bb27 ] ; <i8**> [#uses=1] + %58 = getelementptr i8** %57, i32 %53 ; <i8**> [#uses=1] + store i8** %58, i8*** @next_free.4772, align 4 + store %struct.rec* undef, %struct.rec** @zz_hold, align 4 + br label %bb29 + +bb28: ; preds = %bb24 + store %struct.rec* %55, %struct.rec** @zz_hold, align 4 + %59 = load %struct.rec** null, align 4 ; <%struct.rec*> [#uses=1] + store %struct.rec* %59, %struct.rec** %54, align 4 + br label %bb29 + +bb29: ; preds = %bb28, %GetMemory.exit62 + %.pre184 = phi %struct.rec* [ %55, %bb28 ], [ undef, %GetMemory.exit62 ] ; <%struct.rec*> [#uses=3] + store i8 0, i8* undef + store %struct.rec* %.pre184, %struct.rec** @xx_link, align 4 + br i1 undef, label %bb35, label %bb31 + +bb31: ; preds = %bb29 + store %struct.rec* %.pre184, %struct.rec** undef + br label %bb35 + +bb35: ; preds = %bb31, %bb29 + br i1 undef, label %bb41, label %bb37 + +bb37: ; preds = %bb35 + %60 = load %struct.rec** null, align 4 ; <%struct.rec*> [#uses=1] + store %struct.rec* %60, %struct.rec** undef + store %struct.rec* undef, %struct.rec** null + store %struct.rec* %.pre184, %struct.rec** null, align 4 + br label %bb41 + +bb41: ; preds = %bb37, %bb35 + %61 = call i8* @fgets(i8* %buff14, i32 512, %struct.FILE* %12) nounwind ; <i8*> [#uses=1] + %62 = icmp eq i8* %61, null ; <i1> [#uses=1] + %iftmp.554.0 = select i1 %62, i32 2, i32 1 ; <i32> [#uses=1] + br label %bb100.outer + +bb.i47: ; preds = %bb3.i52 + %63 = icmp eq i8 %64, %65 ; <i1> [#uses=1] + br i1 %63, label %bb2.i51, label %bb2.i41 + +bb2.i51: ; preds = %bb.i47, %bb2.i.i68, %StringBeginsWith.exit88, %bb.i80 + %pp.0.i49 = getelementptr [17 x i8]* @.str1872951, i32 0, i32 0 ; <i8*> [#uses=1] + %64 = load i8* null, align 1 ; <i8> [#uses=1] + br i1 false, label %StringBeginsWith.exit55thread-split, label %bb3.i52 + +bb3.i52: ; preds = %bb2.i51 + %65 = load i8* %pp.0.i49, align 1 ; <i8> [#uses=1] + br i1 false, label %StringBeginsWith.exit55, label %bb.i47 + +StringBeginsWith.exit55thread-split: ; preds = %bb2.i51 + br label %StringBeginsWith.exit55 + +StringBeginsWith.exit55: ; preds = %StringBeginsWith.exit55thread-split, %bb3.i52 + br i1 false, label %bb49, label %bb2.i41 + +bb49: ; preds = %StringBeginsWith.exit55 + br label %bb2.i41 + +bb2.i41: ; preds = %bb2.i41, %bb49, %StringBeginsWith.exit55, %bb.i47 + br i1 false, label %bb2.i41, label %bb2.i.i15 + +bb2.i.i15: ; preds = %bb2.i41 + %pp.0.i.i13 = getelementptr [6 x i8]* @.str742838, i32 0, i32 0 ; <i8*> [#uses=1] + br i1 false, label %StringBeginsWith.exitthread-split.i18, label %bb3.i.i16 + +bb3.i.i16: ; preds = %bb2.i.i15 + %66 = load i8* %pp.0.i.i13, align 1 ; <i8> [#uses=1] + br label %StringBeginsWith.exit.i20 + +StringBeginsWith.exitthread-split.i18: ; preds = %bb2.i.i15 + br label %StringBeginsWith.exit.i20 + +StringBeginsWith.exit.i20: ; preds = %StringBeginsWith.exitthread-split.i18, %bb3.i.i16 + %67 = phi i8 [ undef, %StringBeginsWith.exitthread-split.i18 ], [ %66, %bb3.i.i16 ] ; <i8> [#uses=1] + %phitmp.i19 = icmp eq i8 %67, 0 ; <i1> [#uses=1] + br i1 %phitmp.i19, label %bb58, label %bb2.i6.i26 + +bb2.i6.i26: ; preds = %bb2.i6.i26, %StringBeginsWith.exit.i20 + %indvar.i3.i23 = phi i32 [ %indvar.next.i1.i21, %bb2.i6.i26 ], [ 0, %StringBeginsWith.exit.i20 ] ; <i32> [#uses=3] + %sp.0.i5.i25 = getelementptr [512 x i8]* %buff, i32 0, i32 %indvar.i3.i23 ; <i8*> [#uses=0] + %pp.0.i4.i24 = getelementptr [10 x i8]* @.str752839, i32 0, i32 %indvar.i3.i23 ; <i8*> [#uses=1] + %68 = load i8* %pp.0.i4.i24, align 1 ; <i8> [#uses=0] + %indvar.next.i1.i21 = add i32 %indvar.i3.i23, 1 ; <i32> [#uses=1] + br i1 undef, label %bb2.i6.i26, label %bb55 + +bb55: ; preds = %bb2.i6.i26 + %69 = call i32 @"\01_fputs"(i8* %buff14, %struct.FILE* undef) nounwind ; <i32> [#uses=0] + unreachable + +bb58: ; preds = %StringBeginsWith.exit.i20 + %70 = call i8* @fgets(i8* %buff14, i32 512, %struct.FILE* %12) nounwind ; <i8*> [#uses=0] + %iftmp.560.0 = select i1 undef, i32 2, i32 0 ; <i32> [#uses=1] + br label %bb100.outer + +bb.i7: ; preds = %bb3.i + br i1 false, label %bb2.i8, label %bb2.i.i + +bb2.i8: ; preds = %bb100.outer, %bb.i7 + br i1 undef, label %StringBeginsWith.exitthread-split, label %bb3.i + +bb3.i: ; preds = %bb2.i8 + br i1 undef, label %StringBeginsWith.exit, label %bb.i7 + +StringBeginsWith.exitthread-split: ; preds = %bb2.i8 + br label %StringBeginsWith.exit + +StringBeginsWith.exit: ; preds = %StringBeginsWith.exitthread-split, %bb3.i + %phitmp93 = icmp eq i8 undef, 0 ; <i1> [#uses=1] + br i1 %phitmp93, label %bb66, label %bb2.i.i + +bb66: ; preds = %StringBeginsWith.exit + %71 = call %struct.rec* @MakeWord(i32 11, i8* undef, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*)) nounwind ; <%struct.rec*> [#uses=4] + %72 = load i8* getelementptr ([150 x i8]* @zz_lengths, i32 0, i32 0), align 4 ; <i8> [#uses=1] + %73 = zext i8 %72 to i32 ; <i32> [#uses=2] + %74 = getelementptr [524 x %struct.rec*]* @zz_free, i32 0, i32 %73 ; <%struct.rec**> [#uses=2] + %75 = load %struct.rec** %74, align 4 ; <%struct.rec*> [#uses=3] + %76 = icmp eq %struct.rec* %75, null ; <i1> [#uses=1] + br i1 %76, label %bb69, label %bb70 + +bb69: ; preds = %bb66 + br i1 undef, label %bb.i2, label %GetMemory.exit + +bb.i2: ; preds = %bb69 + %77 = call noalias i8* @calloc(i32 1020, i32 4) nounwind ; <i8*> [#uses=1] + %78 = bitcast i8* %77 to i8** ; <i8**> [#uses=3] + store i8** %78, i8*** @next_free.4772, align 4 + br i1 undef, label %bb1.i3, label %bb2.i4 + +bb1.i3: ; preds = %bb.i2 + call void (i32, i32, i8*, i32, %struct.FILE_POS*, ...)* @Error(i32 31, i32 1, i8* getelementptr ([32 x i8]* @.str1575, i32 0, i32 0), i32 1, %struct.FILE_POS* bitcast (%4* @no_file_pos to %struct.FILE_POS*)) nounwind + br label %bb2.i4 + +bb2.i4: ; preds = %bb1.i3, %bb.i2 + %.pre1.i = phi i8** [ undef, %bb1.i3 ], [ %78, %bb.i2 ] ; <i8**> [#uses=1] + %79 = phi i8** [ undef, %bb1.i3 ], [ %78, %bb.i2 ] ; <i8**> [#uses=1] + %80 = getelementptr i8** %79, i32 1020 ; <i8**> [#uses=1] + store i8** %80, i8*** @top_free.4773, align 4 + br label %GetMemory.exit + +GetMemory.exit: ; preds = %bb2.i4, %bb69 + %81 = phi i8** [ %.pre1.i, %bb2.i4 ], [ undef, %bb69 ] ; <i8**> [#uses=2] + %82 = bitcast i8** %81 to %struct.rec* ; <%struct.rec*> [#uses=3] + %83 = getelementptr i8** %81, i32 %73 ; <i8**> [#uses=1] + store i8** %83, i8*** @next_free.4772, align 4 + store %struct.rec* %82, %struct.rec** @zz_hold, align 4 + br label %bb71 + +bb70: ; preds = %bb66 + %84 = load %struct.rec** null, align 4 ; <%struct.rec*> [#uses=1] + store %struct.rec* %84, %struct.rec** %74, align 4 + br label %bb71 + +bb71: ; preds = %bb70, %GetMemory.exit + %.pre185 = phi %struct.rec* [ %75, %bb70 ], [ %82, %GetMemory.exit ] ; <%struct.rec*> [#uses=8] + %85 = phi %struct.rec* [ %75, %bb70 ], [ %82, %GetMemory.exit ] ; <%struct.rec*> [#uses=1] + %86 = getelementptr %struct.rec* %85, i32 0, i32 0, i32 1, i32 0, i32 0 ; <i8*> [#uses=0] + %87 = getelementptr %struct.rec* %.pre185, i32 0, i32 0, i32 0, i32 1, i32 1 ; <%struct.rec**> [#uses=0] + %88 = getelementptr %struct.rec* %.pre185, i32 0, i32 0, i32 0, i32 1, i32 0 ; <%struct.rec**> [#uses=1] + store %struct.rec* %.pre185, %struct.rec** @xx_link, align 4 + store %struct.rec* %.pre185, %struct.rec** @zz_res, align 4 + %89 = load %struct.rec** @needs, align 4 ; <%struct.rec*> [#uses=2] + store %struct.rec* %89, %struct.rec** @zz_hold, align 4 + br i1 false, label %bb77, label %bb73 + +bb73: ; preds = %bb71 + %90 = getelementptr %struct.rec* %89, i32 0, i32 0, i32 0, i32 0, i32 0 ; <%struct.rec**> [#uses=1] + store %struct.rec* null, %struct.rec** @zz_tmp, align 4 + store %struct.rec* %.pre185, %struct.rec** %90 + store %struct.rec* %.pre185, %struct.rec** undef, align 4 + br label %bb77 + +bb77: ; preds = %bb73, %bb71 + store %struct.rec* %.pre185, %struct.rec** @zz_res, align 4 + store %struct.rec* %71, %struct.rec** @zz_hold, align 4 + br i1 undef, label %bb83, label %bb79 + +bb79: ; preds = %bb77 + %91 = getelementptr %struct.rec* %71, i32 0, i32 0, i32 0, i32 1, i32 0 ; <%struct.rec**> [#uses=1] + store %struct.rec* null, %struct.rec** @zz_tmp, align 4 + %92 = load %struct.rec** %88, align 4 ; <%struct.rec*> [#uses=1] + store %struct.rec* %92, %struct.rec** %91 + %93 = getelementptr %struct.rec* undef, i32 0, i32 0, i32 0, i32 1, i32 1 ; <%struct.rec**> [#uses=1] + store %struct.rec* %71, %struct.rec** %93, align 4 + store %struct.rec* %.pre185, %struct.rec** undef, align 4 + br label %bb83 + +bb83: ; preds = %bb79, %bb77 + br label %bb100.outer.outer + +bb.i.i: ; preds = %bb3.i.i + br i1 undef, label %bb2.i.i, label %bb2.i6.i + +bb2.i.i: ; preds = %bb.i.i, %StringBeginsWith.exit, %bb.i7 + br i1 undef, label %StringBeginsWith.exitthread-split.i, label %bb3.i.i + +bb3.i.i: ; preds = %bb2.i.i + br i1 undef, label %StringBeginsWith.exit.i, label %bb.i.i + +StringBeginsWith.exitthread-split.i: ; preds = %bb2.i.i + br label %StringBeginsWith.exit.i + +StringBeginsWith.exit.i: ; preds = %StringBeginsWith.exitthread-split.i, %bb3.i.i + br i1 false, label %bb94, label %bb2.i6.i + +bb.i2.i: ; preds = %bb3.i7.i + br i1 false, label %bb2.i6.i, label %bb91 + +bb2.i6.i: ; preds = %bb.i2.i, %StringBeginsWith.exit.i, %bb.i.i + br i1 undef, label %strip_out.exitthread-split, label %bb3.i7.i + +bb3.i7.i: ; preds = %bb2.i6.i + %94 = load i8* undef, align 1 ; <i8> [#uses=1] + br i1 undef, label %strip_out.exit, label %bb.i2.i + +strip_out.exitthread-split: ; preds = %bb2.i6.i + %.pr100 = load i8* undef ; <i8> [#uses=1] + br label %strip_out.exit + +strip_out.exit: ; preds = %strip_out.exitthread-split, %bb3.i7.i + %95 = phi i8 [ %.pr100, %strip_out.exitthread-split ], [ %94, %bb3.i7.i ] ; <i8> [#uses=0] + br i1 undef, label %bb94, label %bb91 + +bb91: ; preds = %strip_out.exit, %bb.i2.i + unreachable + +bb94: ; preds = %strip_out.exit, %StringBeginsWith.exit.i + %96 = call i8* @fgets(i8* %buff14, i32 512, %struct.FILE* %12) nounwind ; <i8*> [#uses=0] + unreachable + +bb100.outer: ; preds = %bb58, %bb41, %bb100.outer.outer + %state.0.ph = phi i32 [ %state.0.ph.ph, %bb100.outer.outer ], [ %iftmp.560.0, %bb58 ], [ %iftmp.554.0, %bb41 ] ; <i32> [#uses=1] + switch i32 %state.0.ph, label %bb2.i84 [ + i32 2, label %bb101.split + i32 1, label %bb2.i8 + ] + +bb101.split: ; preds = %bb100.outer + %97 = icmp eq i32 undef, 0 ; <i1> [#uses=1] + br i1 %97, label %bb103, label %bb102 + +bb102: ; preds = %bb101.split + %98 = call i32 @remove(i8* getelementptr ([9 x i8]* @.str19294, i32 0, i32 0)) nounwind ; <i32> [#uses=0] + unreachable + +bb103: ; preds = %bb101.split + %99 = load %struct.FILE** @out_fp, align 4 ; <%struct.FILE*> [#uses=1] + %100 = call i32 (%struct.FILE*, i8*, ...)* @fprintf(%struct.FILE* %99, i8* getelementptr ([26 x i8]* @.str1932957, i32 0, i32 0)) nounwind ; <i32> [#uses=0] + store i32 0, i32* @wordcount, align 4 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll new file mode 100644 index 0000000..779e100 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug.ll
@@ -0,0 +1,33 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | not grep fcpys +; rdar://7117307 + + %struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List } + %struct.List = type { %struct.List*, %struct.Patient*, %struct.List* } + %struct.Patient = type { i32, i32, i32, %struct.Village* } + %struct.Results = type { float, float, float } + %struct.Village = type { [4 x %struct.Village*], %struct.Village*, %struct.List, %struct.Hosp, i32, i32 } + +define void @get_results(%struct.Results* noalias nocapture sret %agg.result, %struct.Village* %village) nounwind { +entry: + br i1 undef, label %bb, label %bb6.preheader + +bb6.preheader: ; preds = %entry + call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* undef, i32 12, i32 4, i1 false) + br i1 undef, label %bb15, label %bb13 + +bb: ; preds = %entry + ret void + +bb13: ; preds = %bb13, %bb6.preheader + %0 = fadd float undef, undef ; <float> [#uses=1] + %1 = fadd float undef, 1.000000e+00 ; <float> [#uses=1] + br i1 undef, label %bb15, label %bb13 + +bb15: ; preds = %bb13, %bb6.preheader + %r1.0.0.lcssa = phi float [ 0.000000e+00, %bb6.preheader ], [ %1, %bb13 ] ; <float> [#uses=1] + %r1.1.0.lcssa = phi float [ undef, %bb6.preheader ], [ %0, %bb13 ] ; <float> [#uses=0] + store float %r1.0.0.lcssa, float* undef, align 4 + ret void +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug2.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug2.ll new file mode 100644 index 0000000..9d4fc31 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug2.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 +; rdar://7117307 + + %struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List } + %struct.List = type { %struct.List*, %struct.Patient*, %struct.List* } + %struct.Patient = type { i32, i32, i32, %struct.Village* } + %struct.Village = type { [4 x %struct.Village*], %struct.Village*, %struct.List, %struct.Hosp, i32, i32 } + +define %struct.List* @sim(%struct.Village* %village) nounwind { +entry: + br i1 undef, label %bb14, label %bb3.preheader + +bb3.preheader: ; preds = %entry + br label %bb5 + +bb5: ; preds = %bb5, %bb3.preheader + br i1 undef, label %bb11, label %bb5 + +bb11: ; preds = %bb5 + %0 = fmul float undef, 0x41E0000000000000 ; <float> [#uses=1] + %1 = fptosi float %0 to i32 ; <i32> [#uses=1] + store i32 %1, i32* undef, align 4 + br i1 undef, label %generate_patient.exit, label %generate_patient.exit.thread + +generate_patient.exit.thread: ; preds = %bb11 + ret %struct.List* null + +generate_patient.exit: ; preds = %bb11 + br i1 undef, label %bb14, label %bb12 + +bb12: ; preds = %generate_patient.exit + br i1 undef, label %bb.i, label %bb1.i + +bb.i: ; preds = %bb12 + ret %struct.List* null + +bb1.i: ; preds = %bb12 + ret %struct.List* null + +bb14: ; preds = %generate_patient.exit, %entry + ret %struct.List* undef +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug3.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug3.ll new file mode 100644 index 0000000..ad32dc9 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-04-SubregLoweringBug3.ll
@@ -0,0 +1,54 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 +; rdar://7117307 + + %struct.Hosp = type { i32, i32, i32, %struct.List, %struct.List, %struct.List, %struct.List } + %struct.List = type { %struct.List*, %struct.Patient*, %struct.List* } + %struct.Patient = type { i32, i32, i32, %struct.Village* } + %struct.Village = type { [4 x %struct.Village*], %struct.Village*, %struct.List, %struct.Hosp, i32, i32 } + +define %struct.List* @sim(%struct.Village* %village) nounwind { +entry: + br i1 undef, label %bb14, label %bb3.preheader + +bb3.preheader: ; preds = %entry + br label %bb5 + +bb5: ; preds = %bb5, %bb3.preheader + br i1 undef, label %bb11, label %bb5 + +bb11: ; preds = %bb5 + %0 = load i32* undef, align 4 ; <i32> [#uses=1] + %1 = xor i32 %0, 123459876 ; <i32> [#uses=1] + %2 = sdiv i32 %1, 127773 ; <i32> [#uses=1] + %3 = mul i32 %2, 2836 ; <i32> [#uses=1] + %4 = sub i32 0, %3 ; <i32> [#uses=1] + %5 = xor i32 %4, 123459876 ; <i32> [#uses=1] + %idum_addr.0.i.i = select i1 undef, i32 undef, i32 %5 ; <i32> [#uses=1] + %6 = sitofp i32 %idum_addr.0.i.i to double ; <double> [#uses=1] + %7 = fmul double %6, 0x3E00000000200000 ; <double> [#uses=1] + %8 = fptrunc double %7 to float ; <float> [#uses=2] + %9 = fmul float %8, 0x41E0000000000000 ; <float> [#uses=1] + %10 = fptosi float %9 to i32 ; <i32> [#uses=1] + store i32 %10, i32* undef, align 4 + %11 = fpext float %8 to double ; <double> [#uses=1] + %12 = fcmp ogt double %11, 6.660000e-01 ; <i1> [#uses=1] + br i1 %12, label %generate_patient.exit, label %generate_patient.exit.thread + +generate_patient.exit.thread: ; preds = %bb11 + ret %struct.List* null + +generate_patient.exit: ; preds = %bb11 + br i1 undef, label %bb14, label %bb12 + +bb12: ; preds = %generate_patient.exit + br i1 undef, label %bb.i, label %bb1.i + +bb.i: ; preds = %bb12 + ret %struct.List* null + +bb1.i: ; preds = %bb12 + ret %struct.List* null + +bb14: ; preds = %generate_patient.exit, %entry + ret %struct.List* undef +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll new file mode 100644 index 0000000..ff68e66 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-06-SpDecBug.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s +; PR4659 +; PR4682 + +define hidden i32 @__gcov_execlp(i8* %path, i8* %arg, ...) nounwind { +entry: +; CHECK: __gcov_execlp: +; CHECK: sub sp, #8 +; CHECK: push +; CHECK: add r7, sp, #4 +; CHECK: sub.w r4, r7, #4 +; CHECK: mov sp, r4 +; CHECK-NOT: mov sp, r7 +; CHECK: add sp, #8 + call void @__gcov_flush() nounwind + br i1 undef, label %bb5, label %bb + +bb: ; preds = %bb, %entry + br i1 undef, label %bb5, label %bb + +bb5: ; preds = %bb, %entry + %0 = alloca i8*, i32 undef, align 4 ; <i8**> [#uses=1] + %1 = call i32 @execvp(i8* %path, i8** %0) nounwind ; <i32> [#uses=1] + ret i32 %1 +} + +declare hidden void @__gcov_flush() + +declare i32 @execvp(i8*, i8**) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-07-CoalescerBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-07-CoalescerBug.ll new file mode 100644 index 0000000..93f5a0f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-07-CoalescerBug.ll
@@ -0,0 +1,16 @@ +; RUN: llc < %s -mtriple=armv7-eabi -mattr=+vfp2 +; PR4686 + + %a = type { i32 (...)** } + %b = type { %a } + %c = type { float, float, float, float } + +declare arm_aapcs_vfpcc float @bar(%c*) + +define arm_aapcs_vfpcc void @foo(%b* %x, %c* %y) { +entry: + %0 = call arm_aapcs_vfpcc float @bar(%c* %y) ; <float> [#uses=0] + %1 = fadd float undef, undef ; <float> [#uses=1] + store float %1, float* undef, align 8 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-07-NeonFPBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-07-NeonFPBug.ll new file mode 100644 index 0000000..f3baeb7 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-07-NeonFPBug.ll
@@ -0,0 +1,80 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -mcpu=cortex-a8 + + %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } + %struct.JHUFF_TBL = type { [17 x i8], [256 x i8], i32 } + %struct.JQUANT_TBL = type { [64 x i16], i32 } + %struct.__sFILEX = type opaque + %struct.__sbuf = type { i8*, i32 } + %struct.anon = type { [8 x i32], [48 x i8] } + %struct.backing_store_info = type { void (%struct.jpeg_common_struct*, %struct.backing_store_info*, i8*, i32, i32)*, void (%struct.jpeg_common_struct*, %struct.backing_store_info*, i8*, i32, i32)*, void (%struct.jpeg_common_struct*, %struct.backing_store_info*)*, %struct.FILE*, [64 x i8] } + %struct.jpeg_color_deconverter = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i8***, i32, i8**, i32)* } + %struct.jpeg_color_quantizer = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8**, i8**, i32)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)* } + %struct.jpeg_common_struct = type { %struct.jpeg_error_mgr*, %struct.jpeg_memory_mgr*, %struct.jpeg_progress_mgr*, i32, i32 } + %struct.jpeg_component_info = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.JQUANT_TBL*, i8* } + %struct.jpeg_d_coef_controller = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*, i8***)*, %struct.jvirt_barray_control** } + %struct.jpeg_d_main_controller = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8**, i32*, i32)* } + %struct.jpeg_d_post_controller = type { void (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*, i8***, i32*, i32, i8**, i32*, i32)* } + %struct.jpeg_decomp_master = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32 } + %struct.jpeg_decompress_struct = type { %struct.jpeg_error_mgr*, %struct.jpeg_memory_mgr*, %struct.jpeg_progress_mgr*, i32, i32, %struct.jpeg_source_mgr*, 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 %struct.JQUANT_TBL*], [4 x %struct.JHUFF_TBL*], [4 x %struct.JHUFF_TBL*], i32, %struct.jpeg_component_info*, i32, i32, [16 x i8], [16 x i8], [16 x i8], i32, i32, i8, i16, i16, i32, i8, i32, i32, i32, i32, i32, i8*, i32, [4 x %struct.jpeg_component_info*], i32, i32, i32, [10 x i32], i32, i32, i32, i32, i32, %struct.jpeg_decomp_master*, %struct.jpeg_d_main_controller*, %struct.jpeg_d_coef_controller*, %struct.jpeg_d_post_controller*, %struct.jpeg_input_controller*, %struct.jpeg_marker_reader*, %struct.jpeg_entropy_decoder*, %struct.jpeg_inverse_dct*, %struct.jpeg_upsampler*, %struct.jpeg_color_deconverter*, %struct.jpeg_color_quantizer* } + %struct.jpeg_entropy_decoder = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*, [64 x i16]**)* } + %struct.jpeg_error_mgr = type { void (%struct.jpeg_common_struct*)*, void (%struct.jpeg_common_struct*, i32)*, void (%struct.jpeg_common_struct*)*, void (%struct.jpeg_common_struct*, i8*)*, void (%struct.jpeg_common_struct*)*, i32, %struct.anon, i32, i32, i8**, i32, i8**, i32, i32 } + %struct.jpeg_input_controller = type { i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*)*, i32, i32 } + %struct.jpeg_inverse_dct = type { void (%struct.jpeg_decompress_struct*)*, [10 x void (%struct.jpeg_decompress_struct*, %struct.jpeg_component_info*, i16*, i8**, i32)*] } + %struct.jpeg_marker_reader = type { void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, [16 x i32 (%struct.jpeg_decompress_struct*)*], i32, i32, i32, i32 } + %struct.jpeg_memory_mgr = type { i8* (%struct.jpeg_common_struct*, i32, i32)*, i8* (%struct.jpeg_common_struct*, i32, i32)*, i8** (%struct.jpeg_common_struct*, i32, i32, i32)*, [64 x i16]** (%struct.jpeg_common_struct*, i32, i32, i32)*, %struct.jvirt_sarray_control* (%struct.jpeg_common_struct*, i32, i32, i32, i32, i32)*, %struct.jvirt_barray_control* (%struct.jpeg_common_struct*, i32, i32, i32, i32, i32)*, void (%struct.jpeg_common_struct*)*, i8** (%struct.jpeg_common_struct*, %struct.jvirt_sarray_control*, i32, i32, i32)*, [64 x i16]** (%struct.jpeg_common_struct*, %struct.jvirt_barray_control*, i32, i32, i32)*, void (%struct.jpeg_common_struct*, i32)*, void (%struct.jpeg_common_struct*)*, i32 } + %struct.jpeg_progress_mgr = type { void (%struct.jpeg_common_struct*)*, i32, i32, i32, i32 } + %struct.jpeg_source_mgr = type { i8*, i32, void (%struct.jpeg_decompress_struct*)*, i32 (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i32)*, i32 (%struct.jpeg_decompress_struct*, i32)*, void (%struct.jpeg_decompress_struct*)* } + %struct.jpeg_upsampler = type { void (%struct.jpeg_decompress_struct*)*, void (%struct.jpeg_decompress_struct*, i8***, i32*, i32, i8**, i32*, i32)*, i32 } + %struct.jvirt_barray_control = type { [64 x i16]**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.jvirt_barray_control*, %struct.backing_store_info } + %struct.jvirt_sarray_control = type { i8**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.jvirt_sarray_control*, %struct.backing_store_info } + +define void @jpeg_idct_float(%struct.jpeg_decompress_struct* nocapture %cinfo, %struct.jpeg_component_info* nocapture %compptr, i16* nocapture %coef_block, i8** nocapture %output_buf, i32 %output_col) nounwind { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %0 = load float* undef, align 4 ; <float> [#uses=1] + %1 = fmul float undef, %0 ; <float> [#uses=2] + %tmp73 = add i32 0, 224 ; <i32> [#uses=1] + %scevgep74 = getelementptr i8* null, i32 %tmp73 ; <i8*> [#uses=1] + %scevgep7475 = bitcast i8* %scevgep74 to float* ; <float*> [#uses=1] + %2 = load float* null, align 4 ; <float> [#uses=1] + %3 = fmul float 0.000000e+00, %2 ; <float> [#uses=2] + %4 = fadd float %1, %3 ; <float> [#uses=1] + %5 = fsub float %1, %3 ; <float> [#uses=2] + %6 = fadd float undef, 0.000000e+00 ; <float> [#uses=2] + %7 = fmul float undef, 0x3FF6A09E60000000 ; <float> [#uses=1] + %8 = fsub float %7, %6 ; <float> [#uses=2] + %9 = fsub float %4, %6 ; <float> [#uses=1] + %10 = fadd float %5, %8 ; <float> [#uses=2] + %11 = fsub float %5, %8 ; <float> [#uses=1] + %12 = sitofp i16 undef to float ; <float> [#uses=1] + %13 = fmul float %12, 0.000000e+00 ; <float> [#uses=2] + %14 = sitofp i16 undef to float ; <float> [#uses=1] + %15 = load float* %scevgep7475, align 4 ; <float> [#uses=1] + %16 = fmul float %14, %15 ; <float> [#uses=2] + %17 = fadd float undef, undef ; <float> [#uses=2] + %18 = fadd float %13, %16 ; <float> [#uses=2] + %19 = fsub float %13, %16 ; <float> [#uses=1] + %20 = fadd float %18, %17 ; <float> [#uses=2] + %21 = fsub float %18, %17 ; <float> [#uses=1] + %22 = fmul float %21, 0x3FF6A09E60000000 ; <float> [#uses=1] + %23 = fmul float undef, 0x3FFD906BC0000000 ; <float> [#uses=2] + %24 = fmul float %19, 0x3FF1517A80000000 ; <float> [#uses=1] + %25 = fsub float %24, %23 ; <float> [#uses=1] + %26 = fadd float undef, %23 ; <float> [#uses=1] + %27 = fsub float %26, %20 ; <float> [#uses=3] + %28 = fsub float %22, %27 ; <float> [#uses=2] + %29 = fadd float %25, %28 ; <float> [#uses=1] + %30 = fadd float undef, %20 ; <float> [#uses=1] + store float %30, float* undef, align 4 + %31 = fadd float %10, %27 ; <float> [#uses=1] + store float %31, float* undef, align 4 + %32 = fsub float %10, %27 ; <float> [#uses=1] + store float %32, float* undef, align 4 + %33 = fadd float %11, %28 ; <float> [#uses=1] + store float %33, float* undef, align 4 + %34 = fsub float %9, %29 ; <float> [#uses=1] + store float %34, float* undef, align 4 + br label %bb +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll new file mode 100644 index 0000000..e3c23ac --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-08-ScavengerAssert.ll
@@ -0,0 +1,20 @@ +; RUN: llc < %s -mtriple=armv7-eabi -mattr=+vfp2 +; PR4686 + +@g_d = external global double ; <double*> [#uses=1] + +define void @foo(float %yIncr) { +entry: + br i1 undef, label %bb, label %bb4 + +bb: ; preds = %entry + %0 = call arm_aapcs_vfpcc float @bar() ; <float> [#uses=1] + %1 = fpext float %0 to double ; <double> [#uses=1] + store double %1, double* @g_d, align 8 + br label %bb4 + +bb4: ; preds = %bb, %entry + unreachable +} + +declare arm_aapcs_vfpcc float @bar()
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-10-ISelBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-10-ISelBug.ll new file mode 100644 index 0000000..974ce50 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-10-ISelBug.ll
@@ -0,0 +1,15 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+vfp2 + +define float @t1(i32 %v0) nounwind { +entry: + store i32 undef, i32* undef, align 4 + %0 = load [4 x i8]** undef, align 4 ; <[4 x i8]*> [#uses=1] + %1 = load i8* undef, align 1 ; <i8> [#uses=1] + %2 = zext i8 %1 to i32 ; <i32> [#uses=1] + %3 = getelementptr [4 x i8]* %0, i32 %v0, i32 0 ; <i8*> [#uses=1] + %4 = load i8* %3, align 1 ; <i8> [#uses=1] + %5 = zext i8 %4 to i32 ; <i32> [#uses=1] + %6 = sub i32 %5, %2 ; <i32> [#uses=1] + %7 = sitofp i32 %6 to float ; <float> [#uses=1] + ret float %7 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-08-21-PostRAKill4.ll b/src/LLVM/test/CodeGen/Thumb2/2009-08-21-PostRAKill4.ll new file mode 100644 index 0000000..5cfc68d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-08-21-PostRAKill4.ll
@@ -0,0 +1,26 @@ +; RUN: llc < %s -asm-verbose=false -O3 -relocation-model=pic -disable-fp-elim -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -post-RA-scheduler + +; ModuleID = '<stdin>' +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 = "armv7-apple-darwin9" + +@.str = external constant [36 x i8], align 1 ; <[36 x i8]*> [#uses=0] +@.str1 = external constant [31 x i8], align 1 ; <[31 x i8]*> [#uses=1] +@.str2 = external constant [4 x i8], align 1 ; <[4 x i8]*> [#uses=1] + +declare i32 @getUnknown(i32, ...) nounwind + +declare void @llvm.va_start(i8*) nounwind + +declare void @llvm.va_end(i8*) nounwind + +declare i32 @printf(i8* nocapture, ...) nounwind + +define i32 @main() nounwind { +entry: + %0 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([31 x i8]* @.str1, i32 0, i32 0), i32 1, i32 1, i32 1, i32 1, i32 1, i32 1) nounwind ; <i32> [#uses=0] + %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([31 x i8]* @.str1, i32 0, i32 0), i32 -128, i32 116, i32 116, i32 -3852, i32 -31232, i32 -1708916736) nounwind ; <i32> [#uses=0] + %2 = tail call i32 (i32, ...)* @getUnknown(i32 undef, i32 116, i32 116, i32 -3852, i32 -31232, i32 30556, i32 -1708916736) nounwind ; <i32> [#uses=1] + %3 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str2, i32 0, i32 0), i32 %2) nounwind ; <i32> [#uses=0] + ret i32 0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-09-01-PostRAProlog.ll b/src/LLVM/test/CodeGen/Thumb2/2009-09-01-PostRAProlog.ll new file mode 100644 index 0000000..06a152d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-09-01-PostRAProlog.ll
@@ -0,0 +1,106 @@ +; RUN: llc -asm-verbose=false -O3 -relocation-model=pic -disable-fp-elim -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 < %s | 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:64:64-v128:128:128-a0:0:32" +target triple = "thumbv7-apple-darwin9" + +@history = internal global [2 x [56 x i32]] [[56 x i32] [i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 0, i32 1, i32 2, i32 4, i32 2, i32 1, i32 0, i32 -1, i32 1, i32 3, i32 5, i32 7, i32 5, i32 3, i32 1, i32 -1, i32 2, i32 5, i32 8, i32 10, i32 8, i32 5, i32 2, i32 -1, i32 2, i32 5, i32 8, i32 10, i32 8, i32 5, i32 2, i32 -1, i32 1, i32 3, i32 5, i32 7, i32 5, i32 3, i32 1, i32 -1, i32 0, i32 1, i32 2, i32 4, i32 2, i32 1, i32 0], [56 x i32] [i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 0, i32 1, i32 2, i32 4, i32 2, i32 1, i32 0, i32 -1, i32 1, i32 3, i32 5, i32 7, i32 5, i32 3, i32 1, i32 -1, i32 2, i32 5, i32 8, i32 10, i32 8, i32 5, i32 2, i32 -1, i32 2, i32 5, i32 8, i32 10, i32 8, i32 5, i32 2, i32 -1, i32 1, i32 3, i32 5, i32 7, i32 5, i32 3, i32 1, i32 -1, i32 0, i32 1, i32 2, i32 4, i32 2, i32 1, i32 0]] ; <[2 x [56 x i32]]*> [#uses=3] +@nodes = internal global i64 0 ; <i64*> [#uses=4] +@.str = private constant [9 x i8] c"##-<=>+#\00", align 1 ; <[9 x i8]*> [#uses=2] +@.str1 = private constant [6 x i8] c"%c%d\0A\00", align 1 ; <[6 x i8]*> [#uses=1] +@.str2 = private constant [16 x i8] c"Fhourstones 2.0\00", align 1 ; <[16 x i8]*> [#uses=1] +@.str3 = private constant [54 x i8] c"Using %d transposition table entries with %d probes.\0A\00", align 1 ; <[54 x i8]*> [#uses=1] +@.str4 = private constant [31 x i8] c"Solving %d-ply position after \00", align 1 ; <[31 x i8]*> [#uses=1] +@.str5 = private constant [7 x i8] c" . . .\00", align 1 ; <[7 x i8]*> [#uses=1] +@.str6 = private constant [28 x i8] c"score = %d (%c) work = %d\0A\00", align 1 ; <[28 x i8]*> [#uses=1] +@.str7 = private constant [36 x i8] c"%lu pos / %lu msec = %.1f Kpos/sec\0A\00", align 1 ; <[36 x i8]*> [#uses=1] +@plycnt = internal global i32 0 ; <i32*> [#uses=21] +@dias = internal global [19 x i32] zeroinitializer ; <[19 x i32]*> [#uses=43] +@columns = internal global [128 x i32] zeroinitializer ; <[128 x i32]*> [#uses=18] +@height = internal global [128 x i32] zeroinitializer ; <[128 x i32]*> [#uses=21] +@rows = internal global [8 x i32] zeroinitializer ; <[8 x i32]*> [#uses=20] +@colthr = internal global [128 x i32] zeroinitializer ; <[128 x i32]*> [#uses=5] +@moves = internal global [44 x i32] zeroinitializer ; <[44 x i32]*> [#uses=9] +@.str8 = private constant [3 x i8] c"%d\00", align 1 ; <[3 x i8]*> [#uses=1] +@he = internal global i8* null ; <i8**> [#uses=9] +@hits = internal global i64 0 ; <i64*> [#uses=8] +@posed = internal global i64 0 ; <i64*> [#uses=7] +@ht = internal global i32* null ; <i32**> [#uses=5] +@.str16 = private constant [19 x i8] c"store rate = %.3f\0A\00", align 1 ; <[19 x i8]*> [#uses=1] +@.str117 = private constant [45 x i8] c"- %5.3f < %5.3f = %5.3f > %5.3f + %5.3f\0A\00", align 1 ; <[45 x i8]*> [#uses=1] +@.str218 = private constant [6 x i8] c"%7d%c\00", align 1 ; <[6 x i8]*> [#uses=1] +@.str319 = private constant [30 x i8] c"Failed to allocate %u bytes.\0A\00", align 1 ; <[30 x i8]*> [#uses=1] + +declare i32 @puts(i8* nocapture) nounwind + +declare i32 @getchar() nounwind + +define internal i32 @transpose() nounwind readonly { +; CHECK: push +entry: + %0 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 1), align 4 ; <i32> [#uses=1] + %1 = shl i32 %0, 7 ; <i32> [#uses=1] + %2 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 2), align 4 ; <i32> [#uses=1] + %3 = or i32 %1, %2 ; <i32> [#uses=1] + %4 = shl i32 %3, 7 ; <i32> [#uses=1] + %5 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 3), align 4 ; <i32> [#uses=1] + %6 = or i32 %4, %5 ; <i32> [#uses=3] + %7 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 7), align 4 ; <i32> [#uses=1] + %8 = shl i32 %7, 7 ; <i32> [#uses=1] + %9 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 6), align 4 ; <i32> [#uses=1] + %10 = or i32 %8, %9 ; <i32> [#uses=1] + %11 = shl i32 %10, 7 ; <i32> [#uses=1] + %12 = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 5), align 4 ; <i32> [#uses=1] + %13 = or i32 %11, %12 ; <i32> [#uses=3] + %14 = icmp ugt i32 %6, %13 ; <i1> [#uses=2] + %.pn2.in.i = select i1 %14, i32 %6, i32 %13 ; <i32> [#uses=1] + %.pn1.in.i = select i1 %14, i32 %13, i32 %6 ; <i32> [#uses=1] + %.pn2.i = shl i32 %.pn2.in.i, 7 ; <i32> [#uses=1] + %.pn3.i = load i32* getelementptr inbounds ([128 x i32]* @columns, i32 0, i32 4) ; <i32> [#uses=1] + %.pn.in.in.i = or i32 %.pn2.i, %.pn3.i ; <i32> [#uses=1] + %.pn.in.i = zext i32 %.pn.in.in.i to i64 ; <i64> [#uses=1] + %.pn.i = shl i64 %.pn.in.i, 21 ; <i64> [#uses=1] + %.pn1.i = zext i32 %.pn1.in.i to i64 ; <i64> [#uses=1] + %iftmp.22.0.i = or i64 %.pn.i, %.pn1.i ; <i64> [#uses=2] + %15 = lshr i64 %iftmp.22.0.i, 17 ; <i64> [#uses=1] + %16 = trunc i64 %15 to i32 ; <i32> [#uses=2] + %17 = urem i64 %iftmp.22.0.i, 1050011 ; <i64> [#uses=1] + %18 = trunc i64 %17 to i32 ; <i32> [#uses=1] + %19 = urem i32 %16, 179 ; <i32> [#uses=1] + %20 = or i32 %19, 131072 ; <i32> [#uses=1] + %21 = load i32** @ht, align 4 ; <i32*> [#uses=1] + br label %bb5 + +bb: ; preds = %bb5 + %22 = getelementptr inbounds i32* %21, i32 %x.0 ; <i32*> [#uses=1] + %23 = load i32* %22, align 4 ; <i32> [#uses=1] + %24 = icmp eq i32 %23, %16 ; <i1> [#uses=1] + br i1 %24, label %bb1, label %bb2 + +bb1: ; preds = %bb + %25 = load i8** @he, align 4 ; <i8*> [#uses=1] + %26 = getelementptr inbounds i8* %25, i32 %x.0 ; <i8*> [#uses=1] + %27 = load i8* %26, align 1 ; <i8> [#uses=1] + %28 = sext i8 %27 to i32 ; <i32> [#uses=1] + ret i32 %28 + +bb2: ; preds = %bb + %29 = add nsw i32 %20, %x.0 ; <i32> [#uses=3] + %30 = add i32 %29, -1050011 ; <i32> [#uses=1] + %31 = icmp sgt i32 %29, 1050010 ; <i1> [#uses=1] + %. = select i1 %31, i32 %30, i32 %29 ; <i32> [#uses=1] + %32 = add i32 %33, 1 ; <i32> [#uses=1] + br label %bb5 + +bb5: ; preds = %bb2, %entry + %33 = phi i32 [ 0, %entry ], [ %32, %bb2 ] ; <i32> [#uses=2] + %x.0 = phi i32 [ %18, %entry ], [ %., %bb2 ] ; <i32> [#uses=3] + %34 = icmp sgt i32 %33, 7 ; <i1> [#uses=1] + br i1 %34, label %bb7, label %bb + +bb7: ; preds = %bb5 + ret i32 -128 +} + +declare noalias i8* @calloc(i32, i32) nounwind + +declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-09-28-ITBlockBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-09-28-ITBlockBug.ll new file mode 100644 index 0000000..ac3e80a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-09-28-ITBlockBug.ll
@@ -0,0 +1,152 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -disable-cgp-branch-opts | FileCheck %s + +%struct.pix_pos = type { i32, i32, i32, i32, i32, i32 } + +@getNeighbour = external global void (i32, i32, i32, i32, %struct.pix_pos*)*, align 4 ; <void (i32, i32, i32, i32, %struct.pix_pos*)**> [#uses=2] + +define void @t() nounwind { +; CHECK: t: +; CHECK: it eq +; CHECK-NEXT: cmpeq +entry: + %pix_a.i294 = alloca [4 x %struct.pix_pos], align 4 ; <[4 x %struct.pix_pos]*> [#uses=2] + br i1 undef, label %land.rhs, label %lor.end + +land.rhs: ; preds = %entry + br label %lor.end + +lor.end: ; preds = %land.rhs, %entry + switch i32 0, label %if.end371 [ + i32 10, label %if.then366 + i32 14, label %if.then366 + ] + +if.then366: ; preds = %lor.end, %lor.end + unreachable + +if.end371: ; preds = %lor.end + %arrayidx56.2.i = getelementptr [4 x %struct.pix_pos]* %pix_a.i294, i32 0, i32 2 ; <%struct.pix_pos*> [#uses=1] + %arrayidx56.3.i = getelementptr [4 x %struct.pix_pos]* %pix_a.i294, i32 0, i32 3 ; <%struct.pix_pos*> [#uses=1] + br i1 undef, label %for.body1857, label %for.end4557 + +for.body1857: ; preds = %if.end371 + br i1 undef, label %if.then1867, label %for.cond1933 + +if.then1867: ; preds = %for.body1857 + unreachable + +for.cond1933: ; preds = %for.body1857 + br i1 undef, label %for.body1940, label %if.then4493 + +for.body1940: ; preds = %for.cond1933 + %shl = shl i32 undef, 2 ; <i32> [#uses=1] + %shl1959 = shl i32 undef, 2 ; <i32> [#uses=4] + br i1 undef, label %if.then1992, label %if.else2003 + +if.then1992: ; preds = %for.body1940 + %tmp14.i302 = load i32* undef ; <i32> [#uses=4] + %add.i307452 = or i32 %shl1959, 1 ; <i32> [#uses=1] + %sub.i308 = add i32 %shl, -1 ; <i32> [#uses=4] + call void undef(i32 %tmp14.i302, i32 %sub.i308, i32 %shl1959, i32 0, %struct.pix_pos* undef) nounwind + %tmp49.i309 = load void (i32, i32, i32, i32, %struct.pix_pos*)** @getNeighbour ; <void (i32, i32, i32, i32, %struct.pix_pos*)*> [#uses=1] + call void %tmp49.i309(i32 %tmp14.i302, i32 %sub.i308, i32 %add.i307452, i32 0, %struct.pix_pos* null) nounwind + %tmp49.1.i = load void (i32, i32, i32, i32, %struct.pix_pos*)** @getNeighbour ; <void (i32, i32, i32, i32, %struct.pix_pos*)*> [#uses=1] + call void %tmp49.1.i(i32 %tmp14.i302, i32 %sub.i308, i32 undef, i32 0, %struct.pix_pos* %arrayidx56.2.i) nounwind + call void undef(i32 %tmp14.i302, i32 %sub.i308, i32 undef, i32 0, %struct.pix_pos* %arrayidx56.3.i) nounwind + unreachable + +if.else2003: ; preds = %for.body1940 + switch i32 undef, label %if.then2015 [ + i32 10, label %if.then4382 + i32 14, label %if.then4382 + ] + +if.then2015: ; preds = %if.else2003 + br i1 undef, label %if.else2298, label %if.then2019 + +if.then2019: ; preds = %if.then2015 + br i1 undef, label %if.then2065, label %if.else2081 + +if.then2065: ; preds = %if.then2019 + br label %if.end2128 + +if.else2081: ; preds = %if.then2019 + br label %if.end2128 + +if.end2128: ; preds = %if.else2081, %if.then2065 + unreachable + +if.else2298: ; preds = %if.then2015 + br i1 undef, label %land.lhs.true2813, label %cond.end2841 + +land.lhs.true2813: ; preds = %if.else2298 + br i1 undef, label %cond.end2841, label %cond.true2824 + +cond.true2824: ; preds = %land.lhs.true2813 + br label %cond.end2841 + +cond.end2841: ; preds = %cond.true2824, %land.lhs.true2813, %if.else2298 + br i1 undef, label %for.cond2882.preheader, label %for.cond2940.preheader + +for.cond2882.preheader: ; preds = %cond.end2841 + %mul3693 = shl i32 undef, 1 ; <i32> [#uses=2] + br i1 undef, label %if.then3689, label %if.else3728 + +for.cond2940.preheader: ; preds = %cond.end2841 + br label %for.inc3040 + +for.inc3040: ; preds = %for.inc3040, %for.cond2940.preheader + br label %for.inc3040 + +if.then3689: ; preds = %for.cond2882.preheader + %add3695 = add nsw i32 %mul3693, %shl1959 ; <i32> [#uses=1] + %mul3697 = shl i32 %add3695, 2 ; <i32> [#uses=2] + %arrayidx3705 = getelementptr inbounds i16* undef, i32 1 ; <i16*> [#uses=1] + %tmp3706 = load i16* %arrayidx3705 ; <i16> [#uses=1] + %conv3707 = sext i16 %tmp3706 to i32 ; <i32> [#uses=1] + %add3708 = add nsw i32 %conv3707, %mul3697 ; <i32> [#uses=1] + %arrayidx3724 = getelementptr inbounds i16* null, i32 1 ; <i16*> [#uses=1] + %tmp3725 = load i16* %arrayidx3724 ; <i16> [#uses=1] + %conv3726 = sext i16 %tmp3725 to i32 ; <i32> [#uses=1] + %add3727 = add nsw i32 %conv3726, %mul3697 ; <i32> [#uses=1] + br label %if.end3770 + +if.else3728: ; preds = %for.cond2882.preheader + %mul3733 = add i32 %shl1959, 1073741816 ; <i32> [#uses=1] + %add3735 = add nsw i32 %mul3733, %mul3693 ; <i32> [#uses=1] + %mul3737 = shl i32 %add3735, 2 ; <i32> [#uses=2] + %tmp3746 = load i16* undef ; <i16> [#uses=1] + %conv3747 = sext i16 %tmp3746 to i32 ; <i32> [#uses=1] + %add3748 = add nsw i32 %conv3747, %mul3737 ; <i32> [#uses=1] + %arrayidx3765 = getelementptr inbounds i16* null, i32 1 ; <i16*> [#uses=1] + %tmp3766 = load i16* %arrayidx3765 ; <i16> [#uses=1] + %conv3767 = sext i16 %tmp3766 to i32 ; <i32> [#uses=1] + %add3768 = add nsw i32 %conv3767, %mul3737 ; <i32> [#uses=1] + br label %if.end3770 + +if.end3770: ; preds = %if.else3728, %if.then3689 + %vec2_y.1 = phi i32 [ %add3727, %if.then3689 ], [ %add3768, %if.else3728 ] ; <i32> [#uses=0] + %vec1_y.2 = phi i32 [ %add3708, %if.then3689 ], [ %add3748, %if.else3728 ] ; <i32> [#uses=0] + unreachable + +if.then4382: ; preds = %if.else2003, %if.else2003 + switch i32 undef, label %if.then4394 [ + i32 10, label %if.else4400 + i32 14, label %if.else4400 + ] + +if.then4394: ; preds = %if.then4382 + unreachable + +if.else4400: ; preds = %if.then4382, %if.then4382 + br label %for.cond4451.preheader + +for.cond4451.preheader: ; preds = %for.cond4451.preheader, %if.else4400 + br label %for.cond4451.preheader + +if.then4493: ; preds = %for.cond1933 + unreachable + +for.end4557: ; preds = %if.end371 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll b/src/LLVM/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll new file mode 100644 index 0000000..18c2e0b --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-10-15-ITBlockBranch.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 -float-abi=hard | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 -float-abi=hard -regalloc=basic | FileCheck %s +; PR5204 + +%"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" = type { i8* } +%"struct.__gnu_cxx::new_allocator<char>" = type <{ i8 }> +%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >" = type { %"struct.__gnu_cxx::__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >" } +%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep" = type { %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" } +%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Rep_base" = type { i32, i32, i32 } + + +define weak arm_aapcs_vfpcc i32 @_ZNKSs7compareERKSs(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this, %"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) { +; CHECK: _ZNKSs7compareERKSs: +; CHECK: it eq +; CHECK-NEXT: subeq{{(.w)?}} r0, r{{[0-9]+}}, r{{[0-9]+}} +; CHECK-NEXT: pop.w +entry: + %0 = tail call arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) ; <i32> [#uses=3] + %1 = tail call arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) ; <i32> [#uses=3] + %2 = icmp ult i32 %1, %0 ; <i1> [#uses=1] + %3 = select i1 %2, i32 %1, i32 %0 ; <i32> [#uses=1] + %4 = tail call arm_aapcs_vfpcc i8* @_ZNKSs7_M_dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) ; <i8*> [#uses=1] + %5 = tail call arm_aapcs_vfpcc i8* @_ZNKSs4dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %__str) ; <i8*> [#uses=1] + %6 = tail call arm_aapcs_vfpcc i32 @memcmp(i8* %4, i8* %5, i32 %3) nounwind readonly ; <i32> [#uses=2] + %7 = icmp eq i32 %6, 0 ; <i1> [#uses=1] + br i1 %7, label %bb, label %bb1 + +bb: ; preds = %entry + %8 = sub i32 %0, %1 ; <i32> [#uses=1] + ret i32 %8 + +bb1: ; preds = %entry + ret i32 %6 +} + +declare arm_aapcs_vfpcc i32 @memcmp(i8* nocapture, i8* nocapture, i32) nounwind readonly + +declare arm_aapcs_vfpcc i32 @_ZNKSs4sizeEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) + +declare arm_aapcs_vfpcc i8* @_ZNKSs7_M_dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this) + +declare arm_aapcs_vfpcc i8* @_ZNKSs4dataEv(%"struct.std::basic_string<char,std::char_traits<char>,std::allocator<char> >"* %this)
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll new file mode 100644 index 0000000..4588018 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-11-01-CopyReg2RegBug.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 + +define void @get_initial_mb16x16_cost() nounwind { +entry: + br i1 undef, label %bb4, label %bb1 + +bb1: ; preds = %entry + br label %bb7 + +bb4: ; preds = %entry + br i1 undef, label %bb7.thread, label %bb5 + +bb5: ; preds = %bb4 + br label %bb7 + +bb7.thread: ; preds = %bb4 + br label %bb8 + +bb7: ; preds = %bb5, %bb1 + br i1 undef, label %bb8, label %bb10 + +bb8: ; preds = %bb7, %bb7.thread + %0 = phi double [ 5.120000e+02, %bb7.thread ], [ undef, %bb7 ] ; <double> [#uses=1] + %1 = fdiv double %0, undef ; <double> [#uses=0] + unreachable + +bb10: ; preds = %bb7 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-11-11-ScavengerAssert.ll b/src/LLVM/test/CodeGen/Thumb2/2009-11-11-ScavengerAssert.ll new file mode 100644 index 0000000..956263b --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-11-11-ScavengerAssert.ll
@@ -0,0 +1,85 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 + +%struct.OP = type { %struct.OP*, %struct.OP*, %struct.OP* ()*, i32, i16, i16, i8, i8 } +%struct.SV = type { i8*, i32, i32 } + +declare void @Perl_mg_set(%struct.SV*) nounwind + +define %struct.OP* @Perl_pp_complement() nounwind { +entry: + %0 = load %struct.SV** null, align 4 ; <%struct.SV*> [#uses=2] + br i1 undef, label %bb21, label %bb5 + +bb5: ; preds = %entry + br i1 undef, label %bb13, label %bb6 + +bb6: ; preds = %bb5 + br i1 undef, label %bb8, label %bb7 + +bb7: ; preds = %bb6 + %1 = getelementptr inbounds %struct.SV* %0, i32 0, i32 0 ; <i8**> [#uses=1] + %2 = load i8** %1, align 4 ; <i8*> [#uses=1] + %3 = getelementptr inbounds i8* %2, i32 12 ; <i8*> [#uses=1] + %4 = bitcast i8* %3 to i32* ; <i32*> [#uses=1] + %5 = load i32* %4, align 4 ; <i32> [#uses=1] + %storemerge5 = xor i32 %5, -1 ; <i32> [#uses=1] + call void @Perl_sv_setiv(%struct.SV* undef, i32 %storemerge5) nounwind + %6 = getelementptr inbounds %struct.SV* undef, i32 0, i32 2 ; <i32*> [#uses=1] + %7 = load i32* %6, align 4 ; <i32> [#uses=1] + %8 = and i32 %7, 16384 ; <i32> [#uses=1] + %9 = icmp eq i32 %8, 0 ; <i1> [#uses=1] + br i1 %9, label %bb12, label %bb11 + +bb8: ; preds = %bb6 + unreachable + +bb11: ; preds = %bb7 + call void @Perl_mg_set(%struct.SV* undef) nounwind + br label %bb12 + +bb12: ; preds = %bb11, %bb7 + store %struct.SV* undef, %struct.SV** null, align 4 + br label %bb44 + +bb13: ; preds = %bb5 + %10 = call i32 @Perl_sv_2uv(%struct.SV* %0) nounwind ; <i32> [#uses=0] + br i1 undef, label %bb.i, label %bb1.i + +bb.i: ; preds = %bb13 + call void @Perl_sv_setiv(%struct.SV* undef, i32 undef) nounwind + br label %Perl_sv_setuv.exit + +bb1.i: ; preds = %bb13 + br label %Perl_sv_setuv.exit + +Perl_sv_setuv.exit: ; preds = %bb1.i, %bb.i + %11 = getelementptr inbounds %struct.SV* undef, i32 0, i32 2 ; <i32*> [#uses=1] + %12 = load i32* %11, align 4 ; <i32> [#uses=1] + %13 = and i32 %12, 16384 ; <i32> [#uses=1] + %14 = icmp eq i32 %13, 0 ; <i1> [#uses=1] + br i1 %14, label %bb20, label %bb19 + +bb19: ; preds = %Perl_sv_setuv.exit + call void @Perl_mg_set(%struct.SV* undef) nounwind + br label %bb20 + +bb20: ; preds = %bb19, %Perl_sv_setuv.exit + store %struct.SV* undef, %struct.SV** null, align 4 + br label %bb44 + +bb21: ; preds = %entry + br i1 undef, label %bb23, label %bb22 + +bb22: ; preds = %bb21 + unreachable + +bb23: ; preds = %bb21 + unreachable + +bb44: ; preds = %bb20, %bb12 + ret %struct.OP* undef +} + +declare void @Perl_sv_setiv(%struct.SV*, i32) nounwind + +declare i32 @Perl_sv_2uv(%struct.SV*) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-11-13-STRDBug.ll b/src/LLVM/test/CodeGen/Thumb2/2009-11-13-STRDBug.ll new file mode 100644 index 0000000..0c9fa5e --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-11-13-STRDBug.ll
@@ -0,0 +1,20 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 +; rdar://7394794 + +define void @lshift_double(i64 %l1, i64 %h1, i64 %count, i32 %prec, i64* nocapture %lv, i64* nocapture %hv, i32 %arith) nounwind { +entry: + %..i = select i1 false, i64 0, i64 0 ; <i64> [#uses=1] + br i1 undef, label %bb11.i, label %bb6.i + +bb6.i: ; preds = %entry + %0 = lshr i64 %h1, 0 ; <i64> [#uses=1] + store i64 %0, i64* %hv, align 4 + %1 = lshr i64 %l1, 0 ; <i64> [#uses=1] + %2 = or i64 0, %1 ; <i64> [#uses=1] + store i64 %2, i64* %lv, align 4 + br label %bb11.i + +bb11.i: ; preds = %bb6.i, %entry + store i64 %..i, i64* %lv, align 4 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2009-12-01-LoopIVUsers.ll b/src/LLVM/test/CodeGen/Thumb2/2009-12-01-LoopIVUsers.ll new file mode 100644 index 0000000..034a28f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2009-12-01-LoopIVUsers.ll
@@ -0,0 +1,128 @@ +; RUN: opt < %s -std-compile-opts | \ +; RUN: llc -mtriple=thumbv7-apple-darwin10 -mattr=+neon | FileCheck %s + +define void @fred(i32 %three_by_three, i8* %in, double %dt1, i32 %x_size, i32 %y_size, i8* %bp) nounwind { +entry: +; -- The loop following the load should only use a single add-literation +; instruction. +; CHECK: ldr.64 +; CHECK: adds r{{[0-9]+.*}}#1 +; CHECK-NOT: adds +; CHECK: subsections_via_symbols + + + %three_by_three_addr = alloca i32 ; <i32*> [#uses=2] + %in_addr = alloca i8* ; <i8**> [#uses=2] + %dt_addr = alloca float ; <float*> [#uses=4] + %x_size_addr = alloca i32 ; <i32*> [#uses=2] + %y_size_addr = alloca i32 ; <i32*> [#uses=1] + %bp_addr = alloca i8* ; <i8**> [#uses=1] + %tmp_image = alloca i8* ; <i8**> [#uses=0] + %out = alloca i8* ; <i8**> [#uses=1] + %cp = alloca i8* ; <i8**> [#uses=0] + %dpt = alloca i8* ; <i8**> [#uses=4] + %dp = alloca i8* ; <i8**> [#uses=2] + %ip = alloca i8* ; <i8**> [#uses=0] + %centre = alloca i32 ; <i32*> [#uses=0] + %tmp = alloca i32 ; <i32*> [#uses=0] + %brightness = alloca i32 ; <i32*> [#uses=0] + %area = alloca i32 ; <i32*> [#uses=0] + %y = alloca i32 ; <i32*> [#uses=0] + %x = alloca i32 ; <i32*> [#uses=2] + %j = alloca i32 ; <i32*> [#uses=6] + %i = alloca i32 ; <i32*> [#uses=1] + %mask_size = alloca i32 ; <i32*> [#uses=5] + %increment = alloca i32 ; <i32*> [#uses=1] + %n_max = alloca i32 ; <i32*> [#uses=4] + %temp = alloca float ; <float*> [#uses=1] + %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] + store i32 %three_by_three, i32* %three_by_three_addr + store i8* %in, i8** %in_addr + %dt = fptrunc double %dt1 to float ; <float> [#uses=1] + store float %dt, float* %dt_addr + store i32 %x_size, i32* %x_size_addr + store i32 %y_size, i32* %y_size_addr + store i8* %bp, i8** %bp_addr + %0 = load i8** %in_addr, align 4 ; <i8*> [#uses=1] + store i8* %0, i8** %out, align 4 + %1 = call i32 (...)* @foo() nounwind ; <i32> [#uses=1] + store i32 %1, i32* %i, align 4 + %2 = load i32* %three_by_three_addr, align 4 ; <i32> [#uses=1] + %3 = icmp eq i32 %2, 0 ; <i1> [#uses=1] + br i1 %3, label %bb, label %bb2 + +bb: ; preds = %entry + %4 = load float* %dt_addr, align 4 ; <float> [#uses=1] + %5 = fpext float %4 to double ; <double> [#uses=1] + %6 = fmul double %5, 1.500000e+00 ; <double> [#uses=1] + %7 = fptosi double %6 to i32 ; <i32> [#uses=1] + %8 = add nsw i32 %7, 1 ; <i32> [#uses=1] + store i32 %8, i32* %mask_size, align 4 + br label %bb3 + +bb2: ; preds = %entry + store i32 1, i32* %mask_size, align 4 + br label %bb3 + +bb3: ; preds = %bb2, %bb + %9 = load i32* %mask_size, align 4 ; <i32> [#uses=1] + %10 = mul i32 %9, 2 ; <i32> [#uses=1] + %11 = add nsw i32 %10, 1 ; <i32> [#uses=1] + store i32 %11, i32* %n_max, align 4 + %12 = load i32* %x_size_addr, align 4 ; <i32> [#uses=1] + %13 = load i32* %n_max, align 4 ; <i32> [#uses=1] + %14 = sub i32 %12, %13 ; <i32> [#uses=1] + store i32 %14, i32* %increment, align 4 + %15 = load i32* %n_max, align 4 ; <i32> [#uses=1] + %16 = load i32* %n_max, align 4 ; <i32> [#uses=1] + %17 = mul i32 %15, %16 ; <i32> [#uses=1] + %18 = call noalias i8* @malloc(i32 %17) nounwind ; <i8*> [#uses=1] + store i8* %18, i8** %dp, align 4 + %19 = load i8** %dp, align 4 ; <i8*> [#uses=1] + store i8* %19, i8** %dpt, align 4 + %20 = load float* %dt_addr, align 4 ; <float> [#uses=1] + %21 = load float* %dt_addr, align 4 ; <float> [#uses=1] + %22 = fmul float %20, %21 ; <float> [#uses=1] + %23 = fsub float -0.000000e+00, %22 ; <float> [#uses=1] + store float %23, float* %temp, align 4 + %24 = load i32* %mask_size, align 4 ; <i32> [#uses=1] + %25 = sub i32 0, %24 ; <i32> [#uses=1] + store i32 %25, i32* %j, align 4 + br label %bb5 + +bb4: ; preds = %bb5 + %26 = load i32* %j, align 4 ; <i32> [#uses=1] + %27 = load i32* %j, align 4 ; <i32> [#uses=1] + %28 = mul i32 %26, %27 ; <i32> [#uses=1] + %29 = sitofp i32 %28 to double ; <double> [#uses=1] + %30 = fmul double %29, 1.234000e+00 ; <double> [#uses=1] + %31 = fptosi double %30 to i32 ; <i32> [#uses=1] + store i32 %31, i32* %x, align 4 + %32 = load i32* %x, align 4 ; <i32> [#uses=1] + %33 = trunc i32 %32 to i8 ; <i8> [#uses=1] + %34 = load i8** %dpt, align 4 ; <i8*> [#uses=1] + store i8 %33, i8* %34, align 1 + %35 = load i8** %dpt, align 4 ; <i8*> [#uses=1] + %36 = getelementptr inbounds i8* %35, i64 1 ; <i8*> [#uses=1] + store i8* %36, i8** %dpt, align 4 + %37 = load i32* %j, align 4 ; <i32> [#uses=1] + %38 = add nsw i32 %37, 1 ; <i32> [#uses=1] + store i32 %38, i32* %j, align 4 + br label %bb5 + +bb5: ; preds = %bb4, %bb3 + %39 = load i32* %j, align 4 ; <i32> [#uses=1] + %40 = load i32* %mask_size, align 4 ; <i32> [#uses=1] + %41 = icmp sle i32 %39, %40 ; <i1> [#uses=1] + br i1 %41, label %bb4, label %bb6 + +bb6: ; preds = %bb5 + br label %return + +return: ; preds = %bb6 + ret void +} + +declare i32 @foo(...) + +declare noalias i8* @malloc(i32) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll b/src/LLVM/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll new file mode 100644 index 0000000..af7d716 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-01-06-TailDuplicateLabels.ll
@@ -0,0 +1,89 @@ +; RUN: llc -relocation-model=pic < %s | grep {:$} | sort | uniq -d | count 0 +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" +target triple = "thumbv7-apple-darwin10" + +; This function produces a duplicate LPC label unless special care is taken when duplicating a t2LDRpci_pic instruction. + +%struct.PlatformMutex = type { i32, [40 x i8] } +%struct.SpinLock = type { %struct.PlatformMutex } +%"struct.WTF::TCMalloc_ThreadCache" = type { i32, %struct._opaque_pthread_t*, i8, [68 x %"struct.WTF::TCMalloc_ThreadCache_FreeList"], i32, i32, %"struct.WTF::TCMalloc_ThreadCache"*, %"struct.WTF::TCMalloc_ThreadCache"* } +%"struct.WTF::TCMalloc_ThreadCache_FreeList" = type { i8*, i16, i16 } +%struct.__darwin_pthread_handler_rec = type { void (i8*)*, i8*, %struct.__darwin_pthread_handler_rec* } +%struct._opaque_pthread_t = type { i32, %struct.__darwin_pthread_handler_rec*, [596 x i8] } + +@_ZN3WTFL8heap_keyE = internal global i32 0 ; <i32*> [#uses=1] +@_ZN3WTFL10tsd_initedE.b = internal global i1 false ; <i1*> [#uses=2] +@_ZN3WTFL13pageheap_lockE = internal global %struct.SpinLock { %struct.PlatformMutex { i32 850045863, [40 x i8] zeroinitializer } } ; <%struct.SpinLock*> [#uses=1] +@_ZN3WTFL12thread_heapsE = internal global %"struct.WTF::TCMalloc_ThreadCache"* null ; <%"struct.WTF::TCMalloc_ThreadCache"**> [#uses=1] +@llvm.used = appending global [1 x i8*] [i8* bitcast (%"struct.WTF::TCMalloc_ThreadCache"* ()* @_ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define %"struct.WTF::TCMalloc_ThreadCache"* @_ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv() nounwind { +entry: + %0 = tail call i32 @pthread_mutex_lock(%struct.PlatformMutex* getelementptr inbounds (%struct.SpinLock* @_ZN3WTFL13pageheap_lockE, i32 0, i32 0)) nounwind + %.b24 = load i1* @_ZN3WTFL10tsd_initedE.b, align 4 ; <i1> [#uses=1] + br i1 %.b24, label %bb5, label %bb6 + +bb5: ; preds = %entry + %1 = tail call %struct._opaque_pthread_t* @pthread_self() nounwind + br label %bb6 + +bb6: ; preds = %bb5, %entry + %me.0 = phi %struct._opaque_pthread_t* [ %1, %bb5 ], [ null, %entry ] ; <%struct._opaque_pthread_t*> [#uses=2] + br label %bb11 + +bb7: ; preds = %bb11 + %2 = getelementptr inbounds %"struct.WTF::TCMalloc_ThreadCache"* %h.0, i32 0, i32 1 + %3 = load %struct._opaque_pthread_t** %2, align 4 + %4 = tail call i32 @pthread_equal(%struct._opaque_pthread_t* %3, %struct._opaque_pthread_t* %me.0) nounwind + %5 = icmp eq i32 %4, 0 + br i1 %5, label %bb10, label %bb14 + +bb10: ; preds = %bb7 + %6 = getelementptr inbounds %"struct.WTF::TCMalloc_ThreadCache"* %h.0, i32 0, i32 6 + br label %bb11 + +bb11: ; preds = %bb10, %bb6 + %h.0.in = phi %"struct.WTF::TCMalloc_ThreadCache"** [ @_ZN3WTFL12thread_heapsE, %bb6 ], [ %6, %bb10 ] ; <%"struct.WTF::TCMalloc_ThreadCache"**> [#uses=1] + %h.0 = load %"struct.WTF::TCMalloc_ThreadCache"** %h.0.in, align 4 ; <%"struct.WTF::TCMalloc_ThreadCache"*> [#uses=4] + %7 = icmp eq %"struct.WTF::TCMalloc_ThreadCache"* %h.0, null + br i1 %7, label %bb13, label %bb7 + +bb13: ; preds = %bb11 + %8 = tail call %"struct.WTF::TCMalloc_ThreadCache"* @_ZN3WTF20TCMalloc_ThreadCache7NewHeapEP17_opaque_pthread_t(%struct._opaque_pthread_t* %me.0) nounwind + br label %bb14 + +bb14: ; preds = %bb13, %bb7 + %heap.1 = phi %"struct.WTF::TCMalloc_ThreadCache"* [ %8, %bb13 ], [ %h.0, %bb7 ] ; <%"struct.WTF::TCMalloc_ThreadCache"*> [#uses=4] + %9 = tail call i32 @pthread_mutex_unlock(%struct.PlatformMutex* getelementptr inbounds (%struct.SpinLock* @_ZN3WTFL13pageheap_lockE, i32 0, i32 0)) nounwind + %10 = getelementptr inbounds %"struct.WTF::TCMalloc_ThreadCache"* %heap.1, i32 0, i32 2 + %11 = load i8* %10, align 4 + %toBool15not = icmp eq i8 %11, 0 ; <i1> [#uses=1] + br i1 %toBool15not, label %bb19, label %bb22 + +bb19: ; preds = %bb14 + %.b = load i1* @_ZN3WTFL10tsd_initedE.b, align 4 ; <i1> [#uses=1] + br i1 %.b, label %bb21, label %bb22 + +bb21: ; preds = %bb19 + store i8 1, i8* %10, align 4 + %12 = load i32* @_ZN3WTFL8heap_keyE, align 4 + %13 = bitcast %"struct.WTF::TCMalloc_ThreadCache"* %heap.1 to i8* + %14 = tail call i32 @pthread_setspecific(i32 %12, i8* %13) nounwind + ret %"struct.WTF::TCMalloc_ThreadCache"* %heap.1 + +bb22: ; preds = %bb19, %bb14 + ret %"struct.WTF::TCMalloc_ThreadCache"* %heap.1 +} + +declare i32 @pthread_mutex_lock(%struct.PlatformMutex*) + +declare i32 @pthread_mutex_unlock(%struct.PlatformMutex*) + +declare hidden %"struct.WTF::TCMalloc_ThreadCache"* @_ZN3WTF20TCMalloc_ThreadCache7NewHeapEP17_opaque_pthread_t(%struct._opaque_pthread_t*) nounwind + +declare i32 @pthread_setspecific(i32, i8*) + +declare %struct._opaque_pthread_t* @pthread_self() + +declare i32 @pthread_equal(%struct._opaque_pthread_t*, %struct._opaque_pthread_t*) +
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll b/src/LLVM/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll new file mode 100644 index 0000000..771a4f8 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-01-19-RemovePredicates.ll
@@ -0,0 +1,53 @@ +; RUN: llc -O3 -relocation-model=pic -mcpu=cortex-a8 -mattr=+thumb2 < %s +; +; This test creates a predicated t2ADDri instruction that is then turned into a t2MOVgpr2gpr instr. +; Test that that the predicate operands are removed properly. +; +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" +target triple = "thumbv7-apple-darwin10" + +declare void @etoe53(i16* nocapture, i16* nocapture) nounwind + +define void @earith(double* nocapture %value, i32 %icode, double* nocapture %r1, double* nocapture %r2) nounwind { +entry: + %v = alloca [6 x i16], align 4 ; <[6 x i16]*> [#uses=1] + br i1 undef, label %bb2.i, label %bb5 + +bb2.i: ; preds = %entry + %0 = bitcast double* %value to i16* ; <i16*> [#uses=1] + call void @etoe53(i16* null, i16* %0) nounwind + ret void + +bb5: ; preds = %entry + switch i32 %icode, label %bb10 [ + i32 57, label %bb14 + i32 58, label %bb18 + i32 67, label %bb22 + i32 76, label %bb26 + i32 77, label %bb35 + ] + +bb10: ; preds = %bb5 + br label %bb46 + +bb14: ; preds = %bb5 + unreachable + +bb18: ; preds = %bb5 + unreachable + +bb22: ; preds = %bb5 + unreachable + +bb26: ; preds = %bb5 + br label %bb46 + +bb35: ; preds = %bb5 + unreachable + +bb46: ; preds = %bb26, %bb10 + %1 = bitcast double* %value to i16* ; <i16*> [#uses=1] + %v47 = getelementptr inbounds [6 x i16]* %v, i32 0, i32 0 ; <i16*> [#uses=1] + call void @etoe53(i16* %v47, i16* %1) nounwind + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll b/src/LLVM/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll new file mode 100644 index 0000000..c153092 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll
@@ -0,0 +1,76 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | 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:64:64-v128:128:128-a0:0:32-n32" + +define i32 @test(i32 %n) nounwind { +; CHECK: test: +; CHECK-NOT: mov +; CHECK: return +entry: + %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb.nph + +bb.nph: ; preds = %entry + %tmp = add i32 %n, -1 ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb.nph, %bb + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ] ; <i32> [#uses=1] + %u.05 = phi i64 [ undef, %bb.nph ], [ %ins, %bb ] ; <i64> [#uses=1] + %1 = tail call i32 @f() nounwind ; <i32> [#uses=1] + %tmp4 = zext i32 %1 to i64 ; <i64> [#uses=1] + %mask = and i64 %u.05, -4294967296 ; <i64> [#uses=1] + %ins = or i64 %tmp4, %mask ; <i64> [#uses=2] + tail call void @g(i64 %ins) nounwind + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret i32 undef +} + +define i32 @test_dead_cycle(i32 %n) nounwind { +; CHECK: test_dead_cycle: +; CHECK: blx +; CHECK-NOT: mov +; CHECK: blx +entry: + %0 = icmp eq i32 %n, 1 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb.nph + +bb.nph: ; preds = %entry + %tmp = add i32 %n, -1 ; <i32> [#uses=2] + br label %bb + +bb: ; preds = %bb.nph, %bb2 + %indvar = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb2 ] ; <i32> [#uses=2] + %u.17 = phi i64 [ undef, %bb.nph ], [ %u.0, %bb2 ] ; <i64> [#uses=2] + %tmp9 = sub i32 %tmp, %indvar ; <i32> [#uses=1] + %1 = icmp sgt i32 %tmp9, 1 ; <i1> [#uses=1] + br i1 %1, label %bb1, label %bb2 + +bb1: ; preds = %bb + %2 = tail call i32 @f() nounwind ; <i32> [#uses=1] + %tmp6 = zext i32 %2 to i64 ; <i64> [#uses=1] + %mask = and i64 %u.17, -4294967296 ; <i64> [#uses=1] + %ins = or i64 %tmp6, %mask ; <i64> [#uses=1] + tail call void @g(i64 %ins) nounwind + br label %bb2 + +bb2: ; preds = %bb1, %bb +; also check for duplicate induction variables (radar 7645034) +; CHECK: subs r{{.*}}, #1 +; CHECK-NOT: subs r{{.*}}, #1 +; CHECK: pop + %u.0 = phi i64 [ %ins, %bb1 ], [ %u.17, %bb ] ; <i64> [#uses=2] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %tmp ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb2, %entry + ret i32 undef +} + +declare i32 @f() + +declare void @g(i64)
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-02-24-BigStack.ll b/src/LLVM/test/CodeGen/Thumb2/2010-02-24-BigStack.ll new file mode 100644 index 0000000..2b53747 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-02-24-BigStack.ll
@@ -0,0 +1,15 @@ +; RUN: llc < %s -O0 -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 -mattr=+vfp2 +; This test creates a big stack frame without spilling any callee-saved registers. +; Make sure the whole stack frame is addrerssable wiothout scavenger crashes. +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" +target triple = "thumbv7-apple-darwin3.0.0-iphoneos" + +define void @FindMin(double* %panelTDEL, i8* %dclOfRow, i32 %numRows, i32 %numCols, double* %retMin_RES_TDEL) { +entry: + %panelTDEL.addr = alloca double*, align 4 ; <double**> [#uses=1] + %panelResTDEL = alloca [2560 x double], align 4 ; <[2560 x double]*> [#uses=0] + store double* %panelTDEL, double** %panelTDEL.addr + store double* %retMin_RES_TDEL, double** undef + store i32 0, i32* undef + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-03-08-addi12-ccout.ll b/src/LLVM/test/CodeGen/Thumb2/2010-03-08-addi12-ccout.ll new file mode 100644 index 0000000..7ce3c25 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-03-08-addi12-ccout.ll
@@ -0,0 +1,266 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin + +@.str41196 = external constant [2 x i8], align 4 ; <[2 x i8]*> [#uses=1] + +declare void @syStopraw(i32) nounwind + +declare i32 @SyFopen(i8*, i8*) nounwind + +declare i8* @SyFgets(i8*, i32) nounwind + +define void @SyHelp(i8* nocapture %topic, i32 %fin) nounwind { +entry: + %line = alloca [256 x i8], align 4 ; <[256 x i8]*> [#uses=1] + %secname = alloca [1024 x i8], align 4 ; <[1024 x i8]*> [#uses=0] + %last = alloca [256 x i8], align 4 ; <[256 x i8]*> [#uses=1] + %last2 = alloca [256 x i8], align 4 ; <[256 x i8]*> [#uses=1] + br i1 undef, label %bb, label %bb2 + +bb: ; preds = %entry + br i1 undef, label %bb2, label %bb3 + +bb2: ; preds = %bb, %entry + br label %bb3 + +bb3: ; preds = %bb2, %bb + %storemerge = phi i32 [ 0, %bb2 ], [ 1, %bb ] ; <i32> [#uses=1] + br i1 undef, label %bb19, label %bb20 + +bb19: ; preds = %bb3 + br label %bb20 + +bb20: ; preds = %bb19, %bb3 + br i1 undef, label %bb25, label %bb26 + +bb25: ; preds = %bb20 + br label %bb26 + +bb26: ; preds = %bb25, %bb20 + %offset.2 = phi i32 [ -2, %bb25 ], [ 0, %bb20 ] ; <i32> [#uses=1] + br i1 undef, label %bb.nph508, label %bb49 + +bb.nph508: ; preds = %bb26 + unreachable + +bb49: ; preds = %bb26 + br i1 undef, label %bb51, label %bb50 + +bb50: ; preds = %bb49 + br i1 undef, label %bb51, label %bb104 + +bb51: ; preds = %bb50, %bb49 + unreachable + +bb104: ; preds = %bb50 + br i1 undef, label %bb106, label %bb105 + +bb105: ; preds = %bb104 + br i1 undef, label %bb106, label %bb161 + +bb106: ; preds = %bb105, %bb104 + unreachable + +bb161: ; preds = %bb105 + br i1 false, label %bb163, label %bb162 + +bb162: ; preds = %bb161 + br i1 undef, label %bb163, label %bb224 + +bb163: ; preds = %bb162, %bb161 + unreachable + +bb224: ; preds = %bb162 + %0 = call i32 @SyFopen(i8* undef, i8* getelementptr inbounds ([2 x i8]* @.str41196, i32 0, i32 0)) nounwind ; <i32> [#uses=2] + br i1 false, label %bb297, label %bb300 + +bb297: ; preds = %bb224 + unreachable + +bb300: ; preds = %bb224 + %1 = icmp eq i32 %offset.2, -1 ; <i1> [#uses=1] + br label %bb440 + +bb307: ; preds = %isdigit1498.exit67 + br label %bb308 + +bb308: ; preds = %bb440, %bb307 + br i1 undef, label %bb309, label %isdigit1498.exit67 + +isdigit1498.exit67: ; preds = %bb308 + br i1 undef, label %bb309, label %bb307 + +bb309: ; preds = %isdigit1498.exit67, %bb308 + br i1 undef, label %bb310, label %bb313 + +bb310: ; preds = %bb309 + br label %bb313 + +bb313: ; preds = %bb310, %bb309 + br i1 false, label %bb318, label %bb317 + +bb317: ; preds = %bb313 + %2 = icmp sgt i8 undef, -1 ; <i1> [#uses=1] + br i1 %2, label %bb.i.i73, label %bb1.i.i74 + +bb.i.i73: ; preds = %bb317 + br i1 false, label %bb318, label %bb329.outer + +bb1.i.i74: ; preds = %bb317 + unreachable + +bb318: ; preds = %bb.i.i73, %bb313 + ret void + +bb329.outer: ; preds = %bb.i.i73 + br i1 undef, label %bb333, label %bb329.us.us + +bb329.us.us: ; preds = %bb329.us.us, %bb329.outer + br i1 undef, label %bb333, label %bb329.us.us + +bb333: ; preds = %bb329.us.us, %bb329.outer + %match.0.lcssa = phi i32 [ undef, %bb329.us.us ], [ 2, %bb329.outer ] ; <i32> [#uses=2] + br i1 undef, label %bb335, label %bb388 + +bb335: ; preds = %bb333 + %3 = and i1 undef, %1 ; <i1> [#uses=1] + br i1 %3, label %bb339, label %bb348 + +bb339: ; preds = %bb335 + br i1 false, label %bb340, label %bb345 + +bb340: ; preds = %bb339 + br i1 undef, label %return, label %bb341 + +bb341: ; preds = %bb340 + ret void + +bb345: ; preds = %bb345, %bb339 + %4 = phi i8 [ %5, %bb345 ], [ undef, %bb339 ] ; <i8> [#uses=0] + %indvar670 = phi i32 [ %tmp673, %bb345 ], [ 0, %bb339 ] ; <i32> [#uses=1] + %tmp673 = add i32 %indvar670, 1 ; <i32> [#uses=2] + %scevgep674 = getelementptr [256 x i8]* %last, i32 0, i32 %tmp673 ; <i8*> [#uses=1] + %5 = load i8* %scevgep674, align 1 ; <i8> [#uses=1] + br i1 undef, label %bb347, label %bb345 + +bb347: ; preds = %bb345 + br label %bb348 + +bb348: ; preds = %bb347, %bb335 + br i1 false, label %bb352, label %bb356 + +bb352: ; preds = %bb348 + unreachable + +bb356: ; preds = %bb348 + br i1 undef, label %bb360, label %bb369 + +bb360: ; preds = %bb356 + br i1 false, label %bb361, label %bb366 + +bb361: ; preds = %bb360 + br i1 undef, label %return, label %bb362 + +bb362: ; preds = %bb361 + ret void + +bb366: ; preds = %bb366, %bb360 + %indvar662 = phi i32 [ %tmp665, %bb366 ], [ 0, %bb360 ] ; <i32> [#uses=1] + %tmp665 = add i32 %indvar662, 1 ; <i32> [#uses=2] + %scevgep666 = getelementptr [256 x i8]* %last2, i32 0, i32 %tmp665 ; <i8*> [#uses=1] + %6 = load i8* %scevgep666, align 1 ; <i8> [#uses=0] + br i1 false, label %bb368, label %bb366 + +bb368: ; preds = %bb366 + br label %bb369 + +bb369: ; preds = %bb368, %bb356 + br i1 undef, label %bb373, label %bb388 + +bb373: ; preds = %bb383, %bb369 + %7 = call i8* @SyFgets(i8* undef, i32 %0) nounwind ; <i8*> [#uses=1] + %8 = icmp eq i8* %7, null ; <i1> [#uses=1] + br i1 %8, label %bb375, label %bb383 + +bb375: ; preds = %bb373 + %9 = icmp eq i32 %storemerge, 0 ; <i1> [#uses=1] + br i1 %9, label %return, label %bb376 + +bb376: ; preds = %bb375 + ret void + +bb383: ; preds = %bb373 + %10 = load i8* undef, align 1 ; <i8> [#uses=1] + %cond1 = icmp eq i8 %10, 46 ; <i1> [#uses=1] + br i1 %cond1, label %bb373, label %bb388 + +bb388: ; preds = %bb383, %bb369, %bb333 + %match.1140 = phi i32 [ %match.0.lcssa, %bb369 ], [ 0, %bb333 ], [ %match.0.lcssa, %bb383 ] ; <i32> [#uses=1] + br label %bb391 + +bb390: ; preds = %isdigit1498.exit83, %bb392 + %indvar.next725 = add i32 %indvar724, 1 ; <i32> [#uses=1] + br label %bb391 + +bb391: ; preds = %bb390, %bb388 + %indvar724 = phi i32 [ %indvar.next725, %bb390 ], [ 0, %bb388 ] ; <i32> [#uses=2] + %11 = load i8* undef, align 1 ; <i8> [#uses=0] + br i1 false, label %bb395, label %bb392 + +bb392: ; preds = %bb391 + br i1 undef, label %bb390, label %isdigit1498.exit83 + +isdigit1498.exit83: ; preds = %bb392 + br i1 undef, label %bb390, label %bb395 + +bb394: ; preds = %isdigit1498.exit87 + br label %bb395 + +bb395: ; preds = %bb394, %isdigit1498.exit83, %bb391 + %storemerge14.sum = add i32 %indvar724, undef ; <i32> [#uses=1] + %p.26 = getelementptr [256 x i8]* %line, i32 0, i32 %storemerge14.sum ; <i8*> [#uses=1] + br i1 undef, label %bb400, label %isdigit1498.exit87 + +isdigit1498.exit87: ; preds = %bb395 + br i1 false, label %bb400, label %bb394 + +bb400: ; preds = %isdigit1498.exit87, %bb395 + br i1 undef, label %bb402, label %bb403 + +bb402: ; preds = %bb400 + %12 = getelementptr inbounds i8* %p.26, i32 undef ; <i8*> [#uses=1] + br label %bb403 + +bb403: ; preds = %bb402, %bb400 + %p.29 = phi i8* [ %12, %bb402 ], [ undef, %bb400 ] ; <i8*> [#uses=0] + br i1 undef, label %bb405, label %bb404 + +bb404: ; preds = %bb403 + br i1 undef, label %bb405, label %bb407 + +bb405: ; preds = %bb404, %bb403 + br i1 undef, label %return, label %bb406 + +bb406: ; preds = %bb405 + call void @syStopraw(i32 %fin) nounwind + ret void + +bb407: ; preds = %bb404 + %cond = icmp eq i32 %match.1140, 2 ; <i1> [#uses=1] + br i1 %cond, label %bb408, label %bb428 + +bb408: ; preds = %bb407 + unreachable + +bb428: ; preds = %bb407 + br label %bb440 + +bb440: ; preds = %bb428, %bb300 + %13 = call i8* @SyFgets(i8* undef, i32 %0) nounwind ; <i8*> [#uses=0] + br i1 false, label %bb442, label %bb308 + +bb442: ; preds = %bb440 + unreachable + +return: ; preds = %bb405, %bb375, %bb361, %bb340 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll b/src/LLVM/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll new file mode 100644 index 0000000..bb734ac --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-03-15-AsmCCClobber.ll
@@ -0,0 +1,68 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 \ +; RUN: -pre-RA-sched=source | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 \ +; RUN: -pre-RA-sched=list-hybrid | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -regalloc=basic | FileCheck %s +; Radar 7459078 +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 { i32, i32 } +%s1 = type { %s3, i32, %s4, i8*, void (i8*, i8*)*, i8*, i32*, i32*, i32*, i32, i64, [1 x i32] } +%s2 = type { i32 (...)**, %s4 } +%s3 = type { %s2, i32, i32, i32*, [4 x i8], float, %s4, i8*, i8* } +%s4 = type { %s5 } +%s5 = type { i32 } + +; Make sure the cmp is not scheduled before the InlineAsm that clobbers cc. +; CHECK: blx _f2 +; CHECK: cmp r0, #0 +; CHECK-NOT: cmp +; CHECK: InlineAsm Start +define void @test(%s1* %this, i32 %format, i32 %w, i32 %h, i32 %levels, i32* %s, i8* %data, i32* nocapture %rowbytes, void (i8*, i8*)* %release, i8* %info) nounwind { +entry: + %tmp1 = getelementptr inbounds %s1* %this, i32 0, i32 0, i32 0, i32 1, i32 0, i32 0 + volatile store i32 1, i32* %tmp1, align 4 + %tmp12 = getelementptr inbounds %s1* %this, i32 0, i32 1 + store i32 %levels, i32* %tmp12, align 4 + %tmp13 = getelementptr inbounds %s1* %this, i32 0, i32 3 + store i8* %data, i8** %tmp13, align 4 + %tmp14 = getelementptr inbounds %s1* %this, i32 0, i32 4 + store void (i8*, i8*)* %release, void (i8*, i8*)** %tmp14, align 4 + %tmp15 = getelementptr inbounds %s1* %this, i32 0, i32 5 + store i8* %info, i8** %tmp15, align 4 + %tmp16 = getelementptr inbounds %s1* %this, i32 0, i32 6 + store i32* null, i32** %tmp16, align 4 + %tmp17 = getelementptr inbounds %s1* %this, i32 0, i32 7 + store i32* null, i32** %tmp17, align 4 + %tmp19 = getelementptr inbounds %s1* %this, i32 0, i32 10 + store i64 0, i64* %tmp19, align 4 + %tmp20 = getelementptr inbounds %s1* %this, i32 0, i32 0 + tail call void @f1(%s3* %tmp20, i32* %s) nounwind + %tmp21 = shl i32 %format, 6 + %tmp22 = tail call zeroext i8 @f2(i32 %format) nounwind + %toBoolnot = icmp eq i8 %tmp22, 0 + %tmp23 = zext i1 %toBoolnot to i32 + %flags.0 = or i32 %tmp23, %tmp21 + %tmp24 = shl i32 %flags.0, 16 + %asmtmp.i.i.i = tail call %0 asm sideeffect "\0A0:\09ldrex $1, [$2]\0A\09orr $1, $1, $3\0A\09strex $0, $1, [$2]\0A\09cmp $0, #0\0A\09bne 0b", "=&r,=&r,r,r,~{memory},~{cc}"(i32* %tmp1, i32 %tmp24) nounwind + %tmp25 = getelementptr inbounds %s1* %this, i32 0, i32 2, i32 0, i32 0 + volatile store i32 1, i32* %tmp25, align 4 + %tmp26 = icmp eq i32 %levels, 0 + br i1 %tmp26, label %return, label %bb4 + +bb4: + %l.09 = phi i32 [ %tmp28, %bb4 ], [ 0, %entry ] + %scevgep = getelementptr %s1* %this, i32 0, i32 11, i32 %l.09 + %scevgep10 = getelementptr i32* %rowbytes, i32 %l.09 + %tmp27 = load i32* %scevgep10, align 4 + store i32 %tmp27, i32* %scevgep, align 4 + %tmp28 = add i32 %l.09, 1 + %exitcond = icmp eq i32 %tmp28, %levels + br i1 %exitcond, label %return, label %bb4 + +return: + ret void +} + +declare void @f1(%s3*, i32*) +declare zeroext i8 @f2(i32)
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-04-15-DynAllocBug.ll b/src/LLVM/test/CodeGen/Thumb2/2010-04-15-DynAllocBug.ll new file mode 100644 index 0000000..2246de3 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-04-15-DynAllocBug.ll
@@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -O3 | FileCheck %s +; rdar://7493908 + +; Make sure the result of the first dynamic_alloc isn't copied back to sp more +; than once. We'll deal with poor codegen later. + +define void @t() nounwind ssp { +entry: +; CHECK: t: + %size = mul i32 8, 2 +; CHECK: subs r0, #16 +; CHECK: mov sp, r0 + %vla_a = alloca i8, i32 %size, align 8 +; CHECK: subs r0, #16 +; CHECK: mov sp, r0 + %vla_b = alloca i8, i32 %size, align 8 + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-04-26-CopyRegCrash.ll b/src/LLVM/test/CodeGen/Thumb2/2010-04-26-CopyRegCrash.ll new file mode 100644 index 0000000..3be016f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-04-26-CopyRegCrash.ll
@@ -0,0 +1,73 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin +; Radar 7896289 + +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" +target triple = "thumbv7-apple-darwin10" + +define void @test(i32 %mode) nounwind optsize noinline { +entry: + br i1 undef, label %return, label %bb3 + +bb3: ; preds = %entry + br i1 undef, label %bb15, label %bb18 + +bb15: ; preds = %bb3 + unreachable + +bb18: ; preds = %bb3 + switch i32 %mode, label %return [ + i32 0, label %bb26 + i32 1, label %bb56 + i32 2, label %bb107 + i32 6, label %bb150.preheader + i32 9, label %bb310.preheader + i32 13, label %bb414.preheader + i32 15, label %bb468.preheader + i32 16, label %bb522.preheader + ] + +bb150.preheader: ; preds = %bb18 + br i1 undef, label %bb154, label %bb160 + +bb310.preheader: ; preds = %bb18 + unreachable + +bb414.preheader: ; preds = %bb18 + unreachable + +bb468.preheader: ; preds = %bb18 + unreachable + +bb522.preheader: ; preds = %bb18 + unreachable + +bb26: ; preds = %bb18 + unreachable + +bb56: ; preds = %bb18 + unreachable + +bb107: ; preds = %bb18 + br label %bb110 + +bb110: ; preds = %bb122, %bb107 + %asmtmp.i.i179 = tail call i16 asm "rev16 $0, $1\0A", "=l,l"(i16 undef) nounwind ; <i16> [#uses=1] + %asmtmp.i.i178 = tail call i16 asm "rev16 $0, $1\0A", "=l,l"(i16 %asmtmp.i.i179) nounwind ; <i16> [#uses=1] + store i16 %asmtmp.i.i178, i16* undef, align 2 + br i1 undef, label %bb122, label %bb121 + +bb121: ; preds = %bb110 + br label %bb122 + +bb122: ; preds = %bb121, %bb110 + br label %bb110 + +bb154: ; preds = %bb150.preheader + unreachable + +bb160: ; preds = %bb150.preheader + unreachable + +return: ; preds = %bb18, %entry + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-05-24-rsbs.ll b/src/LLVM/test/CodeGen/Thumb2/2010-05-24-rsbs.ll new file mode 100644 index 0000000..e72d542 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-05-24-rsbs.ll
@@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s +; Radar 8017376: Missing 's' suffix for t2RSBS instructions. +; CHECK: rsbs + +define i64 @test(i64 %x) nounwind readnone { +entry: + %0 = sub nsw i64 1, %x ; <i64> [#uses=1] + ret i64 %0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll b/src/LLVM/test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll new file mode 100644 index 0000000..01fb0a5 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-06-14-NEONCoalescer.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -O3 -relocation-model=pic -mattr=+thumb2 -mcpu=cortex-a8 -disable-branch-fold | 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:64:64-v128:128:128-a0:0:32-n32" +target triple = "thumbv7-apple-darwin10" + +; This is a case where the coalescer was too eager. These two copies were +; considered equivalent and coalescable: +; +; 140 %reg1038:dsub_0<def> = VMOVD %reg1047:dsub_0, pred:14, pred:%reg0 +; 148 %reg1038:dsub_1<def> = VMOVD %reg1047:dsub_0, pred:14, pred:%reg0 +; +; Only one can be coalesced. + +@.str = private constant [7 x i8] c"%g %g\0A\00", align 4 ; <[7 x i8]*> [#uses=1] + +define i32 @main(i32 %argc, i8** nocapture %Argv) nounwind { +entry: + %0 = icmp eq i32 %argc, 2123 ; <i1> [#uses=1] + %U.0 = select i1 %0, double 3.282190e+01, double 8.731834e+02 ; <double> [#uses=2] + %1 = icmp eq i32 %argc, 5123 ; <i1> [#uses=1] + %V.0.ph = select i1 %1, double 7.779980e+01, double 0x409CCB9C779A6B51 ; <double> [#uses=1] + %2 = insertelement <2 x double> undef, double %U.0, i32 0 ; <<2 x double>> [#uses=2] + %3 = insertelement <2 x double> %2, double %U.0, i32 1 ; <<2 x double>> [#uses=2] + %4 = insertelement <2 x double> %2, double %V.0.ph, i32 1 ; <<2 x double>> [#uses=2] +; Constant pool load followed by add. +; Then clobber the loaded register, not the sum. +; CHECK: vldr.64 [[LDR:d.*]], +; CHECK: LPC0_0: +; CHECK: vadd.f64 [[ADD:d.*]], [[LDR]], [[LDR]] +; CHECK-NOT: vmov.f64 [[ADD]] + %5 = fadd <2 x double> %3, %3 ; <<2 x double>> [#uses=2] + %6 = fadd <2 x double> %4, %4 ; <<2 x double>> [#uses=2] + %tmp7 = extractelement <2 x double> %5, i32 0 ; <double> [#uses=1] + %tmp5 = extractelement <2 x double> %5, i32 1 ; <double> [#uses=1] +; CHECK: printf + %7 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), double %tmp7, double %tmp5) nounwind ; <i32> [#uses=0] + %tmp3 = extractelement <2 x double> %6, i32 0 ; <double> [#uses=1] + %tmp1 = extractelement <2 x double> %6, i32 1 ; <double> [#uses=1] + %8 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([7 x i8]* @.str, i32 0, i32 0), double %tmp3, double %tmp1) nounwind ; <i32> [#uses=0] + ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-06-19-ITBlockCrash.ll b/src/LLVM/test/CodeGen/Thumb2/2010-06-19-ITBlockCrash.ll new file mode 100644 index 0000000..501f763 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-06-19-ITBlockCrash.ll
@@ -0,0 +1,35 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -O3 -relocation-model=pic -disable-fp-elim -mcpu=cortex-a8 +; rdar://8110842 + +declare arm_apcscc i32 @__maskrune(i32, i32) + +define arm_apcscc i32 @strncmpic(i8* nocapture %s1, i8* nocapture %s2, i32 %n) nounwind { +entry: + br i1 undef, label %bb11, label %bb19 + +bb11: ; preds = %entry + %0 = sext i8 0 to i32 ; <i32> [#uses=1] + br i1 undef, label %bb.i.i10, label %bb1.i.i11 + +bb.i.i10: ; preds = %bb11 + br label %isupper144.exit12 + +bb1.i.i11: ; preds = %bb11 + %1 = tail call arm_apcscc i32 @__maskrune(i32 %0, i32 32768) nounwind ; <i32> [#uses=1] + %2 = icmp ne i32 %1, 0 ; <i1> [#uses=1] + %3 = zext i1 %2 to i32 ; <i32> [#uses=1] + %.pre = load i8* undef, align 1 ; <i8> [#uses=1] + br label %isupper144.exit12 + +isupper144.exit12: ; preds = %bb1.i.i11, %bb.i.i10 + %4 = phi i8 [ %.pre, %bb1.i.i11 ], [ 0, %bb.i.i10 ] ; <i8> [#uses=1] + %5 = phi i32 [ %3, %bb1.i.i11 ], [ undef, %bb.i.i10 ] ; <i32> [#uses=1] + %6 = icmp eq i32 %5, 0 ; <i1> [#uses=1] + %7 = sext i8 %4 to i32 ; <i32> [#uses=1] + %storemerge1 = select i1 %6, i32 %7, i32 undef ; <i32> [#uses=1] + %8 = sub nsw i32 %storemerge1, 0 ; <i32> [#uses=1] + ret i32 %8 + +bb19: ; preds = %entry + ret i32 0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-06-21-TailMergeBug.ll b/src/LLVM/test/CodeGen/Thumb2/2010-06-21-TailMergeBug.ll new file mode 100644 index 0000000..244d0bb --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-06-21-TailMergeBug.ll
@@ -0,0 +1,127 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -O3 -relocation-model=pic | FileCheck %s +; rdar://8115404 +; Tail merging must not split an IT block. + +%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } +%struct._RuneCharClass = type { [14 x i8], i32 } +%struct._RuneEntry = type { i32, i32, i32, i32* } +%struct._RuneLocale = type { [8 x i8], [32 x i8], i32 (i8*, i32, i8**)*, i32 (i32, i8*, i32, i8**)*, i32, [256 x i32], [256 x i32], [256 x i32], %struct._RuneRange, %struct._RuneRange, %struct._RuneRange, i8*, i32, i32, %struct._RuneCharClass* } +%struct._RuneRange = type { i32, %struct._RuneEntry* } +%struct.__sFILEX = type opaque +%struct.__sbuf = type { i8*, i32 } + +@finput = external global %struct.FILE* ; <%struct.FILE**> [#uses=1] +@_DefaultRuneLocale = external global %struct._RuneLocale ; <%struct._RuneLocale*> [#uses=0] +@token_buffer = external global [1025 x i8], align 4 ; <[1025 x i8]*> [#uses=1] +@.str73 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str174 = external constant [5 x i8], align 4 ; <[5 x i8]*> [#uses=0] +@.str275 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str376 = external constant [5 x i8], align 4 ; <[5 x i8]*> [#uses=0] +@.str477 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str578 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str679 = external constant [7 x i8], align 4 ; <[7 x i8]*> [#uses=0] +@.str780 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str881 = external constant [5 x i8], align 4 ; <[5 x i8]*> [#uses=0] +@.str982 = external constant [6 x i8], align 4 ; <[6 x i8]*> [#uses=0] +@.str1083 = external constant [9 x i8], align 4 ; <[9 x i8]*> [#uses=0] +@.str1184 = external constant [7 x i8], align 4 ; <[7 x i8]*> [#uses=0] +@.str1285 = external constant [16 x i8], align 4 ; <[16 x i8]*> [#uses=0] +@.str1386 = external constant [12 x i8], align 4 ; <[12 x i8]*> [#uses=0] +@.str1487 = external constant [5 x i8], align 4 ; <[5 x i8]*> [#uses=0] +@llvm.used = external global [1 x i8*] ; <[1 x i8*]*> [#uses=0] + +define fastcc i32 @parse_percent_token() nounwind { +entry: +; CHECK: pop +; CHECK: pop +; CHECK: pop +; CHECK: pop +; CHECK: pop +; CHECK: pop +; CHECK: pop +; Do not convert into single stream code. BranchProbability Analysis assumes +; that branches which goes to "ret" intruction have lower probabilities. + switch i32 undef, label %bb7 [ + i32 37, label %bb43 + i32 48, label %bb5 + i32 50, label %bb4 + i32 60, label %bb2 + i32 61, label %bb6 + i32 62, label %bb3 + i32 123, label %bb1 + ] + +bb1: ; preds = %entry + ret i32 8 + +bb2: ; preds = %entry + ret i32 15 + +bb3: ; preds = %entry + ret i32 16 + +bb4: ; preds = %entry + ret i32 17 + +bb5: ; preds = %entry + ret i32 9 + +bb6: ; preds = %entry + ret i32 18 + +bb7: ; preds = %entry + br i1 undef, label %bb.i.i, label %bb1.i.i + +bb.i.i: ; preds = %bb7 + br i1 undef, label %bb43, label %bb12 + +bb1.i.i: ; preds = %bb7 + unreachable + +bb9: ; preds = %bb.i.i2 + br i1 undef, label %bb10, label %bb11 + +bb10: ; preds = %bb9 + br label %bb11 + +bb11: ; preds = %bb10, %bb9 + %p.0 = phi i8* [ undef, %bb10 ], [ %p.1, %bb9 ] ; <i8*> [#uses=1] + %0 = load %struct.FILE** @finput, align 4 ; <%struct.FILE*> [#uses=1] + %1 = tail call i32 @getc(%struct.FILE* %0) nounwind ; <i32> [#uses=0] + br label %bb12 + +bb12: ; preds = %bb11, %bb.i.i + %p.1 = phi i8* [ %p.0, %bb11 ], [ getelementptr inbounds ([1025 x i8]* @token_buffer, i32 0, i32 0), %bb.i.i ] ; <i8*> [#uses=2] + %2 = icmp ult i32 undef, 128 ; <i1> [#uses=1] + br i1 %2, label %bb.i.i2, label %bb1.i.i3 + +bb.i.i2: ; preds = %bb12 + %3 = load i32* null, align 4 ; <i32> [#uses=1] + %4 = lshr i32 %3, 8 ; <i32> [#uses=1] + %.lobit.i1 = and i32 %4, 1 ; <i32> [#uses=1] + %.not = icmp ne i32 %.lobit.i1, 0 ; <i1> [#uses=1] + %or.cond = or i1 %.not, undef ; <i1> [#uses=1] + br i1 %or.cond, label %bb9, label %bb14 + +bb1.i.i3: ; preds = %bb12 + unreachable + +bb14: ; preds = %bb.i.i2 + store i8 0, i8* %p.1, align 1 + br i1 undef, label %bb43, label %bb15 + +bb15: ; preds = %bb14 + unreachable + +bb43: ; preds = %bb14, %bb.i.i, %entry + %.0 = phi i32 [ 7, %entry ], [ 24, %bb.i.i ], [ 9, %bb14 ] ; <i32> [#uses=1] + ret i32 %.0 +} + +declare i32 @getc(%struct.FILE* nocapture) nounwind + +declare i32 @strcmp(i8* nocapture, i8* nocapture) nounwind readonly + +declare i32 @__maskrune(i32, i32) + +declare i32 @ungetc(i32, %struct.FILE* nocapture) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-08-10-VarSizedAllocaBug.ll b/src/LLVM/test/CodeGen/Thumb2/2010-08-10-VarSizedAllocaBug.ll new file mode 100644 index 0000000..47d7a9c --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-08-10-VarSizedAllocaBug.ll
@@ -0,0 +1,59 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -O3 | FileCheck %s + +@.str = private constant [4 x i8] c"%d\0A\00", align 4 ; <[4 x i8]*> [#uses=1] + +define internal fastcc i32 @Callee(i32 %i) nounwind { +entry: +; CHECK: Callee: +; CHECK: push +; CHECK: mov r4, sp +; CHECK: sub.w [[R12:r[0-9]+]], r4, #1000 +; CHECK: mov sp, [[R12]] + %0 = icmp eq i32 %i, 0 ; <i1> [#uses=1] + br i1 %0, label %bb2, label %bb + +bb: ; preds = %entry + %1 = alloca [1000 x i8], align 4 ; <[1000 x i8]*> [#uses=1] + %.sub = getelementptr inbounds [1000 x i8]* %1, i32 0, i32 0 ; <i8*> [#uses=2] + %2 = call i32 (i8*, i32, i32, i8*, ...)* @__sprintf_chk(i8* %.sub, i32 0, i32 1000, i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %i) nounwind ; <i32> [#uses=0] + %3 = load i8* %.sub, align 4 ; <i8> [#uses=1] + %4 = sext i8 %3 to i32 ; <i32> [#uses=1] + ret i32 %4 + +bb2: ; preds = %entry +; Must restore sp from fp here. Make sure not to leave sp in a temporarily invalid +; state though. rdar://8465407 +; CHECK-NOT: mov sp, r7 +; CHECK: sub.w r4, r7, #8 +; CHECK: mov sp, r4 +; CHECK: pop + ret i32 0 +} + +declare i32 @__sprintf_chk(i8*, i32, i32, i8*, ...) nounwind + +define i32 @main() nounwind { +; CHECK: main: +bb.nph: + br label %bb + +bb: ; preds = %bb, %bb.nph + %0 = phi i32 [ 0, %bb.nph ], [ %3, %bb ] ; <i32> [#uses=2] + %j.01 = phi i32 [ 0, %bb.nph ], [ %2, %bb ] ; <i32> [#uses=1] + %1 = tail call fastcc i32 @Callee(i32 %0) nounwind ; <i32> [#uses=1] + %2 = add nsw i32 %1, %j.01 ; <i32> [#uses=2] + %3 = add nsw i32 %0, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %3, 10000 ; <i1> [#uses=1] + br i1 %exitcond, label %bb2, label %bb + +bb2: ; preds = %bb +; No need to restore sp from fp here. +; CHECK: printf +; CHECK-NOT: mov sp, r7 +; CHECK-NOT: sub sp, #12 +; CHECK: pop + %4 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %2) nounwind ; <i32> [#uses=0] + ret i32 0 +} + +declare i32 @printf(i8* nocapture, ...) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll b/src/LLVM/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll new file mode 100644 index 0000000..d2140a1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll
@@ -0,0 +1,34 @@ +; rdar://8465407 +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +%struct.buf = type opaque + +declare void @bar() nounwind optsize + +define void @foo() nounwind optsize { +; CHECK: foo: +; CHECK: push +; CHECK: mov r7, sp +; CHECK: sub sp, #4 +entry: + %m.i = alloca %struct.buf*, align 4 + br label %bb + +bb: + br i1 undef, label %bb3, label %bb2 + +bb2: + call void @bar() nounwind optsize + br i1 undef, label %bb, label %bb3 + +bb3: + br i1 undef, label %return, label %bb + +return: +; CHECK: %return +; 'mov sp, r7' would have left sp in an invalid state +; CHECK-NOT: mov sp, r7 +; CHECK-NOT: sub, sp, #4 +; CHECK: add sp, #4 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2010-12-03-AddSPNarrowing.ll b/src/LLVM/test/CodeGen/Thumb2/2010-12-03-AddSPNarrowing.ll new file mode 100644 index 0000000..5b91a5f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2010-12-03-AddSPNarrowing.ll
@@ -0,0 +1,11 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s +; Radar 8724703: Make sure that a t2ADDrSPi instruction with SP as the +; destination register is narrowed to tADDspi instead of tADDrSPi. + +define void @test() nounwind { +entry: +; CHECK: sub.w +; CHECK: add.w + %Buffer.i = alloca [512 x i8], align 4 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/2011-04-21-FILoweringBug.ll b/src/LLVM/test/CodeGen/Thumb2/2011-04-21-FILoweringBug.ll new file mode 100644 index 0000000..604a352 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2011-04-21-FILoweringBug.ll
@@ -0,0 +1,23 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +; Use sp, #imm to lower frame indices when the offset is multiple of 4 +; and in the range of 0-1020. This saves code size by utilizing +; 16-bit instructions. +; rdar://9321541 + +define i32 @t() nounwind { +entry: +; CHECK: t: +; CHECK: sub sp, #12 +; CHECK-NOT: sub +; CHECK: add r0, sp, #4 +; CHECK: add r1, sp, #8 +; CHECK: mov r2, sp + %size = alloca i32, align 4 + %count = alloca i32, align 4 + %index = alloca i32, align 4 + %0 = call i32 @foo(i32* %count, i32* %size, i32* %index) nounwind + ret i32 %0 +} + +declare i32 @foo(i32*, i32*, i32*)
diff --git a/src/LLVM/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll b/src/LLVM/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll new file mode 100644 index 0000000..b1ce3bb --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/2011-06-07-TwoAddrEarlyClobber.ll
@@ -0,0 +1,34 @@ +; RUN: llc -mtriple=thumbv7-apple-darwin10 < %s | FileCheck %s + +%struct.op = type { %struct.op*, %struct.op*, %struct.op* ()*, i32, i16, i16, i8, i8 } + +; CHECK: Perl_ck_sort +; CHECK: ldreq +; CHECK: moveq [[REGISTER:(r[0-9]+)|(lr)]] +; CHECK: streq {{(r[0-9])|(lr)}}, {{\[}}[[REGISTER]]{{\]}}, #24 + +define void @Perl_ck_sort() nounwind optsize { +entry: + %tmp27 = load %struct.op** undef, align 4 + switch i16 undef, label %if.end151 [ + i16 178, label %if.then60 + i16 177, label %if.then60 + ] + +if.then60: ; preds = %if.then40 + br i1 undef, label %if.then67, label %if.end95 + +if.then67: ; preds = %if.then60 + %op_next71 = getelementptr inbounds %struct.op* %tmp27, i32 0, i32 0 + store %struct.op* %tmp27, %struct.op** %op_next71, align 4 + %0 = getelementptr inbounds %struct.op* %tmp27, i32 1, i32 0 + br label %if.end95 + +if.end95: ; preds = %if.else92, %if.then67 + %.pre-phi = phi %struct.op** [ undef, %if.then60 ], [ %0, %if.then67 ] + %tmp98 = load %struct.op** %.pre-phi, align 4 + br label %if.end151 + +if.end151: ; preds = %if.end100, %if.end, %entry + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/bfi.ll b/src/LLVM/test/CodeGen/Thumb2/bfi.ll new file mode 100644 index 0000000..3612e27 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/bfi.ll
@@ -0,0 +1,61 @@ +; RUN: llc -march=thumb -mattr=+v6t2 < %s | FileCheck %s + +%struct.F = type { [3 x i8], i8 } + +@X = common global %struct.F zeroinitializer, align 4 ; <%struct.F*> [#uses=1] + +define void @f1([1 x i32] %f.coerce0) nounwind { +entry: +; CHECK: f1 +; CHECK: movs r2, #10 +; CHECK: bfi r1, r2, #22, #4 + %0 = load i32* bitcast (%struct.F* @X to i32*), align 4 ; <i32> [#uses=1] + %1 = and i32 %0, -62914561 ; <i32> [#uses=1] + %2 = or i32 %1, 41943040 ; <i32> [#uses=1] + store i32 %2, i32* bitcast (%struct.F* @X to i32*), align 4 + ret void +} + +define i32 @f2(i32 %A, i32 %B) nounwind readnone optsize { +entry: +; CHECK: f2 +; CHECK: lsrs r1, r1, #7 +; CHECK: bfi r0, r1, #7, #16 + %and = and i32 %A, -8388481 ; <i32> [#uses=1] + %and2 = and i32 %B, 8388480 ; <i32> [#uses=1] + %or = or i32 %and2, %and ; <i32> [#uses=1] + ret i32 %or +} + +define i32 @f3(i32 %A, i32 %B) nounwind readnone optsize { +entry: +; CHECK: f3 +; CHECK: lsrs {{.*}}, #7 +; CHECK: bfi {{.*}}, #7, #16 + %and = and i32 %A, 8388480 ; <i32> [#uses=1] + %and2 = and i32 %B, -8388481 ; <i32> [#uses=1] + %or = or i32 %and2, %and ; <i32> [#uses=1] + ret i32 %or +} + +; rdar://8752056 +define i32 @f4(i32 %a) nounwind { +; CHECK: f4 +; CHECK: movw [[R1:r[0-9]+]], #3137 +; CHECK: bfi [[R1]], {{.*}}, #15, #5 + %1 = shl i32 %a, 15 + %ins7 = and i32 %1, 1015808 + %ins12 = or i32 %ins7, 3137 + ret i32 %ins12 +} + +; rdar://9177502 +define i32 @f5(i32 %a, i32 %b) nounwind readnone { +entry: +; CHECK: f5 +; CHECK-NOT: bfi r0, r2, #0, #1 +%and = and i32 %a, 2 +%b.masked = and i32 %b, -2 +%and3 = or i32 %b.masked, %and +ret i32 %and3 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/bfx.ll b/src/LLVM/test/CodeGen/Thumb2/bfx.ll new file mode 100644 index 0000000..489349d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/bfx.ll
@@ -0,0 +1,28 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @sbfx1(i32 %a) { +; CHECK: sbfx1 +; CHECK: sbfx r0, r0, #7, #11 + %t1 = lshr i32 %a, 7 + %t2 = trunc i32 %t1 to i11 + %t3 = sext i11 %t2 to i32 + ret i32 %t3 +} + +define i32 @ubfx1(i32 %a) { +; CHECK: ubfx1 +; CHECK: ubfx r0, r0, #7, #11 + %t1 = lshr i32 %a, 7 + %t2 = trunc i32 %t1 to i11 + %t3 = zext i11 %t2 to i32 + ret i32 %t3 +} + +define i32 @ubfx2(i32 %a) { +; CHECK: ubfx2 +; CHECK: ubfx r0, r0, #7, #11 + %t1 = lshr i32 %a, 7 + %t2 = and i32 %t1, 2047 + ret i32 %t2 +} +
diff --git a/src/LLVM/test/CodeGen/Thumb2/buildvector-crash.ll b/src/LLVM/test/CodeGen/Thumb2/buildvector-crash.ll new file mode 100644 index 0000000..01ef472 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/buildvector-crash.ll
@@ -0,0 +1,17 @@ +; RUN: llc < %s -O3 -mtriple=thumbv7-apple-darwin10 -mcpu=cortex-a8 | FileCheck %s +; Formerly crashed, 3573915. + +define void @RotateStarsFP_Vec() nounwind { +bb.nph372: + br label %bb8 + +bb8: ; preds = %bb8, %bb.nph372 + %0 = fadd <4 x float> undef, <float 0xBFEE353F80000000, float 0xBFEE353F80000000, float 0xBFEE353F80000000, float 0xBFEE353F80000000> + %1 = fmul <4 x float> %0, undef + %2 = fmul <4 x float> %1, undef + %3 = fadd <4 x float> undef, %2 + store <4 x float> %3, <4 x float>* undef, align 4 + br label %bb8 +; CHECK: RotateStarsFP_Vec: +; CHECK: vldmia +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/carry.ll b/src/LLVM/test/CodeGen/Thumb2/carry.ll new file mode 100644 index 0000000..de6f6e2 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/carry.ll
@@ -0,0 +1,22 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i64 @f1(i64 %a, i64 %b) { +entry: +; CHECK: f1: +; CHECK: subs r0, r0, r2 +; CHECK: sbcs r1, r3 + %tmp = sub i64 %a, %b + ret i64 %tmp +} + +define i64 @f2(i64 %a, i64 %b) { +entry: +; CHECK: f2: +; CHECK: adds r0, r0, r0 +; CHECK: adcs r1, r1 +; CHECK: subs r0, r0, r2 +; CHECK: sbcs r1, r3 + %tmp1 = shl i64 %a, 1 + %tmp2 = sub i64 %tmp1, %b + ret i64 %tmp2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/cortex-fp.ll b/src/LLVM/test/CodeGen/Thumb2/cortex-fp.ll new file mode 100644 index 0000000..d06f8a7 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/cortex-fp.ll
@@ -0,0 +1,24 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -march=thumb -mcpu=cortex-m3 | FileCheck %s -check-prefix=CORTEXM3 +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -march=thumb -mcpu=cortex-m4 | FileCheck %s -check-prefix=CORTEXM4 +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -march=thumb -mcpu=cortex-a8 | FileCheck %s -check-prefix=CORTEXA8 + + +define float @foo(float %a, float %b) { +entry: +; CHECK: foo +; CORTEXM3: blx ___mulsf3 +; CORTEXM4: vmul.f32 s0, s1, s0 +; CORTEXA8: vmul.f32 d0, d1, d0 + %0 = fmul float %a, %b + ret float %0 +} + +define double @bar(double %a, double %b) { +entry: +; CHECK: bar + %0 = fmul double %a, %b +; CORTEXM3: blx ___muldf3 +; CORTEXM4: blx ___muldf3 +; CORTEXA8: vmul.f64 d16, d17, d16 + ret double %0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/crash.ll b/src/LLVM/test/CodeGen/Thumb2/crash.ll new file mode 100644 index 0000000..d8b51ec --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/crash.ll
@@ -0,0 +1,49 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 +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" +target triple = "thumbv7-apple-darwin10" + +; This function would crash LiveIntervalAnalysis by creating a chain of 4 INSERT_SUBREGs of the same register. +define arm_apcscc void @NEON_vst4q_u32(i32* nocapture %sp0, i32* nocapture %sp1, i32* nocapture %sp2, i32* nocapture %sp3, i32* %dp) nounwind { +entry: + %0 = bitcast i32* %sp0 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %1 = load <4 x i32>* %0, align 16 ; <<4 x i32>> [#uses=1] + %2 = bitcast i32* %sp1 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %3 = load <4 x i32>* %2, align 16 ; <<4 x i32>> [#uses=1] + %4 = bitcast i32* %sp2 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %5 = load <4 x i32>* %4, align 16 ; <<4 x i32>> [#uses=1] + %6 = bitcast i32* %sp3 to <4 x i32>* ; <<4 x i32>*> [#uses=1] + %7 = load <4 x i32>* %6, align 16 ; <<4 x i32>> [#uses=1] + %8 = bitcast i32* %dp to i8* ; <i8*> [#uses=1] + tail call void @llvm.arm.neon.vst4.v4i32(i8* %8, <4 x i32> %1, <4 x i32> %3, <4 x i32> %5, <4 x i32> %7, i32 1) + ret void +} + +declare void @llvm.arm.neon.vst4.v4i32(i8*, <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32>, i32) nounwind + +@sbuf = common global [16 x i32] zeroinitializer, align 16 ; <[16 x i32]*> [#uses=5] +@dbuf = common global [16 x i32] zeroinitializer ; <[16 x i32]*> [#uses=2] + +; This function creates 4 chained INSERT_SUBREGS and then invokes the register scavenger. +; The first INSERT_SUBREG needs an <undef> use operand for that to work. +define arm_apcscc i32 @main() nounwind { +bb.nph: + br label %bb + +bb: ; preds = %bb, %bb.nph + %0 = phi i32 [ 0, %bb.nph ], [ %1, %bb ] ; <i32> [#uses=4] + %scevgep = getelementptr [16 x i32]* @sbuf, i32 0, i32 %0 ; <i32*> [#uses=1] + %scevgep5 = getelementptr [16 x i32]* @dbuf, i32 0, i32 %0 ; <i32*> [#uses=1] + store i32 %0, i32* %scevgep, align 4 + store i32 -1, i32* %scevgep5, align 4 + %1 = add nsw i32 %0, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %1, 16 ; <i1> [#uses=1] + br i1 %exitcond, label %bb2, label %bb + +bb2: ; preds = %bb + %2 = load <4 x i32>* bitcast ([16 x i32]* @sbuf to <4 x i32>*), align 16 ; <<4 x i32>> [#uses=1] + %3 = load <4 x i32>* bitcast (i32* getelementptr inbounds ([16 x i32]* @sbuf, i32 0, i32 4) to <4 x i32>*), align 16 ; <<4 x i32>> [#uses=1] + %4 = load <4 x i32>* bitcast (i32* getelementptr inbounds ([16 x i32]* @sbuf, i32 0, i32 8) to <4 x i32>*), align 16 ; <<4 x i32>> [#uses=1] + %5 = load <4 x i32>* bitcast (i32* getelementptr inbounds ([16 x i32]* @sbuf, i32 0, i32 12) to <4 x i32>*), align 16 ; <<4 x i32>> [#uses=1] + tail call void @llvm.arm.neon.vst4.v4i32(i8* bitcast ([16 x i32]* @dbuf to i8*), <4 x i32> %2, <4 x i32> %3, <4 x i32> %4, <4 x i32> %5, i32 1) nounwind + ret i32 0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-1.ll b/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-1.ll new file mode 100644 index 0000000..c71c3ca --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-1.ll
@@ -0,0 +1,52 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 + +%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 } +%struct.__sFILEX = type opaque +%struct.__sbuf = type { i8*, i32 } + +declare i32 @fgetc(%struct.FILE* nocapture) nounwind + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { +entry: + br i1 undef, label %bb, label %bb1 + +bb: ; preds = %entry + unreachable + +bb1: ; preds = %entry + br i1 undef, label %bb.i1, label %bb1.i2 + +bb.i1: ; preds = %bb1 + unreachable + +bb1.i2: ; preds = %bb1 + %0 = call i32 @fgetc(%struct.FILE* undef) nounwind ; <i32> [#uses=0] + br i1 undef, label %bb2.i3, label %bb3.i4 + +bb2.i3: ; preds = %bb1.i2 + br i1 undef, label %bb4.i, label %bb3.i4 + +bb3.i4: ; preds = %bb2.i3, %bb1.i2 + unreachable + +bb4.i: ; preds = %bb2.i3 + br i1 undef, label %bb5.i, label %get_image.exit + +bb5.i: ; preds = %bb4.i + unreachable + +get_image.exit: ; preds = %bb4.i + br i1 undef, label %bb28, label %bb27 + +bb27: ; preds = %get_image.exit + br label %bb.i + +bb.i: ; preds = %bb.i, %bb27 + %1 = fptrunc double undef to float ; <float> [#uses=1] + %2 = fptoui float %1 to i8 ; <i8> [#uses=1] + store i8 %2, i8* undef, align 1 + br label %bb.i + +bb28: ; preds = %get_image.exit + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll b/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll new file mode 100644 index 0000000..edbf834 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/cross-rc-coalescing-2.ll
@@ -0,0 +1,73 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | FileCheck %s + +define void @fht(float* nocapture %fz, i16 signext %n) nounwind { +; CHECK: fht: +entry: + br label %bb5 + +bb5: ; preds = %bb5, %entry + br i1 undef, label %bb5, label %bb.nph + +bb.nph: ; preds = %bb5 + br label %bb7 + +; Loop preheader +; CHECK: vmov.f32 +bb7: ; preds = %bb9, %bb.nph + %s1.02 = phi float [ undef, %bb.nph ], [ %35, %bb9 ] ; <float> [#uses=3] + %tmp79 = add i32 undef, undef ; <i32> [#uses=1] + %tmp53 = sub i32 undef, undef ; <i32> [#uses=1] + %0 = fadd float 0.000000e+00, 1.000000e+00 ; <float> [#uses=2] + %1 = fmul float 0.000000e+00, 0.000000e+00 ; <float> [#uses=2] + br label %bb8 + +bb8: ; preds = %bb8, %bb7 +; CHECK: %bb8 +; CHECK-NOT: vmov.f32 +; CHECK: blt + %tmp54 = add i32 0, %tmp53 ; <i32> [#uses=0] + %fi.1 = getelementptr float* %fz, i32 undef ; <float*> [#uses=2] + %tmp80 = add i32 0, %tmp79 ; <i32> [#uses=1] + %scevgep81 = getelementptr float* %fz, i32 %tmp80 ; <float*> [#uses=1] + %2 = load float* undef, align 4 ; <float> [#uses=1] + %3 = fmul float %2, %1 ; <float> [#uses=1] + %4 = load float* null, align 4 ; <float> [#uses=2] + %5 = fmul float %4, %0 ; <float> [#uses=1] + %6 = fsub float %3, %5 ; <float> [#uses=1] + %7 = fmul float %4, %1 ; <float> [#uses=1] + %8 = fadd float undef, %7 ; <float> [#uses=2] + %9 = load float* %fi.1, align 4 ; <float> [#uses=2] + %10 = fsub float %9, %8 ; <float> [#uses=1] + %11 = fadd float %9, %8 ; <float> [#uses=1] + %12 = fsub float 0.000000e+00, %6 ; <float> [#uses=1] + %13 = fsub float 0.000000e+00, undef ; <float> [#uses=2] + %14 = fmul float undef, %0 ; <float> [#uses=1] + %15 = fadd float %14, undef ; <float> [#uses=2] + %16 = load float* %scevgep81, align 4 ; <float> [#uses=2] + %17 = fsub float %16, %15 ; <float> [#uses=1] + %18 = fadd float %16, %15 ; <float> [#uses=2] + %19 = load float* undef, align 4 ; <float> [#uses=2] + %20 = fsub float %19, %13 ; <float> [#uses=2] + %21 = fadd float %19, %13 ; <float> [#uses=1] + %22 = fmul float %s1.02, %18 ; <float> [#uses=1] + %23 = fmul float 0.000000e+00, %20 ; <float> [#uses=1] + %24 = fsub float %22, %23 ; <float> [#uses=1] + %25 = fmul float 0.000000e+00, %18 ; <float> [#uses=1] + %26 = fmul float %s1.02, %20 ; <float> [#uses=1] + %27 = fadd float %25, %26 ; <float> [#uses=1] + %28 = fadd float %11, %27 ; <float> [#uses=1] + store float %28, float* %fi.1, align 4 + %29 = fadd float %12, %24 ; <float> [#uses=1] + store float %29, float* null, align 4 + %30 = fmul float 0.000000e+00, %21 ; <float> [#uses=1] + %31 = fmul float %s1.02, %17 ; <float> [#uses=1] + %32 = fsub float %30, %31 ; <float> [#uses=1] + %33 = fsub float %10, %32 ; <float> [#uses=1] + store float %33, float* undef, align 4 + %34 = icmp slt i32 undef, undef ; <i1> [#uses=1] + br i1 %34, label %bb8, label %bb9 + +bb9: ; preds = %bb8 + %35 = fadd float 0.000000e+00, undef ; <float> [#uses=1] + br label %bb7 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/dg.exp b/src/LLVM/test/CodeGen/Thumb2/dg.exp new file mode 100644 index 0000000..3ff359a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/dg.exp
@@ -0,0 +1,5 @@ +load_lib llvm.exp + +if { [llvm_supports_target ARM] } { + RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/div.ll b/src/LLVM/test/CodeGen/Thumb2/div.ll new file mode 100644 index 0000000..2c00c70 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/div.ll
@@ -0,0 +1,45 @@ +; RUN: llc < %s -mtriple=thumb-apple-darwin -mattr=+thumb2 \ +; RUN: | FileCheck %s -check-prefix=CHECK-THUMB +; RUN: llc < %s -march=thumb -mcpu=cortex-m3 -mattr=+thumb2 \ +; RUN: | FileCheck %s -check-prefix=CHECK-THUMBV7M + +define i32 @f1(i32 %a, i32 %b) { +entry: +; CHECK-THUMB: f1 +; CHECK-THUMB: __divsi3 +; CHECK-THUMBV7M: f1 +; CHECK-THUMBV7M: sdiv + %tmp1 = sdiv i32 %a, %b ; <i32> [#uses=1] + ret i32 %tmp1 +} + +define i32 @f2(i32 %a, i32 %b) { +entry: +; CHECK-THUMB: f2 +; CHECK-THUMB: __udivsi3 +; CHECK-THUMBV7M: f2 +; CHECK-THUMBV7M: udiv + %tmp1 = udiv i32 %a, %b ; <i32> [#uses=1] + ret i32 %tmp1 +} + +define i32 @f3(i32 %a, i32 %b) { +entry: +; CHECK-THUMB: f3 +; CHECK-THUMB: __modsi3 +; CHECK-THUMBV7M: f3 +; CHECK-THUMBV7M: sdiv + %tmp1 = srem i32 %a, %b ; <i32> [#uses=1] + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +entry: +; CHECK-THUMB: f4 +; CHECK-THUMB: __umodsi3 +; CHECK-THUMBV7M: f4 +; CHECK-THUMBV7M: udiv + %tmp1 = urem i32 %a, %b ; <i32> [#uses=1] + ret i32 %tmp1 +} +
diff --git a/src/LLVM/test/CodeGen/Thumb2/frameless.ll b/src/LLVM/test/CodeGen/Thumb2/frameless.ll new file mode 100644 index 0000000..fa8d5d8 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/frameless.ll
@@ -0,0 +1,6 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -disable-fp-elim | not grep mov +; RUN: llc < %s -mtriple=thumbv7-linux -disable-fp-elim | not grep mov + +define void @t() nounwind readnone { + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/frameless2.ll b/src/LLVM/test/CodeGen/Thumb2/frameless2.ll new file mode 100644 index 0000000..c5d3239 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/frameless2.ll
@@ -0,0 +1,12 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -disable-fp-elim | not grep r7 + +%struct.noise3 = type { [3 x [17 x i32]] } +%struct.noiseguard = type { i32, i32, i32 } + +define void @vorbis_encode_noisebias_setup(i8* nocapture %vi.0.7.val, double %s, i32 %block, i32* nocapture %suppress, %struct.noise3* nocapture %in, %struct.noiseguard* nocapture %guard, double %userbias) nounwind { +entry: + %0 = getelementptr %struct.noiseguard* %guard, i32 %block, i32 2; <i32*> [#uses=1] + %1 = load i32* %0, align 4 ; <i32> [#uses=1] + store i32 %1, i32* undef, align 4 + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/ifcvt-neon.ll b/src/LLVM/test/CodeGen/Thumb2/ifcvt-neon.ll new file mode 100644 index 0000000..6832053 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/ifcvt-neon.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -march=thumb -mcpu=cortex-a8 | FileCheck %s +; rdar://7368193 + +@a = common global float 0.000000e+00 ; <float*> [#uses=2] +@b = common global float 0.000000e+00 ; <float*> [#uses=1] + +define float @t(i32 %c) nounwind { +entry: + %0 = icmp sgt i32 %c, 1 ; <i1> [#uses=1] + %1 = load float* @a, align 4 ; <float> [#uses=2] + %2 = load float* @b, align 4 ; <float> [#uses=2] + br i1 %0, label %bb, label %bb1 + +bb: ; preds = %entry +; CHECK: ite lt +; CHECK: vsublt.f32 +; CHECK-NEXT: vaddge.f32 + %3 = fadd float %1, %2 ; <float> [#uses=1] + br label %bb2 + +bb1: ; preds = %entry + %4 = fsub float %1, %2 ; <float> [#uses=1] + br label %bb2 + +bb2: ; preds = %bb1, %bb + %storemerge = phi float [ %4, %bb1 ], [ %3, %bb ] ; <float> [#uses=2] + store float %storemerge, float* @a + ret float %storemerge +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/large-stack.ll b/src/LLVM/test/CodeGen/Thumb2/large-stack.ll new file mode 100644 index 0000000..68b5d1c --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/large-stack.ll
@@ -0,0 +1,39 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN +; RUN: llc < %s -march=thumb -mattr=+thumb2 -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=LINUX + +define void @test1() { +; DARWIN: test1: +; DARWIN: sub sp, #256 +; LINUX: test1: +; LINUX: sub sp, #256 + %tmp = alloca [ 64 x i32 ] , align 4 + ret void +} + +define void @test2() { +; DARWIN: test2: +; DARWIN: sub.w sp, sp, #4160 +; DARWIN: sub sp, #8 +; LINUX: test2: +; LINUX: sub.w sp, sp, #4160 +; LINUX: sub sp, #8 + %tmp = alloca [ 4168 x i8 ] , align 4 + ret void +} + +define i32 @test3() { +; DARWIN: test3: +; DARWIN: push {r4, r7, lr} +; DARWIN: sub.w sp, sp, #805306368 +; DARWIN: sub sp, #20 +; LINUX: test3: +; LINUX: push.w {r4, r7, r11, lr} +; LINUX: sub.w sp, sp, #805306368 +; LINUX: sub sp, #16 + %retval = alloca i32, align 4 + %tmp = alloca i32, align 4 + %a = alloca [805306369 x i8], align 16 + store i32 0, i32* %tmp + %tmp1 = load i32* %tmp + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/ldr-str-imm12.ll b/src/LLVM/test/CodeGen/Thumb2/ldr-str-imm12.ll new file mode 100644 index 0000000..4597ba5 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/ldr-str-imm12.ll
@@ -0,0 +1,76 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim -regalloc=linearscan | FileCheck %s +; rdar://7352504 +; Make sure we use "str r9, [sp, #+28]" instead of "sub.w r4, r7, #256" followed by "str r9, [r4, #-32]". + +%0 = type { i16, i8, i8 } +%1 = type { [2 x i32], [2 x i32] } +%2 = type { %union.rec* } +%struct.FILE_POS = type { i8, i8, i16, i32 } +%struct.GAP = type { i8, i8, i16 } +%struct.LIST = type { %union.rec*, %union.rec* } +%struct.STYLE = type { %union.anon, %union.anon, i16, i16, i32 } +%struct.head_type = type { [2 x %struct.LIST], %union.FIRST_UNION, %union.SECOND_UNION, %union.THIRD_UNION, %union.FOURTH_UNION, %union.rec*, %2, %union.rec*, %union.rec*, %union.rec*, %union.rec*, %union.rec*, %union.rec*, %union.rec*, %union.rec*, i32 } +%union.FIRST_UNION = type { %struct.FILE_POS } +%union.FOURTH_UNION = type { %struct.STYLE } +%union.SECOND_UNION = type { %0 } +%union.THIRD_UNION = type { %1 } +%union.anon = type { %struct.GAP } +%union.rec = type { %struct.head_type } + +@zz_hold = external global %union.rec* ; <%union.rec**> [#uses=2] +@zz_res = external global %union.rec* ; <%union.rec**> [#uses=1] + +define %union.rec* @Manifest(%union.rec* %x, %union.rec* %env, %struct.STYLE* %style, %union.rec** %bthr, %union.rec** %fthr, %union.rec** %target, %union.rec** %crs, i32 %ok, i32 %need_expand, %union.rec** %enclose, i32 %fcr) nounwind { +entry: +; CHECK: ldr{{(.w)?}} {{(r[0-9]+)|(lr)}}, [r7, #28] + %xgaps.i = alloca [32 x %union.rec*], align 4 ; <[32 x %union.rec*]*> [#uses=0] + %ycomp.i = alloca [32 x %union.rec*], align 4 ; <[32 x %union.rec*]*> [#uses=0] + br label %bb20 + +bb20: ; preds = %entry + switch i32 undef, label %bb1287 [ + i32 11, label %bb119 + i32 12, label %bb119 + i32 21, label %bb420 + i32 23, label %bb420 + i32 45, label %bb438 + i32 46, label %bb438 + i32 55, label %bb533 + i32 56, label %bb569 + i32 64, label %bb745 + i32 78, label %bb1098 + ] + +bb119: ; preds = %bb20, %bb20 + unreachable + +bb420: ; preds = %bb20, %bb20 +; CHECK: bb420 +; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp] +; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #4] +; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #8] +; CHECK: str{{(.w)?}} r{{[0-9]+}}, [sp, #24] + store %union.rec* null, %union.rec** @zz_hold, align 4 + store %union.rec* null, %union.rec** @zz_res, align 4 + store %union.rec* %x, %union.rec** @zz_hold, align 4 + %0 = call %union.rec* @Manifest(%union.rec* undef, %union.rec* %env, %struct.STYLE* %style, %union.rec** %bthr, %union.rec** %fthr, %union.rec** %target, %union.rec** %crs, i32 %ok, i32 %need_expand, %union.rec** %enclose, i32 %fcr) nounwind ; <%union.rec*> [#uses=0] + unreachable + +bb438: ; preds = %bb20, %bb20 + unreachable + +bb533: ; preds = %bb20 + ret %union.rec* %x + +bb569: ; preds = %bb20 + unreachable + +bb745: ; preds = %bb20 + unreachable + +bb1098: ; preds = %bb20 + unreachable + +bb1287: ; preds = %bb20 + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/lsr-deficiency.ll b/src/LLVM/test/CodeGen/Thumb2/lsr-deficiency.ll new file mode 100644 index 0000000..9ff114e --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/lsr-deficiency.ll
@@ -0,0 +1,41 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin10 -relocation-model=pic | FileCheck %s +; rdar://7387640 + +; This now reduces to a single induction variable. + +; TODO: It still gets a GPR shuffle at the end of the loop +; This is because something in instruction selection has decided +; that comparing the pre-incremented value with zero is better +; than comparing the post-incremented value with -4. + +@G = external global i32 ; <i32*> [#uses=2] +@array = external global i32* ; <i32**> [#uses=1] + +define void @t() nounwind optsize { +; CHECK: t: +; CHECK: mov{{.*}}, #1000 +entry: + %.pre = load i32* @G, align 4 ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb, %entry +; CHECK: LBB0_1: +; CHECK: cmp [[R2:r[0-9]+]], #0 +; CHECK: sub{{(.w)?}} [[REGISTER:(r[0-9]+)|(lr)]], [[R2]], #1 +; CHECK: mov [[R2]], [[REGISTER]] + + %0 = phi i32 [ %.pre, %entry ], [ %3, %bb ] ; <i32> [#uses=1] + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2] + %tmp5 = sub i32 1000, %indvar ; <i32> [#uses=1] + %1 = load i32** @array, align 4 ; <i32*> [#uses=1] + %scevgep = getelementptr i32* %1, i32 %tmp5 ; <i32*> [#uses=1] + %2 = load i32* %scevgep, align 4 ; <i32> [#uses=1] + %3 = add nsw i32 %2, %0 ; <i32> [#uses=2] + store i32 %3, i32* @G, align 4 + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 1001 ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/machine-licm.ll b/src/LLVM/test/CodeGen/Thumb2/machine-licm.ll new file mode 100644 index 0000000..46937fc --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/machine-licm.ll
@@ -0,0 +1,121 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=dynamic-no-pic -disable-fp-elim | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim | FileCheck %s --check-prefix=PIC +; rdar://7353541 +; rdar://7354376 + +@GV = external global i32 ; <i32*> [#uses=2] + +define void @t1(i32* nocapture %vals, i32 %c) nounwind { +entry: +; CHECK: t1: +; CHECK: bxeq lr + + %0 = icmp eq i32 %c, 0 ; <i1> [#uses=1] + br i1 %0, label %return, label %bb.nph + +bb.nph: ; preds = %entry +; CHECK: movw r[[R2:[0-9]+]], :lower16:L_GV$non_lazy_ptr +; CHECK: movt r[[R2]], :upper16:L_GV$non_lazy_ptr +; CHECK: ldr{{(.w)?}} r[[R2b:[0-9]+]], [r[[R2]] +; CHECK: ldr{{.*}}, [r[[R2b]] +; CHECK: LBB0_ +; CHECK-NOT: LCPI0_0: + +; PIC: movw r[[R2:[0-9]+]], :lower16:(L_GV$non_lazy_ptr-(LPC0_0+4)) +; PIC: movt r[[R2]], :upper16:(L_GV$non_lazy_ptr-(LPC0_0+4)) +; PIC: add r[[R2]], pc +; PIC: ldr{{(.w)?}} r[[R2b:[0-9]+]], [r[[R2]] +; PIC: ldr{{.*}}, [r[[R2b]] +; PIC: LBB0_ +; PIC-NOT: LCPI0_0: +; PIC: .section + %.pre = load i32* @GV, align 4 ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %1 = phi i32 [ %.pre, %bb.nph ], [ %3, %bb ] ; <i32> [#uses=1] + %i.03 = phi i32 [ 0, %bb.nph ], [ %4, %bb ] ; <i32> [#uses=2] + %scevgep = getelementptr i32* %vals, i32 %i.03 ; <i32*> [#uses=1] + %2 = load i32* %scevgep, align 4 ; <i32> [#uses=1] + %3 = add nsw i32 %1, %2 ; <i32> [#uses=2] + store i32 %3, i32* @GV, align 4 + %4 = add i32 %i.03, 1 ; <i32> [#uses=2] + %exitcond = icmp eq i32 %4, %c ; <i1> [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} + +; rdar://8001136 +define void @t2(i8* %ptr1, i8* %ptr2) nounwind { +entry: +; CHECK: t2: +; CHECK: mov.w [[R3:r[0-9]+]], #1065353216 +; CHECK: vdup.32 q{{.*}}, [[R3]] + br i1 undef, label %bb1, label %bb2 + +bb1: +; CHECK-NEXT: %bb1 + %indvar = phi i32 [ %indvar.next, %bb1 ], [ 0, %entry ] + %tmp1 = shl i32 %indvar, 2 + %gep1 = getelementptr i8* %ptr1, i32 %tmp1 + %tmp2 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %gep1, i32 1) + %tmp3 = call <4 x float> @llvm.arm.neon.vmaxs.v4f32(<4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, <4 x float> %tmp2) + %gep2 = getelementptr i8* %ptr2, i32 %tmp1 + call void @llvm.arm.neon.vst1.v4f32(i8* %gep2, <4 x float> %tmp3, i32 1) + %indvar.next = add i32 %indvar, 1 + %cond = icmp eq i32 %indvar.next, 10 + br i1 %cond, label %bb2, label %bb1 + +bb2: + ret void +} + +; CHECK-NOT: LCPI1_0: + +declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly + +declare void @llvm.arm.neon.vst1.v4f32(i8*, <4 x float>, i32) nounwind + +declare <4 x float> @llvm.arm.neon.vmaxs.v4f32(<4 x float>, <4 x float>) nounwind readnone + +; rdar://8241368 +; isel should not fold immediate into eor's which would have prevented LICM. +define zeroext i16 @t3(i8 zeroext %data, i16 zeroext %crc) nounwind readnone { +; CHECK: t3: +bb.nph: +; CHECK: bb.nph +; CHECK: movw {{(r[0-9])|(lr)}}, #32768 +; CHECK: movs {{(r[0-9]+)|(lr)}}, #0 +; CHECK: movw [[REGISTER:(r[0-9]+)|(lr)]], #16386 +; CHECK: movw {{(r[0-9]+)|(lr)}}, #65534 +; CHECK: movt {{(r[0-9]+)|(lr)}}, #65535 + br label %bb + +bb: ; preds = %bb, %bb.nph +; CHECK: bb +; CHECK: eor.w {{(r[0-9])|(lr)}}, {{(r[0-9])|(lr)}}, [[REGISTER]] +; CHECK: eor.w +; CHECK-NOT: eor +; CHECK: and + %data_addr.013 = phi i8 [ %data, %bb.nph ], [ %8, %bb ] ; <i8> [#uses=2] + %crc_addr.112 = phi i16 [ %crc, %bb.nph ], [ %crc_addr.2, %bb ] ; <i16> [#uses=3] + %i.011 = phi i8 [ 0, %bb.nph ], [ %7, %bb ] ; <i8> [#uses=1] + %0 = trunc i16 %crc_addr.112 to i8 ; <i8> [#uses=1] + %1 = xor i8 %data_addr.013, %0 ; <i8> [#uses=1] + %2 = and i8 %1, 1 ; <i8> [#uses=1] + %3 = icmp eq i8 %2, 0 ; <i1> [#uses=2] + %4 = xor i16 %crc_addr.112, 16386 ; <i16> [#uses=1] + %crc_addr.0 = select i1 %3, i16 %crc_addr.112, i16 %4 ; <i16> [#uses=1] + %5 = lshr i16 %crc_addr.0, 1 ; <i16> [#uses=2] + %6 = or i16 %5, -32768 ; <i16> [#uses=1] + %crc_addr.2 = select i1 %3, i16 %5, i16 %6 ; <i16> [#uses=2] + %7 = add i8 %i.011, 1 ; <i8> [#uses=2] + %8 = lshr i8 %data_addr.013, 1 ; <i8> [#uses=1] + %exitcond = icmp eq i8 %7, 8 ; <i1> [#uses=1] + br i1 %exitcond, label %bb8, label %bb + +bb8: ; preds = %bb + ret i16 %crc_addr.2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/mul_const.ll b/src/LLVM/test/CodeGen/Thumb2/mul_const.ll new file mode 100644 index 0000000..9a2ec93 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/mul_const.ll
@@ -0,0 +1,18 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; rdar://7069502 + +define i32 @t1(i32 %v) nounwind readnone { +entry: +; CHECK: t1: +; CHECK: add.w r0, r0, r0, lsl #3 + %0 = mul i32 %v, 9 + ret i32 %0 +} + +define i32 @t2(i32 %v) nounwind readnone { +entry: +; CHECK: t2: +; CHECK: rsb r0, r0, r0, lsl #3 + %0 = mul i32 %v, 7 + ret i32 %0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/pic-load.ll b/src/LLVM/test/CodeGen/Thumb2/pic-load.ll new file mode 100644 index 0000000..35a03e7 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/pic-load.ll
@@ -0,0 +1,21 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -relocation-model=pic | FileCheck %s + + %struct.anon = type { void ()* } + %struct.one_atexit_routine = type { %struct.anon, i32, i8* } +@__dso_handle = external global { } ; <{ }*> [#uses=1] +@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 (void ()*)* @atexit to i8*)], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define hidden i32 @atexit(void ()* %func) nounwind { +entry: +; CHECK: atexit: +; CHECK: add r0, pc + %r = alloca %struct.one_atexit_routine, align 4 ; <%struct.one_atexit_routine*> [#uses=3] + %0 = getelementptr %struct.one_atexit_routine* %r, i32 0, i32 0, i32 0 ; <void ()**> [#uses=1] + store void ()* %func, void ()** %0, align 4 + %1 = getelementptr %struct.one_atexit_routine* %r, i32 0, i32 1 ; <i32*> [#uses=1] + store i32 0, i32* %1, align 4 + %2 = call i32 @atexit_common(%struct.one_atexit_routine* %r, i8* bitcast ({ }* @__dso_handle to i8*)) nounwind ; <i32> [#uses=1] + ret i32 %2 +} + +declare i32 @atexit_common(%struct.one_atexit_routine*, i8*) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-adc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-adc.ll new file mode 100644 index 0000000..702df91 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-adc.ll
@@ -0,0 +1,48 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 734439407618 = 0x000000ab00000002 +define i64 @f1(i64 %a) { +; CHECK: f1: +; CHECK: adds r0, #2 + %tmp = add i64 %a, 734439407618 + ret i64 %tmp +} + +; 5066626890203138 = 0x0012001200000002 +define i64 @f2(i64 %a) { +; CHECK: f2: +; CHECK: adds r0, #2 + %tmp = add i64 %a, 5066626890203138 + ret i64 %tmp +} + +; 3747052064576897026 = 0x3400340000000002 +define i64 @f3(i64 %a) { +; CHECK: f3: +; CHECK: adds r0, #2 + %tmp = add i64 %a, 3747052064576897026 + ret i64 %tmp +} + +; 6221254862626095106 = 0x5656565600000002 +define i64 @f4(i64 %a) { +; CHECK: f4: +; CHECK: adds r0, #2 + %tmp = add i64 %a, 6221254862626095106 + ret i64 %tmp +} + +; 287104476244869122 = 0x03fc000000000002 +define i64 @f5(i64 %a) { +; CHECK: f5: +; CHECK: adds r0, #2 + %tmp = add i64 %a, 287104476244869122 + ret i64 %tmp +} + +define i64 @f6(i64 %a, i64 %b) { +; CHECK: f6: +; CHECK: adds r0, r0, r2 + %tmp = add i64 %a, %b + ret i64 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add.ll new file mode 100644 index 0000000..66fca13 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add.ll
@@ -0,0 +1,83 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @t2ADDrc_255(i32 %lhs) { +; CHECK: t2ADDrc_255: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #255 +; CHECK: bx lr + + %Rd = add i32 %lhs, 255 + ret i32 %Rd +} + +define i32 @t2ADDrc_256(i32 %lhs) { +; CHECK: t2ADDrc_256: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #256 +; CHECK: bx lr + + %Rd = add i32 %lhs, 256 + ret i32 %Rd +} + +define i32 @t2ADDrc_257(i32 %lhs) { +; CHECK: t2ADDrc_257: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #257 +; CHECK: bx lr + + %Rd = add i32 %lhs, 257 + ret i32 %Rd +} + +define i32 @t2ADDrc_4094(i32 %lhs) { +; CHECK: t2ADDrc_4094: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #4094 +; CHECK: bx lr + + %Rd = add i32 %lhs, 4094 + ret i32 %Rd +} + +define i32 @t2ADDrc_4095(i32 %lhs) { +; CHECK: t2ADDrc_4095: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #4095 +; CHECK: bx lr + + %Rd = add i32 %lhs, 4095 + ret i32 %Rd +} + +define i32 @t2ADDrc_4096(i32 %lhs) { +; CHECK: t2ADDrc_4096: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} #4096 +; CHECK: bx lr + + %Rd = add i32 %lhs, 4096 + ret i32 %Rd +} + +define i32 @t2ADDrr(i32 %lhs, i32 %rhs) { +; CHECK: t2ADDrr: +; CHECK-NOT: bx lr +; CHECK: add +; CHECK: bx lr + + %Rd = add i32 %lhs, %rhs + ret i32 %Rd +} + +define i32 @t2ADDrs(i32 %lhs, i32 %rhs) { +; CHECK: t2ADDrs: +; CHECK-NOT: bx lr +; CHECK: add{{.*}} lsl #8 +; CHECK: bx lr + + %tmp = shl i32 %rhs, 8 + %Rd = add i32 %lhs, %tmp + ret i32 %Rd +} +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add2.ll new file mode 100644 index 0000000..e496654 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add2.ll
@@ -0,0 +1,41 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 171 = 0x000000ab +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: adds r0, #171 + %tmp = add i32 %a, 171 + ret i32 %tmp +} + +; 1179666 = 0x00120012 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: add.w r0, r0, #1179666 + %tmp = add i32 %a, 1179666 + ret i32 %tmp +} + +; 872428544 = 0x34003400 +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: add.w r0, r0, #872428544 + %tmp = add i32 %a, 872428544 + ret i32 %tmp +} + +; 1448498774 = 0x56565656 +define i32 @f4(i32 %a) { +; CHECK: f4: +; CHECK: add.w r0, r0, #1448498774 + %tmp = add i32 %a, 1448498774 + ret i32 %tmp +} + +; 510 = 0x000001fe +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: add.w r0, r0, #510 + %tmp = add i32 %a, 510 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add3.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add3.ll new file mode 100644 index 0000000..58fc333 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add3.ll
@@ -0,0 +1,9 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { + %tmp = add i32 %a, 4095 + ret i32 %tmp +} + +; CHECK: f1: +; CHECK: addw r0, r0, #4095
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add4.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add4.ll new file mode 100644 index 0000000..b94e84d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add4.ll
@@ -0,0 +1,46 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 171 = 0x000000ab +define i64 @f1(i64 %a) { +; CHECK: f1: +; CHECK: adds r0, #171 +; CHECK: adc r1, r1, #0 + %tmp = add i64 %a, 171 + ret i64 %tmp +} + +; 1179666 = 0x00120012 +define i64 @f2(i64 %a) { +; CHECK: f2: +; CHECK: adds.w r0, r0, #1179666 +; CHECK: adc r1, r1, #0 + %tmp = add i64 %a, 1179666 + ret i64 %tmp +} + +; 872428544 = 0x34003400 +define i64 @f3(i64 %a) { +; CHECK: f3: +; CHECK: adds.w r0, r0, #872428544 +; CHECK: adc r1, r1, #0 + %tmp = add i64 %a, 872428544 + ret i64 %tmp +} + +; 1448498774 = 0x56565656 +define i64 @f4(i64 %a) { +; CHECK: f4: +; CHECK: adds.w r0, r0, #1448498774 +; CHECK: adc r1, r1, #0 + %tmp = add i64 %a, 1448498774 + ret i64 %tmp +} + +; 66846720 = 0x03fc0000 +define i64 @f5(i64 %a) { +; CHECK: f5: +; CHECK: adds.w r0, r0, #66846720 +; CHECK: adc r1, r1, #0 + %tmp = add i64 %a, 66846720 + ret i64 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add5.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add5.ll new file mode 100644 index 0000000..8b3a4f6 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add5.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: add r0, r1 + %tmp = add i32 %a, %b + ret i32 %tmp +} + +define i32 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: add.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = add i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f3(i32 %a, i32 %b) { +; CHECK: f3: +; CHECK: add.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = add i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: add.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = add i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: add.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = add i32 %a, %tmp + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-add6.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-add6.ll new file mode 100644 index 0000000..0ecaa79 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-add6.ll
@@ -0,0 +1,9 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i64 @f1(i64 %a, i64 %b) { +; CHECK: f1: +; CHECK: adds r0, r0, r2 +; CHECK: adcs r1, r3 + %tmp = add i64 %a, %b + ret i64 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-and.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-and.ll new file mode 100644 index 0000000..8e2245a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-and.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: ands r0, r1 + %tmp = and i32 %a, %b + ret i32 %tmp +} + +define i32 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: and.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f3(i32 %a, i32 %b) { +; CHECK: f3: +; CHECK: and.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: and.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: and.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-and2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-and2.ll new file mode 100644 index 0000000..7b0432d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-and2.ll
@@ -0,0 +1,41 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 171 = 0x000000ab +define i32 @f1(i32 %a) { + %tmp = and i32 %a, 171 + ret i32 %tmp +} +; CHECK: f1: +; CHECK: and r0, r0, #171 + +; 1179666 = 0x00120012 +define i32 @f2(i32 %a) { + %tmp = and i32 %a, 1179666 + ret i32 %tmp +} +; CHECK: f2: +; CHECK: and r0, r0, #1179666 + +; 872428544 = 0x34003400 +define i32 @f3(i32 %a) { + %tmp = and i32 %a, 872428544 + ret i32 %tmp +} +; CHECK: f3: +; CHECK: and r0, r0, #872428544 + +; 1448498774 = 0x56565656 +define i32 @f4(i32 %a) { + %tmp = and i32 %a, 1448498774 + ret i32 %tmp +} +; CHECK: f4: +; CHECK: bic r0, r0, #-1448498775 + +; 66846720 = 0x03fc0000 +define i32 @f5(i32 %a) { + %tmp = and i32 %a, 66846720 + ret i32 %tmp +} +; CHECK: f5: +; CHECK: and r0, r0, #66846720
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-asr.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-asr.ll new file mode 100644 index 0000000..a0a60e6 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-asr.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: asrs r0, r1 + %tmp = ashr i32 %a, %b + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-asr2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-asr2.ll new file mode 100644 index 0000000..9c8634f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-asr2.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: asrs r0, r0, #17 + %tmp = ashr i32 %a, 17 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-bcc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-bcc.ll new file mode 100644 index 0000000..4a2d600 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-bcc.ll
@@ -0,0 +1,23 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s +; If-conversion defeats the purpose of this test, which is to check CBZ +; generation, so use memory barrier instruction to make sure it doesn't +; happen and we get actual branches. + +define i32 @t1(i32 %a, i32 %b, i32 %c) { +; CHECK: t1: +; CHECK: cbz + %tmp2 = icmp eq i32 %a, 0 + br i1 %tmp2, label %cond_false, label %cond_true + +cond_true: + fence seq_cst + %tmp5 = add i32 %b, 1 + %tmp6 = and i32 %tmp5, %c + ret i32 %tmp6 + +cond_false: + fence seq_cst + %tmp7 = add i32 %b, -1 + %tmp8 = xor i32 %tmp7, %c + ret i32 %tmp8 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-bfc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-bfc.ll new file mode 100644 index 0000000..b486045 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-bfc.ll
@@ -0,0 +1,32 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 4278190095 = 0xff00000f +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: bfc r + %tmp = and i32 %a, 4278190095 + ret i32 %tmp +} + +; 4286578688 = 0xff800000 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: bfc r + %tmp = and i32 %a, 4286578688 + ret i32 %tmp +} + +; 4095 = 0x00000fff +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: bfc r + %tmp = and i32 %a, 4095 + ret i32 %tmp +} + +; 2147483646 = 0x7ffffffe not implementable w/ BFC +define i32 @f4(i32 %a) { +; CHECK: f4: + %tmp = and i32 %a, 2147483646 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-bic.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-bic.ll new file mode 100644 index 0000000..4e35383 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-bic.ll
@@ -0,0 +1,105 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: bics r0, r1 + %tmp = xor i32 %b, 4294967295 + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: bics r0, r1 + %tmp = xor i32 %b, 4294967295 + %tmp1 = and i32 %tmp, %a + ret i32 %tmp1 +} + +define i32 @f3(i32 %a, i32 %b) { +; CHECK: f3: +; CHECK: bics r0, r1 + %tmp = xor i32 4294967295, %b + %tmp1 = and i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: bics r0, r1 + %tmp = xor i32 4294967295, %b + %tmp1 = and i32 %tmp, %a + ret i32 %tmp1 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: bic.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = and i32 %a, %tmp1 + ret i32 %tmp2 +} + +define i32 @f6(i32 %a, i32 %b) { +; CHECK: f6: +; CHECK: bic.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = xor i32 %tmp, 4294967295 + %tmp2 = and i32 %tmp1, %a + ret i32 %tmp2 +} + +define i32 @f7(i32 %a, i32 %b) { +; CHECK: f7: +; CHECK: bic.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = xor i32 %tmp, 4294967295 + %tmp2 = and i32 %a, %tmp1 + ret i32 %tmp2 +} + +define i32 @f8(i32 %a, i32 %b) { +; CHECK: f8: +; CHECK: bic.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = and i32 %tmp1, %a + ret i32 %tmp2 +} + +; ~0x000000bb = 4294967108 +define i32 @f9(i32 %a) { + %tmp = and i32 %a, 4294967108 + ret i32 %tmp + +; CHECK: f9: +; CHECK: bic r0, r0, #187 +} + +; ~0x00aa00aa = 4283826005 +define i32 @f10(i32 %a) { + %tmp = and i32 %a, 4283826005 + ret i32 %tmp + +; CHECK: f10: +; CHECK: bic r0, r0, #11141290 +} + +; ~0xcc00cc00 = 872363007 +define i32 @f11(i32 %a) { + %tmp = and i32 %a, 872363007 + ret i32 %tmp +; CHECK: f11: +; CHECK: bic r0, r0, #-872363008 +} + +; ~0x00110000 = 4293853183 +define i32 @f12(i32 %a) { + %tmp = and i32 %a, 4293853183 + ret i32 %tmp +; CHECK: f12: +; CHECK: bic r0, r0, #1114112 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-branch.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-branch.ll new file mode 100644 index 0000000..27d8e8f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-branch.ll
@@ -0,0 +1,72 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 | FileCheck %s +; If-conversion defeats the purpose of this test, which is to check conditional +; branch generation, so use memory barrier instruction to make sure it doesn't +; happen and we get actual branches. + +define i32 @f1(i32 %a, i32 %b, i32* %v) { +entry: +; CHECK: f1: +; CHECK: bne LBB + %tmp = icmp eq i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %return + +cond_true: ; preds = %entry + fence seq_cst + store i32 0, i32* %v + ret i32 0 + +return: ; preds = %entry + fence seq_cst + ret i32 1 +} + +define i32 @f2(i32 %a, i32 %b, i32* %v) { +entry: +; CHECK: f2: +; CHECK: bge LBB + %tmp = icmp slt i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %return + +cond_true: ; preds = %entry + fence seq_cst + store i32 0, i32* %v + ret i32 0 + +return: ; preds = %entry + fence seq_cst + ret i32 1 +} + +define i32 @f3(i32 %a, i32 %b, i32* %v) { +entry: +; CHECK: f3: +; CHECK: bhs LBB + %tmp = icmp ult i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp, label %cond_true, label %return + +cond_true: ; preds = %entry + fence seq_cst + store i32 0, i32* %v + ret i32 0 + +return: ; preds = %entry + fence seq_cst + ret i32 1 +} + +define i32 @f4(i32 %a, i32 %b, i32* %v) { +entry: +; CHECK: f4: +; CHECK: blo LBB + %tmp = icmp ult i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp, label %return, label %cond_true + +cond_true: ; preds = %entry + fence seq_cst + store i32 0, i32* %v + ret i32 0 + +return: ; preds = %entry + fence seq_cst + ret i32 1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-call-tc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-call-tc.ll new file mode 100644 index 0000000..2e4da1b --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-call-tc.ll
@@ -0,0 +1,38 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 | FileCheck %s -check-prefix=DARWIN +; RUN: llc < %s -mtriple=thumbv7-linux -mattr=+thumb2 | FileCheck %s -check-prefix=LINUX +; XFAIL: * + +@t = weak global i32 ()* null ; <i32 ()**> [#uses=1] + +declare void @g(i32, i32, i32, i32) + +define void @f() { +; DARWIN: f: +; DARWIN: blx _g + +; LINUX: f: +; LINUX: bl g + tail call void @g( i32 1, i32 2, i32 3, i32 4 ) + ret void +} + +define void @h() { +; DARWIN: h: +; DARWIN: bx r0 @ TAILCALL + +; LINUX: h: +; LINUX: bx r0 @ TAILCALL + %tmp = load i32 ()** @t ; <i32 ()*> [#uses=1] + %tmp.upgrd.2 = tail call i32 %tmp( ) ; <i32> [#uses=0] + ret void +} + +define void @j() { +; DARWIN: j: +; DARWIN: b.w _f @ TAILCALL + +; LINUX: j: +; LINUX: b.w f @ TAILCALL + tail call void @f() + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-call.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-call.ll new file mode 100644 index 0000000..8513cfb --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-call.ll
@@ -0,0 +1,27 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 | FileCheck %s -check-prefix=DARWIN +; RUN: llc < %s -mtriple=thumbv7-linux -mattr=+thumb2 | FileCheck %s -check-prefix=LINUX + +@t = weak global i32 ()* null ; <i32 ()**> [#uses=1] + +declare void @g(i32, i32, i32, i32) + +define void @f() { +; DARWIN: f: +; DARWIN: blx _g + +; LINUX: f: +; LINUX: bl g + call void @g( i32 1, i32 2, i32 3, i32 4 ) + ret void +} + +define void @h() { +; DARWIN: h: +; DARWIN: blx r0 + +; LINUX: h: +; LINUX: blx r0 + %tmp = load i32 ()** @t ; <i32 ()*> [#uses=1] + %tmp.upgrd.2 = call i32 %tmp( ) ; <i32> [#uses=0] + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-cbnz.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-cbnz.ll new file mode 100644 index 0000000..0992fa8 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-cbnz.ll
@@ -0,0 +1,36 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mcpu=cortex-a8 | FileCheck %s +; rdar://7354379 + +declare double @floor(double) nounwind readnone + +define void @t(i32 %c, double %b) { +entry: + %cmp1 = icmp ne i32 %c, 0 + br i1 %cmp1, label %bb3, label %bb1 + +bb1: ; preds = %entry + unreachable + +bb3: ; preds = %entry + %cmp2 = icmp ne i32 %c, 0 + br i1 %cmp2, label %bb7, label %bb5 + +bb5: ; preds = %bb3 + unreachable + +bb7: ; preds = %bb3 + %cmp3 = icmp ne i32 %c, 0 + br i1 %cmp3, label %bb11, label %bb9 + +bb9: ; preds = %bb7 +; CHECK: cmp r0, #0 +; CHECK: cmp r0, #0 +; CHECK-NEXT: cbnz + %0 = tail call double @floor(double %b) nounwind readnone ; <double> [#uses=0] + br label %bb11 + +bb11: ; preds = %bb9, %bb7 + %1 = getelementptr i32* undef, i32 0 + store i32 0, i32* %1 + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-clz.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-clz.ll new file mode 100644 index 0000000..00a54a0 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-clz.ll
@@ -0,0 +1,10 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: clz r + %tmp = tail call i32 @llvm.ctlz.i32(i32 %a) + ret i32 %tmp +} + +declare i32 @llvm.ctlz.i32(i32) nounwind readnone
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn.ll new file mode 100644 index 0000000..df221b9 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn.ll
@@ -0,0 +1,75 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; test as 'mov.w r0, #0'. So far, that requires physreg joining. + +define i1 @f1(i32 %a, i32 %b) { + %nb = sub i32 0, %b + %tmp = icmp ne i32 %a, %nb + ret i1 %tmp +} +; CHECK: f1: +; CHECK: cmn.w r0, r1 + +define i1 @f2(i32 %a, i32 %b) { + %nb = sub i32 0, %b + %tmp = icmp ne i32 %nb, %a + ret i1 %tmp +} +; CHECK: f2: +; CHECK: cmn.w r0, r1 + +define i1 @f3(i32 %a, i32 %b) { + %nb = sub i32 0, %b + %tmp = icmp eq i32 %a, %nb + ret i1 %tmp +} +; CHECK: f3: +; CHECK: cmn.w r0, r1 + +define i1 @f4(i32 %a, i32 %b) { + %nb = sub i32 0, %b + %tmp = icmp eq i32 %nb, %a + ret i1 %tmp +} +; CHECK: f4: +; CHECK: cmn.w r0, r1 + +define i1 @f5(i32 %a, i32 %b) { + %tmp = shl i32 %b, 5 + %nb = sub i32 0, %tmp + %tmp1 = icmp eq i32 %nb, %a + ret i1 %tmp1 +} +; CHECK: f5: +; CHECK: cmn.w r0, r1, lsl #5 + +define i1 @f6(i32 %a, i32 %b) { + %tmp = lshr i32 %b, 6 + %nb = sub i32 0, %tmp + %tmp1 = icmp ne i32 %nb, %a + ret i1 %tmp1 +} +; CHECK: f6: +; CHECK: cmn.w r0, r1, lsr #6 + +define i1 @f7(i32 %a, i32 %b) { + %tmp = ashr i32 %b, 7 + %nb = sub i32 0, %tmp + %tmp1 = icmp eq i32 %a, %nb + ret i1 %tmp1 +} +; CHECK: f7: +; CHECK: cmn.w r0, r1, asr #7 + +define i1 @f8(i32 %a, i32 %b) { + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %nb = sub i32 0, %tmp + %tmp1 = icmp ne i32 %a, %nb + ret i1 %tmp1 +} +; CHECK: f8: +; CHECK: cmn.w r0, r0, ror #8 +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn2.ll new file mode 100644 index 0000000..c0e19f6 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmn2.ll
@@ -0,0 +1,33 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; -0x000000bb = 4294967109 +define i1 @f1(i32 %a) { +; CHECK: f1: +; CHECK: cmn.w {{r.*}}, #187 + %tmp = icmp ne i32 %a, 4294967109 + ret i1 %tmp +} + +; -0x00aa00aa = 4283826006 +define i1 @f2(i32 %a) { +; CHECK: f2: +; CHECK: cmn.w {{r.*}}, #11141290 + %tmp = icmp eq i32 %a, 4283826006 + ret i1 %tmp +} + +; -0xcc00cc00 = 872363008 +define i1 @f3(i32 %a) { +; CHECK: f3: +; CHECK: cmn.w {{r.*}}, #-872363008 + %tmp = icmp ne i32 %a, 872363008 + ret i1 %tmp +} + +; -0x00110000 = 4293853184 +define i1 @f4(i32 %a) { +; CHECK: f4: +; CHECK: cmn.w {{r.*}}, #1114112 + %tmp = icmp eq i32 %a, 4293853184 + ret i1 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp.ll new file mode 100644 index 0000000..da12114 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp.ll
@@ -0,0 +1,58 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; test as 'mov.w r0, #0'. So far, that requires physreg joining. + +; 0x000000bb = 187 +define i1 @f1(i32 %a) { +; CHECK: f1: +; CHECK: cmp r0, #187 + %tmp = icmp ne i32 %a, 187 + ret i1 %tmp +} + +; 0x00aa00aa = 11141290 +define i1 @f2(i32 %a) { +; CHECK: f2: +; CHECK: cmp.w r0, #11141290 + %tmp = icmp eq i32 %a, 11141290 + ret i1 %tmp +} + +; 0xcc00cc00 = 3422604288 +define i1 @f3(i32 %a) { +; CHECK: f3: +; CHECK: cmp.w r0, #-872363008 + %tmp = icmp ne i32 %a, 3422604288 + ret i1 %tmp +} + +; 0xdddddddd = 3722304989 +define i1 @f4(i32 %a) { +; CHECK: f4: +; CHECK: cmp.w r0, #-572662307 + %tmp = icmp ne i32 %a, 3722304989 + ret i1 %tmp +} + +; 0x00110000 = 1114112 +define i1 @f5(i32 %a) { +; CHECK: f5: +; CHECK: cmp.w r0, #1114112 + %tmp = icmp eq i32 %a, 1114112 + ret i1 %tmp +} + +; Check that we don't do an invalid (a > b) --> !(a < b + 1) transform. +; +; CHECK: f6: +; CHECK-NOT: cmp.w r0, #-2147483648 +; CHECK: bx lr +define i32 @f6(i32 %a) { + %tmp = icmp sgt i32 %a, 2147483647 + br i1 %tmp, label %true, label %false +true: + ret i32 2 +false: + ret i32 0 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp2.ll new file mode 100644 index 0000000..15052e0 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-cmp2.ll
@@ -0,0 +1,52 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; test as 'mov.w r0, #0'. So far, that requires physreg joining. + +define i1 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: cmp r0, r1 + %tmp = icmp ne i32 %a, %b + ret i1 %tmp +} + +define i1 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: cmp r0, r1 + %tmp = icmp eq i32 %a, %b + ret i1 %tmp +} + +define i1 @f6(i32 %a, i32 %b) { +; CHECK: f6: +; CHECK: cmp.w r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = icmp eq i32 %tmp, %a + ret i1 %tmp1 +} + +define i1 @f7(i32 %a, i32 %b) { +; CHECK: f7: +; CHECK: cmp.w r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = icmp ne i32 %tmp, %a + ret i1 %tmp1 +} + +define i1 @f8(i32 %a, i32 %b) { +; CHECK: f8: +; CHECK: cmp.w r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = icmp eq i32 %a, %tmp + ret i1 %tmp1 +} + +define i1 @f9(i32 %a, i32 %b) { +; CHECK: f9: +; CHECK: cmp.w r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = icmp ne i32 %a, %tmp + ret i1 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-eor.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-eor.ll new file mode 100644 index 0000000..116a1a3 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-eor.ll
@@ -0,0 +1,56 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: eors r0, r1 + %tmp = xor i32 %a, %b + ret i32 %tmp +} + +define i32 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: eors r0, r1 + %tmp = xor i32 %b, %a + ret i32 %tmp +} + +define i32 @f2b(i32 %a, i32 %b, i32 %c) { +; CHECK: f2b: +; CHECK: eor.w r0, r1, r2 + %tmp = xor i32 %b, %c + ret i32 %tmp +} + +define i32 @f3(i32 %a, i32 %b) { +; CHECK: f3: +; CHECK: eor.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = xor i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: eor.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = xor i32 %tmp, %a + ret i32 %tmp1 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: eor.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = xor i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f6(i32 %a, i32 %b) { +; CHECK: f6: +; CHECK: eor.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = xor i32 %tmp, %a + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-eor2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-eor2.ll new file mode 100644 index 0000000..6b2e9dc --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-eor2.ll
@@ -0,0 +1,41 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 0x000000bb = 187 +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: eor {{.*}}#187 + %tmp = xor i32 %a, 187 + ret i32 %tmp +} + +; 0x00aa00aa = 11141290 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: eor {{.*}}#11141290 + %tmp = xor i32 %a, 11141290 + ret i32 %tmp +} + +; 0xcc00cc00 = 3422604288 +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: eor {{.*}}#-872363008 + %tmp = xor i32 %a, 3422604288 + ret i32 %tmp +} + +; 0xdddddddd = 3722304989 +define i32 @f4(i32 %a) { +; CHECK: f4: +; CHECK: eor {{.*}}#-572662307 + %tmp = xor i32 %a, 3722304989 + ret i32 %tmp +} + +; 0x00110000 = 1114112 +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: eor {{.*}}#1114112 + %tmp = xor i32 %a, 1114112 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1-tc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1-tc.ll new file mode 100644 index 0000000..5315535 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1-tc.ll
@@ -0,0 +1,87 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s +; XFAIL: * + +define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; CHECK: t1: +; CHECK: it ne +; CHECK: cmpne + switch i32 %c, label %cond_next [ + i32 1, label %cond_true + i32 7, label %cond_true + ] + +cond_true: + %tmp12 = add i32 %a, 1 + %tmp1518 = add i32 %tmp12, %b + ret i32 %tmp1518 + +cond_next: + %tmp15 = add i32 %b, %a + ret i32 %tmp15 +} + +; FIXME: Check for # of unconditional branch after adding branch folding post ifcvt. +define i32 @t2(i32 %a, i32 %b) nounwind { +entry: +; CHECK: t2: +; CHECK: ite gt +; CHECK: subgt +; CHECK: suble + %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp1434, label %bb17, label %bb.outer + +bb.outer: ; preds = %cond_false, %entry + %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5] + %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %cond_true, %bb.outer + %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2] + %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1] + %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1] + %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6] + %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1] + br i1 %tmp3, label %cond_true, label %cond_false + +cond_true: ; preds = %bb + %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2] + %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp1437, label %bb17, label %bb + +cond_false: ; preds = %bb + %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2] + %tmp14 = icmp eq i32 %a_addr.026.0, %tmp10 ; <i1> [#uses=1] + br i1 %tmp14, label %bb17, label %bb.outer + +bb17: ; preds = %cond_false, %cond_true, %entry + %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] + ret i32 %a_addr.026.1 +} + +@x = external global i32* ; <i32**> [#uses=1] + +define void @foo(i32 %a) nounwind { +entry: + %tmp = load i32** @x ; <i32*> [#uses=1] + store i32 %a, i32* %tmp + ret void +} + +; Tail call prevents use of ifcvt in this one. Seems like a win though. +define void @t3(i32 %a, i32 %b) nounwind { +entry: +; CHECK: t3: +; CHECK-NOT: it lt +; CHECK-NOT: poplt +; CHECK: b.w _foo @ TAILCALL + %tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1] + br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock + +cond_true: ; preds = %entry + tail call void @foo( i32 %b ) + ret void + +UnifiedReturnBlock: ; preds = %entry + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1.ll new file mode 100644 index 0000000..af8fcc6 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt1.ll
@@ -0,0 +1,87 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; CHECK: t1: +; CHECK: ittt ne +; CHECK: cmpne +; CHECK: addne +; CHECK: bxne lr + switch i32 %c, label %cond_next [ + i32 1, label %cond_true + i32 7, label %cond_true + ] + +cond_true: + %tmp12 = add i32 %a, 1 + %tmp1518 = add i32 %tmp12, %b + ret i32 %tmp1518 + +cond_next: + %tmp15 = add i32 %b, %a + ret i32 %tmp15 +} + +define i32 @t2(i32 %a, i32 %b) nounwind { +entry: +; Do not if-convert when branches go to the different loops. +; CHECK: t2: +; CHECK-NOT: ite gt +; CHECK-NOT: subgt +; CHECK-NOT: suble + %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1] + br i1 %tmp1434, label %bb17, label %bb.outer + +bb.outer: ; preds = %cond_false, %entry + %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5] + %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] + br label %bb + +bb: ; preds = %cond_true, %bb.outer + %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2] + %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1] + %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1] + %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6] + %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1] + br i1 %tmp3, label %cond_true, label %cond_false + +cond_true: ; preds = %bb + %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2] + %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1] + %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1] + br i1 %tmp1437, label %bb17, label %bb + +cond_false: ; preds = %bb + %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2] + %tmp14 = icmp eq i32 %a_addr.026.0, %tmp10 ; <i1> [#uses=1] + br i1 %tmp14, label %bb17, label %bb.outer + +bb17: ; preds = %cond_false, %cond_true, %entry + %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1] + ret i32 %a_addr.026.1 +} + +@x = external global i32* ; <i32**> [#uses=1] + +define void @foo(i32 %a) nounwind { +entry: + %tmp = load i32** @x ; <i32*> [#uses=1] + store i32 %a, i32* %tmp + ret void +} + +define void @t3(i32 %a, i32 %b) nounwind { +entry: +; CHECK: t3: +; CHECK: itt ge +; CHECK: movge r0, r1 +; CHECK: blge _foo + %tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1] + br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock + +cond_true: ; preds = %entry + call void @foo( i32 %b ) + ret void + +UnifiedReturnBlock: ; preds = %entry + ret void +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt2.ll new file mode 100644 index 0000000..2c57348 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt2.ll
@@ -0,0 +1,94 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +define void @foo(i32 %X, i32 %Y) { +entry: +; CHECK: foo: +; CHECK: it ne +; CHECK: cmpne +; CHECK: it hi +; CHECK: pophi {r7, pc} + %tmp1 = icmp ult i32 %X, 4 ; <i1> [#uses=1] + %tmp4 = icmp eq i32 %Y, 0 ; <i1> [#uses=1] + %tmp7 = or i1 %tmp4, %tmp1 ; <i1> [#uses=1] + br i1 %tmp7, label %cond_true, label %UnifiedReturnBlock + +cond_true: ; preds = %entry + %tmp10 = call i32 (...)* @bar( ) ; <i32> [#uses=0] + ret void + +UnifiedReturnBlock: ; preds = %entry + ret void +} + +declare i32 @bar(...) + +; FIXME: Need post-ifcvt branch folding to get rid of the extra br at end of BB1. + + %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* } + +define fastcc i32 @CountTree(%struct.quad_struct* %tree) { +entry: +; CHECK: CountTree: +; CHECK: it eq +; CHECK: cmpeq +; CHECK: bne +; CHECK: cmp +; CHECK: itt eq +; CHECK: moveq +; CHECK: popeq + br label %tailrecurse + +tailrecurse: ; preds = %bb, %entry + %tmp6 = load %struct.quad_struct** null ; <%struct.quad_struct*> [#uses=1] + %tmp9 = load %struct.quad_struct** null ; <%struct.quad_struct*> [#uses=2] + %tmp12 = load %struct.quad_struct** null ; <%struct.quad_struct*> [#uses=1] + %tmp14 = icmp eq %struct.quad_struct* null, null ; <i1> [#uses=1] + %tmp17 = icmp eq %struct.quad_struct* %tmp6, null ; <i1> [#uses=1] + %tmp23 = icmp eq %struct.quad_struct* %tmp9, null ; <i1> [#uses=1] + %tmp29 = icmp eq %struct.quad_struct* %tmp12, null ; <i1> [#uses=1] + %bothcond = and i1 %tmp17, %tmp14 ; <i1> [#uses=1] + %bothcond1 = and i1 %bothcond, %tmp23 ; <i1> [#uses=1] + %bothcond2 = and i1 %bothcond1, %tmp29 ; <i1> [#uses=1] + br i1 %bothcond2, label %return, label %bb + +bb: ; preds = %tailrecurse + %tmp41 = tail call fastcc i32 @CountTree( %struct.quad_struct* %tmp9 ) ; <i32> [#uses=0] + br label %tailrecurse + +return: ; preds = %tailrecurse + ret i32 0 +} + + %struct.SString = type { i8*, i32, i32 } + +declare void @abort() + +define fastcc void @t1(%struct.SString* %word, i8 signext %c) { +entry: +; CHECK: t1: +; CHECK: it ne +; CHECK: popne {r7, pc} + %tmp1 = icmp eq %struct.SString* %word, null ; <i1> [#uses=1] + br i1 %tmp1, label %cond_true, label %cond_false + +cond_true: ; preds = %entry + tail call void @abort( ) + unreachable + +cond_false: ; preds = %entry + ret void +} + +define fastcc void @t2() nounwind { +entry: +; CHECK: t2: +; CHECK: cmp r0, #0 +; CHECK: beq + br i1 undef, label %bb.i.i3, label %growMapping.exit + +bb.i.i3: ; preds = %entry + unreachable + +growMapping.exit: ; preds = %entry + unreachable +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt3.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt3.ll new file mode 100644 index 0000000..bcf10ef --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ifcvt3.ll
@@ -0,0 +1,31 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +; There shouldn't be a unconditional branch at end of bb52. +; rdar://7184787 + +@posed = external global i64 ; <i64*> [#uses=1] + +define i1 @ab_bb52(i64 %.reload78, i64* %.out, i64* %.out1) nounwind { +newFuncRoot: + br label %bb52 + +bb52.bb55_crit_edge.exitStub: ; preds = %bb52 + store i64 %0, i64* %.out + store i64 %2, i64* %.out1 + ret i1 true + +bb52.bb53_crit_edge.exitStub: ; preds = %bb52 + store i64 %0, i64* %.out + store i64 %2, i64* %.out1 + ret i1 false + +bb52: ; preds = %newFuncRoot +; CHECK: movne +; CHECK: moveq +; CHECK: pop + %0 = load i64* @posed, align 4 ; <i64> [#uses=3] + %1 = sub i64 %0, %.reload78 ; <i64> [#uses=1] + %2 = ashr i64 %1, 1 ; <i64> [#uses=3] + %3 = icmp eq i64 %2, 0 ; <i1> [#uses=1] + br i1 %3, label %bb52.bb55_crit_edge.exitStub, label %bb52.bb53_crit_edge.exitStub +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-jtb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-jtb.ll new file mode 100644 index 0000000..f5a56e5 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-jtb.ll
@@ -0,0 +1,120 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -arm-adjust-jump-tables=0 | not grep tbb + +; Do not use tbb / tbh if any destination is before the jumptable. +; rdar://7102917 + +define i16 @main__getopt_internal_2E_exit_2E_ce(i32) nounwind { +newFuncRoot: + br label %_getopt_internal.exit.ce + +codeRepl127.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 0 + +parse_options.exit.loopexit.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 1 + +bb1.i.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 2 + +bb90.i.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 3 + +codeRepl104.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 4 + +codeRepl113.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 5 + +codeRepl51.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 6 + +codeRepl70.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 7 + +codeRepl119.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 8 + +codeRepl93.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 9 + +codeRepl101.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 10 + +codeRepl120.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 11 + +codeRepl89.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 12 + +codeRepl45.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 13 + +codeRepl58.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 14 + +codeRepl46.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 15 + +codeRepl50.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 16 + +codeRepl52.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 17 + +codeRepl53.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 18 + +codeRepl61.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 19 + +codeRepl85.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 20 + +codeRepl97.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 21 + +codeRepl79.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 22 + +codeRepl102.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 23 + +codeRepl54.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 24 + +codeRepl57.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 25 + +codeRepl103.exitStub: ; preds = %_getopt_internal.exit.ce + ret i16 26 + +_getopt_internal.exit.ce: ; preds = %newFuncRoot + switch i32 %0, label %codeRepl127.exitStub [ + i32 -1, label %parse_options.exit.loopexit.exitStub + i32 0, label %bb1.i.exitStub + i32 63, label %bb90.i.exitStub + i32 66, label %codeRepl104.exitStub + i32 67, label %codeRepl113.exitStub + i32 71, label %codeRepl51.exitStub + i32 77, label %codeRepl70.exitStub + i32 78, label %codeRepl119.exitStub + i32 80, label %codeRepl93.exitStub + i32 81, label %codeRepl101.exitStub + i32 82, label %codeRepl120.exitStub + i32 88, label %codeRepl89.exitStub + i32 97, label %codeRepl45.exitStub + i32 98, label %codeRepl58.exitStub + i32 99, label %codeRepl46.exitStub + i32 100, label %codeRepl50.exitStub + i32 104, label %codeRepl52.exitStub + i32 108, label %codeRepl53.exitStub + i32 109, label %codeRepl61.exitStub + i32 110, label %codeRepl85.exitStub + i32 111, label %codeRepl97.exitStub + i32 113, label %codeRepl79.exitStub + i32 114, label %codeRepl102.exitStub + i32 115, label %codeRepl54.exitStub + i32 116, label %codeRepl57.exitStub + i32 118, label %codeRepl103.exitStub + ] +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldm.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldm.ll new file mode 100644 index 0000000..4f2b7c1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldm.ll
@@ -0,0 +1,40 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 | FileCheck %s + +@X = external global [0 x i32] ; <[0 x i32]*> [#uses=5] + +define i32 @t1() { +; CHECK: t1: +; CHECK: push {r7, lr} +; CHECK: pop {r7, pc} + %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 0) ; <i32> [#uses=1] + %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; <i32> [#uses=1] + %tmp4 = call i32 @f1( i32 %tmp, i32 %tmp3 ) ; <i32> [#uses=1] + ret i32 %tmp4 +} + +define i32 @t2() { +; CHECK: t2: +; CHECK: push {r7, lr} +; CHECK: ldm +; CHECK: pop {r7, pc} + %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; <i32> [#uses=1] + %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; <i32> [#uses=1] + %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 4) ; <i32> [#uses=1] + %tmp6 = call i32 @f2( i32 %tmp, i32 %tmp3, i32 %tmp5 ) ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @t3() { +; CHECK: t3: +; CHECK: push {r7, lr} +; CHECK: pop {r7, pc} + %tmp = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 1) ; <i32> [#uses=1] + %tmp3 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 2) ; <i32> [#uses=1] + %tmp5 = load i32* getelementptr ([0 x i32]* @X, i32 0, i32 3) ; <i32> [#uses=1] + %tmp6 = call i32 @f2( i32 %tmp, i32 %tmp3, i32 %tmp5 ) ; <i32> [#uses=1] + ret i32 %tmp6 +} + +declare i32 @f1(i32, i32) + +declare i32 @f2(i32, i32, i32)
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr.ll new file mode 100644 index 0000000..88434f1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr.ll
@@ -0,0 +1,72 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32* %v) { +entry: +; CHECK: f1: +; CHECK: ldr r0, [r0] + %tmp = load i32* %v + ret i32 %tmp +} + +define i32 @f2(i32* %v) { +entry: +; CHECK: f2: +; CHECK: ldr.w r0, [r0, #4092] + %tmp2 = getelementptr i32* %v, i32 1023 + %tmp = load i32* %tmp2 + ret i32 %tmp +} + +define i32 @f3(i32* %v) { +entry: +; CHECK: f3: +; CHECK: mov.w r1, #4096 +; CHECK: ldr r0, [r0, r1] + %tmp2 = getelementptr i32* %v, i32 1024 + %tmp = load i32* %tmp2 + ret i32 %tmp +} + +define i32 @f4(i32 %base) { +entry: +; CHECK: f4: +; CHECK: ldr r0, [r0, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i32* + %tmp3 = load i32* %tmp2 + ret i32 %tmp3 +} + +define i32 @f5(i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: ldr r0, [r0, r1] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i32* + %tmp3 = load i32* %tmp2 + ret i32 %tmp3 +} + +define i32 @f6(i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: ldr.w r0, [r0, r1, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i32* + %tmp4 = load i32* %tmp3 + ret i32 %tmp4 +} + +define i32 @f7(i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r1, r1, #2 +; CHECK: ldr r0, [r0, r1] + + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i32* + %tmp4 = load i32* %tmp3 + ret i32 %tmp4 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_ext.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_ext.ll new file mode 100644 index 0000000..9e6aef4 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_ext.ll
@@ -0,0 +1,28 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep ldrb | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep ldrh | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep ldrsb | count 1 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep ldrsh | count 1 + +define i32 @test1(i8* %v.pntr.s0.u1) { + %tmp.u = load i8* %v.pntr.s0.u1 + %tmp1.s = zext i8 %tmp.u to i32 + ret i32 %tmp1.s +} + +define i32 @test2(i16* %v.pntr.s0.u1) { + %tmp.u = load i16* %v.pntr.s0.u1 + %tmp1.s = zext i16 %tmp.u to i32 + ret i32 %tmp1.s +} + +define i32 @test3(i8* %v.pntr.s1.u0) { + %tmp.s = load i8* %v.pntr.s1.u0 + %tmp1.s = sext i8 %tmp.s to i32 + ret i32 %tmp1.s +} + +define i32 @test4() { + %tmp.s = load i16* null + %tmp1.s = sext i16 %tmp.s to i32 + ret i32 %tmp1.s +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_post.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_post.ll new file mode 100644 index 0000000..d1af4ba --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_post.ll
@@ -0,0 +1,12 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ +; RUN: grep {ldr.*\\\[.*\],} | count 1 + +define i32 @test(i32 %a, i32 %b, i32 %c) { + %tmp1 = mul i32 %a, %b ; <i32> [#uses=2] + %tmp2 = inttoptr i32 %tmp1 to i32* ; <i32*> [#uses=1] + %tmp3 = load i32* %tmp2 ; <i32> [#uses=1] + %tmp4 = sub i32 %tmp1, 8 ; <i32> [#uses=1] + %tmp5 = mul i32 %tmp4, %tmp3 ; <i32> [#uses=1] + ret i32 %tmp5 +} +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_pre.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_pre.ll new file mode 100644 index 0000000..9cc3f4a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldr_pre.ll
@@ -0,0 +1,28 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ +; RUN: grep {ldr.*\\!} | count 3 +; RUN: llc < %s -march=thumb -mattr=+thumb2 | \ +; RUN: grep {ldrsb.*\\!} | count 1 + +define i32* @test1(i32* %X, i32* %dest) { + %Y = getelementptr i32* %X, i32 4 ; <i32*> [#uses=2] + %A = load i32* %Y ; <i32> [#uses=1] + store i32 %A, i32* %dest + ret i32* %Y +} + +define i32 @test2(i32 %a, i32 %b) { + %tmp1 = sub i32 %a, 64 ; <i32> [#uses=2] + %tmp2 = inttoptr i32 %tmp1 to i32* ; <i32*> [#uses=1] + %tmp3 = load i32* %tmp2 ; <i32> [#uses=1] + %tmp4 = sub i32 %tmp1, %b ; <i32> [#uses=1] + %tmp5 = add i32 %tmp4, %tmp3 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +define i8* @test3(i8* %X, i32* %dest) { + %tmp1 = getelementptr i8* %X, i32 4 + %tmp2 = load i8* %tmp1 + %tmp3 = sext i8 %tmp2 to i32 + store i32 %tmp3, i32* %dest + ret i8* %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrb.ll new file mode 100644 index 0000000..bf10097 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrb.ll
@@ -0,0 +1,72 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i8 @f1(i8* %v) { +entry: +; CHECK: f1: +; CHECK: ldrb r0, [r0] + %tmp = load i8* %v + ret i8 %tmp +} + +define i8 @f2(i8* %v) { +entry: +; CHECK: f2: +; CHECK: ldrb r0, [r0, #-1] + %tmp2 = getelementptr i8* %v, i8 1023 + %tmp = load i8* %tmp2 + ret i8 %tmp +} + +define i8 @f3(i32 %base) { +entry: +; CHECK: f3: +; CHECK: mov.w r1, #4096 +; CHECK: ldrb r0, [r0, r1] + %tmp1 = add i32 %base, 4096 + %tmp2 = inttoptr i32 %tmp1 to i8* + %tmp3 = load i8* %tmp2 + ret i8 %tmp3 +} + +define i8 @f4(i32 %base) { +entry: +; CHECK: f4: +; CHECK: ldrb r0, [r0, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i8* + %tmp3 = load i8* %tmp2 + ret i8 %tmp3 +} + +define i8 @f5(i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: ldrb r0, [r0, r1] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i8* + %tmp3 = load i8* %tmp2 + ret i8 %tmp3 +} + +define i8 @f6(i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: ldrb.w r0, [r0, r1, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i8* + %tmp4 = load i8* %tmp3 + ret i8 %tmp4 +} + +define i8 @f7(i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r1, r1, #2 +; CHECK: ldrb r0, [r0, r1] + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i8* + %tmp4 = load i8* %tmp3 + ret i8 %tmp4 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrd.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrd.ll new file mode 100644 index 0000000..d3b781d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrd.ll
@@ -0,0 +1,12 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -mattr=+thumb2 -regalloc=linearscan | FileCheck %s + +@b = external global i64* + +define i64 @t(i64 %a) nounwind readonly { +entry: +;CHECK: ldrd r2, r3, [r2] + %0 = load i64** @b, align 4 + %1 = load i64* %0, align 4 + %2 = mul i64 %1, %a + ret i64 %2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrh.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrh.ll new file mode 100644 index 0000000..fee97bf --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ldrh.ll
@@ -0,0 +1,71 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i16 @f1(i16* %v) { +entry: +; CHECK: f1: +; CHECK: ldrh r0, [r0] + %tmp = load i16* %v + ret i16 %tmp +} + +define i16 @f2(i16* %v) { +entry: +; CHECK: f2: +; CHECK: ldrh.w r0, [r0, #2046] + %tmp2 = getelementptr i16* %v, i16 1023 + %tmp = load i16* %tmp2 + ret i16 %tmp +} + +define i16 @f3(i16* %v) { +entry: +; CHECK: f3: +; CHECK: mov.w r1, #4096 +; CHECK: ldrh r0, [r0, r1] + %tmp2 = getelementptr i16* %v, i16 2048 + %tmp = load i16* %tmp2 + ret i16 %tmp +} + +define i16 @f4(i32 %base) { +entry: +; CHECK: f4: +; CHECK: ldrh r0, [r0, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i16* + %tmp3 = load i16* %tmp2 + ret i16 %tmp3 +} + +define i16 @f5(i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: ldrh r0, [r0, r1] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i16* + %tmp3 = load i16* %tmp2 + ret i16 %tmp3 +} + +define i16 @f6(i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: ldrh.w r0, [r0, r1, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i16* + %tmp4 = load i16* %tmp3 + ret i16 %tmp4 +} + +define i16 @f7(i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r1, r1, #2 +; CHECK: ldrh r0, [r0, r1] + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i16* + %tmp4 = load i16* %tmp3 + ret i16 %tmp4 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl.ll new file mode 100644 index 0000000..6b0818a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: lsls r0, r0, #5 + %tmp = shl i32 %a, 5 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl2.ll new file mode 100644 index 0000000..f283eef --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsl2.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: lsls r0, r1 + %tmp = shl i32 %a, %b + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr.ll new file mode 100644 index 0000000..7cbee54 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: lsrs r0, r0, #13 + %tmp = lshr i32 %a, 13 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr2.ll new file mode 100644 index 0000000..87800f9 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr2.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: lsrs r0, r1 + %tmp = lshr i32 %a, %b + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr3.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr3.ll new file mode 100644 index 0000000..e7ba782 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-lsr3.ll
@@ -0,0 +1,19 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i1 @test1(i64 %poscnt, i32 %work) { +entry: +; CHECK: lsrs.w r1, r1, #1 +; CHECK: rrx r0, r0 + %0 = lshr i64 %poscnt, 1 + %1 = icmp eq i64 %0, 0 + ret i1 %1 +} + +define i1 @test2(i64 %poscnt, i32 %work) { +entry: +; CHECK: asrs.w r1, r1, #1 +; CHECK: rrx r0, r0 + %0 = ashr i64 %poscnt, 1 + %1 = icmp eq i64 %0, 0 + ret i1 %1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mla.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mla.ll new file mode 100644 index 0000000..c4cc749 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mla.ll
@@ -0,0 +1,17 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b, i32 %c) { + %tmp1 = mul i32 %a, %b + %tmp2 = add i32 %c, %tmp1 + ret i32 %tmp2 +} +; CHECK: f1: +; CHECK: mla r0, r0, r1, r2 + +define i32 @f2(i32 %a, i32 %b, i32 %c) { + %tmp1 = mul i32 %a, %b + %tmp2 = add i32 %tmp1, %c + ret i32 %tmp2 +} +; CHECK: f2: +; CHECK: mla r0, r0, r1, r2
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mls.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mls.ll new file mode 100644 index 0000000..24c45c5 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mls.ll
@@ -0,0 +1,19 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b, i32 %c) { + %tmp1 = mul i32 %a, %b + %tmp2 = sub i32 %c, %tmp1 + ret i32 %tmp2 +} +; CHECK: f1: +; CHECK: mls r0, r0, r1, r2 + +; sub doesn't commute, so no mls for this one +define i32 @f2(i32 %a, i32 %b, i32 %c) { + %tmp1 = mul i32 %a, %b + %tmp2 = sub i32 %tmp1, %c + ret i32 %tmp2 +} +; CHECK: f2: +; CHECK: muls r0, r0, r1 +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mov.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mov.ll new file mode 100644 index 0000000..adb6dde --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mov.ll
@@ -0,0 +1,266 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; Test #<const> + +; var 2.1 - 0x00ab00ab +define i32 @t2_const_var2_1_ok_1(i32 %lhs) { +;CHECK: t2_const_var2_1_ok_1: +;CHECK: add.w r0, r0, #11206827 + %ret = add i32 %lhs, 11206827 ; 0x00ab00ab + ret i32 %ret +} + +define i32 @t2_const_var2_1_ok_2(i32 %lhs) { +;CHECK: t2_const_var2_1_ok_2: +;CHECK: add.w r0, r0, #11206656 +;CHECK: adds r0, #187 + %ret = add i32 %lhs, 11206843 ; 0x00ab00bb + ret i32 %ret +} + +define i32 @t2_const_var2_1_ok_3(i32 %lhs) { +;CHECK: t2_const_var2_1_ok_3: +;CHECK: add.w r0, r0, #11206827 +;CHECK: add.w r0, r0, #16777216 + %ret = add i32 %lhs, 27984043 ; 0x01ab00ab + ret i32 %ret +} + +define i32 @t2_const_var2_1_ok_4(i32 %lhs) { +;CHECK: t2_const_var2_1_ok_4: +;CHECK: add.w r0, r0, #16777472 +;CHECK: add.w r0, r0, #11206827 + %ret = add i32 %lhs, 27984299 ; 0x01ab01ab + ret i32 %ret +} + +define i32 @t2_const_var2_1_fail_1(i32 %lhs) { +;CHECK: t2_const_var2_1_fail_1: +;CHECK: movw r1, #43777 +;CHECK: movt r1, #427 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 28027649 ; 0x01abab01 + ret i32 %ret +} + +; var 2.2 - 0xab00ab00 +define i32 @t2_const_var2_2_ok_1(i32 %lhs) { +;CHECK: t2_const_var2_2_ok_1: +;CHECK: add.w r0, r0, #-1426019584 + %ret = add i32 %lhs, 2868947712 ; 0xab00ab00 + ret i32 %ret +} + +define i32 @t2_const_var2_2_ok_2(i32 %lhs) { +;CHECK: t2_const_var2_2_ok_2: +;CHECK: add.w r0, r0, #2868903936 +;CHECK: add.w r0, r0, #47616 + %ret = add i32 %lhs, 2868951552 ; 0xab00ba00 + ret i32 %ret +} + +define i32 @t2_const_var2_2_ok_3(i32 %lhs) { +;CHECK: t2_const_var2_2_ok_3: +;CHECK: add.w r0, r0, #2868947712 +;CHECK: adds r0, #16 + %ret = add i32 %lhs, 2868947728 ; 0xab00ab10 + ret i32 %ret +} + +define i32 @t2_const_var2_2_ok_4(i32 %lhs) { +;CHECK: t2_const_var2_2_ok_4: +;CHECK: add.w r0, r0, #2868947712 +;CHECK: add.w r0, r0, #1048592 + %ret = add i32 %lhs, 2869996304 ; 0xab10ab10 + ret i32 %ret +} + +define i32 @t2_const_var2_2_fail_1(i32 %lhs) { +;CHECK: t2_const_var2_2_fail_1: +;CHECK: movw r1, #43792 +;CHECK: movt r1, #4267 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 279685904 ; 0x10abab10 + ret i32 %ret +} + +; var 2.3 - 0xabababab +define i32 @t2_const_var2_3_ok_1(i32 %lhs) { +;CHECK: t2_const_var2_3_ok_1: +;CHECK: add.w r0, r0, #-1414812757 + %ret = add i32 %lhs, 2880154539 ; 0xabababab + ret i32 %ret +} + +define i32 @t2_const_var2_3_fail_1(i32 %lhs) { +;CHECK: t2_const_var2_3_fail_1: +;CHECK: movw r1, #43962 +;CHECK: movt r1, #43947 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 2880154554 ; 0xabababba + ret i32 %ret +} + +define i32 @t2_const_var2_3_fail_2(i32 %lhs) { +;CHECK: t2_const_var2_3_fail_2: +;CHECK: movw r1, #47787 +;CHECK: movt r1, #43947 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 2880158379 ; 0xababbaab + ret i32 %ret +} + +define i32 @t2_const_var2_3_fail_3(i32 %lhs) { +;CHECK: t2_const_var2_3_fail_3: +;CHECK: movw r1, #43947 +;CHECK: movt r1, #43962 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 2881137579 ; 0xabbaabab + ret i32 %ret +} + +define i32 @t2_const_var2_3_fail_4(i32 %lhs) { +;CHECK: t2_const_var2_3_fail_4: +;CHECK: movw r1, #43947 +;CHECK: movt r1, #47787 +;CHECK: add r0, r1 + %ret = add i32 %lhs, 3131812779 ; 0xbaababab + ret i32 %ret +} + +; var 3 - 0x0F000000 +define i32 @t2_const_var3_1_ok_1(i32 %lhs) { +;CHECK: t2_const_var3_1_ok_1: +;CHECK: add.w r0, r0, #251658240 + %ret = add i32 %lhs, 251658240 ; 0x0F000000 + ret i32 %ret +} + +define i32 @t2_const_var3_2_ok_1(i32 %lhs) { +;CHECK: t2_const_var3_2_ok_1: +;CHECK: add.w r0, r0, #3948544 + %ret = add i32 %lhs, 3948544 ; 0b00000000001111000100000000000000 + ret i32 %ret +} + +define i32 @t2_const_var3_2_ok_2(i32 %lhs) { +;CHECK: t2_const_var3_2_ok_2: +;CHECK: add.w r0, r0, #2097152 +;CHECK: add.w r0, r0, #1843200 + %ret = add i32 %lhs, 3940352 ; 0b00000000001111000010000000000000 + ret i32 %ret +} + +define i32 @t2_const_var3_3_ok_1(i32 %lhs) { +;CHECK: t2_const_var3_3_ok_1: +;CHECK: add.w r0, r0, #258 + %ret = add i32 %lhs, 258 ; 0b00000000000000000000000100000010 + ret i32 %ret +} + +define i32 @t2_const_var3_4_ok_1(i32 %lhs) { +;CHECK: t2_const_var3_4_ok_1: +;CHECK: add.w r0, r0, #-268435456 + %ret = add i32 %lhs, 4026531840 ; 0xF0000000 + ret i32 %ret +} + +define i32 @t2MOVTi16_ok_1(i32 %a) { +; CHECK: t2MOVTi16_ok_1: +; CHECK: movt r0, #1234 + %1 = and i32 %a, 65535 + %2 = shl i32 1234, 16 + %3 = or i32 %1, %2 + + ret i32 %3 +} + +define i32 @t2MOVTi16_test_1(i32 %a) { +; CHECK: t2MOVTi16_test_1: +; CHECK: movt r0, #1234 + %1 = shl i32 255, 8 + %2 = shl i32 1234, 8 + %3 = or i32 %1, 255 ; This gives us 0xFFFF in %3 + %4 = shl i32 %2, 8 ; This gives us (1234 << 16) in %4 + %5 = and i32 %a, %3 + %6 = or i32 %4, %5 + + ret i32 %6 +} + +define i32 @t2MOVTi16_test_2(i32 %a) { +; CHECK: t2MOVTi16_test_2: +; CHECK: movt r0, #1234 + %1 = shl i32 255, 8 + %2 = shl i32 1234, 8 + %3 = or i32 %1, 255 ; This gives us 0xFFFF in %3 + %4 = shl i32 %2, 6 + %5 = and i32 %a, %3 + %6 = shl i32 %4, 2 ; This gives us (1234 << 16) in %6 + %7 = or i32 %5, %6 + + ret i32 %7 +} + +define i32 @t2MOVTi16_test_3(i32 %a) { +; CHECK: t2MOVTi16_test_3: +; CHECK: movt r0, #1234 + %1 = shl i32 255, 8 + %2 = shl i32 1234, 8 + %3 = or i32 %1, 255 ; This gives us 0xFFFF in %3 + %4 = shl i32 %2, 6 + %5 = and i32 %a, %3 + %6 = shl i32 %4, 2 ; This gives us (1234 << 16) in %6 + %7 = lshr i32 %6, 6 + %8 = shl i32 %7, 6 + %9 = or i32 %5, %8 + + ret i32 %8 +} + +; 171 = 0x000000ab +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: movs r0, #171 + %tmp = add i32 0, 171 + ret i32 %tmp +} + +; 1179666 = 0x00120012 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: mov.w r0, #1179666 + %tmp = add i32 0, 1179666 + ret i32 %tmp +} + +; 872428544 = 0x34003400 +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: mov.w r0, #872428544 + %tmp = add i32 0, 872428544 + ret i32 %tmp +} + +; 1448498774 = 0x56565656 +define i32 @f4(i32 %a) { +; CHECK: f4: +; CHECK: mov.w r0, #1448498774 + %tmp = add i32 0, 1448498774 + ret i32 %tmp +} + +; 66846720 = 0x03fc0000 +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: mov.w r0, #66846720 + %tmp = add i32 0, 66846720 + ret i32 %tmp +} + +define i32 @f6(i32 %a) { +;CHECK: f6 +;CHECK: movw r0, #65535 + %tmp = add i32 0, 65535 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mul.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mul.ll new file mode 100644 index 0000000..bb97d97 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mul.ll
@@ -0,0 +1,26 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b, i32 %c) { +; CHECK: f1: +; CHECK: muls r0, r0, r1 + %tmp = mul i32 %a, %b + ret i32 %tmp +} + +%struct.CMPoint = type { %struct.Point, float, float, [5 x float] } +%struct.Point = type { float, float } + +define %struct.CMPoint* @t1(i32 %i, i32 %j, i32 %n, %struct.CMPoint* %thePoints) nounwind readnone ssp { +entry: +; CHECK: t1: +; CHECK: mla r0, r2, r0, r1 +; CHECK: add.w r0, r0, r0, lsl #3 +; CHECL: add.w r0, r3, r0, lsl #2 + %mul = mul i32 %n, %i + %add = add i32 %mul, %j + %0 = ptrtoint %struct.CMPoint* %thePoints to i32 + %mul5 = mul i32 %add, 36 + %add6 = add i32 %mul5, %0 + %1 = inttoptr i32 %add6 to %struct.CMPoint* + ret %struct.CMPoint* %1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mulhi.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mulhi.ll new file mode 100644 index 0000000..9d4840a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mulhi.ll
@@ -0,0 +1,23 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2dsp | FileCheck %s + +define i32 @smulhi(i32 %x, i32 %y) { +; CHECK: smulhi +; CHECK: smmul r0, r1, r0 + %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] + %tmp3 = lshr i64 %tmp2, 32 ; <i64> [#uses=1] + %tmp3.upgrd.1 = trunc i64 %tmp3 to i32 ; <i32> [#uses=1] + ret i32 %tmp3.upgrd.1 +} + +define i32 @umulhi(i32 %x, i32 %y) { +; CHECK: umulhi +; CHECK: umull r1, r0, r1, r0 + %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] + %tmp3 = lshr i64 %tmp2, 32 ; <i64> [#uses=1] + %tmp3.upgrd.2 = trunc i64 %tmp3 to i32 ; <i32> [#uses=1] + ret i32 %tmp3.upgrd.2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn.ll new file mode 100644 index 0000000..a8c8f83 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn.ll
@@ -0,0 +1,33 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s + +; 0x000000bb = 187 +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: mvn r0, #187 + %tmp = xor i32 4294967295, 187 + ret i32 %tmp +} + +; 0x00aa00aa = 11141290 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: mvn r0, #11141290 + %tmp = xor i32 4294967295, 11141290 + ret i32 %tmp +} + +; 0xcc00cc00 = 3422604288 +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: mvn r0, #-872363008 + %tmp = xor i32 4294967295, 3422604288 + ret i32 %tmp +} + +; 0x00110000 = 1114112 +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: mvn r0, #1114112 + %tmp = xor i32 4294967295, 1114112 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn2.ll new file mode 100644 index 0000000..375d0aa --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-mvn2.ll
@@ -0,0 +1,49 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: mvns r0, r0 + %tmp = xor i32 4294967295, %a + ret i32 %tmp +} + +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: mvns r0, r0 + %tmp = xor i32 %a, 4294967295 + ret i32 %tmp +} + +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: mvn.w r0, r0, lsl #5 + %tmp = shl i32 %a, 5 + %tmp1 = xor i32 %tmp, 4294967295 + ret i32 %tmp1 +} + +define i32 @f6(i32 %a) { +; CHECK: f6: +; CHECK: mvn.w r0, r0, lsr #6 + %tmp = lshr i32 %a, 6 + %tmp1 = xor i32 %tmp, 4294967295 + ret i32 %tmp1 +} + +define i32 @f7(i32 %a) { +; CHECK: f7: +; CHECK: mvn.w r0, r0, asr #7 + %tmp = ashr i32 %a, 7 + %tmp1 = xor i32 %tmp, 4294967295 + ret i32 %tmp1 +} + +define i32 @f8(i32 %a) { +; CHECK: f8: +; CHECK: mvn.w r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = xor i32 %tmp, 4294967295 + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-neg.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-neg.ll new file mode 100644 index 0000000..6bf11ec --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-neg.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: rsbs r0, r0, #0 + %tmp = sub i32 0, %a + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-orn.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-orn.ll new file mode 100644 index 0000000..97a3fd7 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-orn.ll
@@ -0,0 +1,72 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + + +define i32 @f1(i32 %a, i32 %b) { + %tmp = xor i32 %b, 4294967295 + %tmp1 = or i32 %a, %tmp + ret i32 %tmp1 +} +; CHECK: f1: +; CHECK: orn r0, r0, r1 + +define i32 @f2(i32 %a, i32 %b) { + %tmp = xor i32 %b, 4294967295 + %tmp1 = or i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f2: +; CHECK: orn r0, r0, r1 + +define i32 @f3(i32 %a, i32 %b) { + %tmp = xor i32 4294967295, %b + %tmp1 = or i32 %a, %tmp + ret i32 %tmp1 +} +; CHECK: f3: +; CHECK: orn r0, r0, r1 + +define i32 @f4(i32 %a, i32 %b) { + %tmp = xor i32 4294967295, %b + %tmp1 = or i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f4: +; CHECK: orn r0, r0, r1 + +define i32 @f5(i32 %a, i32 %b) { + %tmp = shl i32 %b, 5 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f5: +; CHECK: orn r0, r0, r1, lsl #5 + +define i32 @f6(i32 %a, i32 %b) { + %tmp = lshr i32 %b, 6 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f6: +; CHECK: orn r0, r0, r1, lsr #6 + +define i32 @f7(i32 %a, i32 %b) { + %tmp = ashr i32 %b, 7 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f7: +; CHECK: orn r0, r0, r1, asr #7 + +define i32 @f8(i32 %a, i32 %b) { + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = xor i32 4294967295, %tmp + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f8: +; CHECK: orn r0, r0, r0, ror #8
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-orn2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-orn2.ll new file mode 100644 index 0000000..34ab3a5 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-orn2.ll
@@ -0,0 +1,38 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + + +; 0x000000bb = 187 +define i32 @f1(i32 %a) { + %tmp1 = xor i32 4294967295, 187 + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f1: +; CHECK: orn r0, r0, #187 + +; 0x00aa00aa = 11141290 +define i32 @f2(i32 %a) { + %tmp1 = xor i32 4294967295, 11141290 + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f2: +; CHECK: orn r0, r0, #11141290 + +; 0xcc00cc00 = 3422604288 +define i32 @f3(i32 %a) { + %tmp1 = xor i32 4294967295, 3422604288 + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f3: +; CHECK: orn r0, r0, #-872363008 + +; 0x00110000 = 1114112 +define i32 @f5(i32 %a) { + %tmp1 = xor i32 4294967295, 1114112 + %tmp2 = or i32 %a, %tmp1 + ret i32 %tmp2 +} +; CHECK: f5: +; CHECK: orn r0, r0, #1114112
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-orr.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-orr.ll new file mode 100644 index 0000000..89ab7b1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-orr.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: orrs r0, r1 + %tmp2 = or i32 %a, %b + ret i32 %tmp2 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: orr.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp2 = or i32 %a, %tmp + ret i32 %tmp2 +} + +define i32 @f6(i32 %a, i32 %b) { +; CHECK: f6: +; CHECK: orr.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp2 = or i32 %a, %tmp + ret i32 %tmp2 +} + +define i32 @f7(i32 %a, i32 %b) { +; CHECK: f7: +; CHECK: orr.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp2 = or i32 %a, %tmp + ret i32 %tmp2 +} + +define i32 @f8(i32 %a, i32 %b) { +; CHECK: f8: +; CHECK: orr.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp2 = or i32 %a, %tmp + ret i32 %tmp2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-orr2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-orr2.ll new file mode 100644 index 0000000..8f7a3c2 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-orr2.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + + +; 0x000000bb = 187 +define i32 @f1(i32 %a) { + %tmp2 = or i32 %a, 187 + ret i32 %tmp2 +} +; CHECK: f1: +; CHECK: orr r0, r0, #187 + +; 0x00aa00aa = 11141290 +define i32 @f2(i32 %a) { + %tmp2 = or i32 %a, 11141290 + ret i32 %tmp2 +} +; CHECK: f2: +; CHECK: orr r0, r0, #11141290 + +; 0xcc00cc00 = 3422604288 +define i32 @f3(i32 %a) { + %tmp2 = or i32 %a, 3422604288 + ret i32 %tmp2 +} +; CHECK: f3: +; CHECK: orr r0, r0, #-872363008 + +; 0x44444444 = 1145324612 +define i32 @f4(i32 %a) { + %tmp2 = or i32 %a, 1145324612 + ret i32 %tmp2 +} +; CHECK: f4: +; CHECK: orr r0, r0, #1145324612 + +; 0x00110000 = 1114112 +define i32 @f5(i32 %a) { + %tmp2 = or i32 %a, 1114112 + ret i32 %tmp2 +} +; CHECK: f5: +; CHECK: orr r0, r0, #1114112
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-pack.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-pack.ll new file mode 100644 index 0000000..2e8bb1d --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-pack.ll
@@ -0,0 +1,97 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s + +; CHECK: test1 +; CHECK: pkhbt r0, r0, r1, lsl #16 +define i32 @test1(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; <i32> [#uses=1] + %tmp4 = shl i32 %Y, 16 ; <i32> [#uses=1] + %tmp5 = or i32 %tmp4, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +; CHECK: test1a +; CHECK: pkhbt r0, r0, r1, lsl #16 +define i32 @test1a(i32 %X, i32 %Y) { + %tmp19 = and i32 %X, 65535 ; <i32> [#uses=1] + %tmp37 = shl i32 %Y, 16 ; <i32> [#uses=1] + %tmp5 = or i32 %tmp37, %tmp19 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +; CHECK: test2 +; CHECK: pkhbt r0, r0, r1, lsl #12 +define i32 @test2(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; <i32> [#uses=1] + %tmp3 = shl i32 %Y, 12 ; <i32> [#uses=1] + %tmp4 = and i32 %tmp3, -65536 ; <i32> [#uses=1] + %tmp57 = or i32 %tmp4, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp57 +} + +; CHECK: test3 +; CHECK: pkhbt r0, r0, r1, lsl #18 +define i32 @test3(i32 %X, i32 %Y) { + %tmp19 = and i32 %X, 65535 ; <i32> [#uses=1] + %tmp37 = shl i32 %Y, 18 ; <i32> [#uses=1] + %tmp5 = or i32 %tmp37, %tmp19 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +; CHECK: test4 +; CHECK: pkhbt r0, r0, r1 +define i32 @test4(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, 65535 ; <i32> [#uses=1] + %tmp3 = and i32 %Y, -65536 ; <i32> [#uses=1] + %tmp46 = or i32 %tmp3, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp46 +} + +; CHECK: test5 +; CHECK: pkhtb r0, r0, r1, asr #16 +define i32 @test5(i32 %X, i32 %Y) { + %tmp17 = and i32 %X, -65536 ; <i32> [#uses=1] + %tmp2 = bitcast i32 %Y to i32 ; <i32> [#uses=1] + %tmp4 = lshr i32 %tmp2, 16 ; <i32> [#uses=2] + %tmp5 = or i32 %tmp4, %tmp17 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +; CHECK: test5a +; CHECK: pkhtb r0, r0, r1, asr #16 +define i32 @test5a(i32 %X, i32 %Y) { + %tmp110 = and i32 %X, -65536 ; <i32> [#uses=1] + %tmp37 = lshr i32 %Y, 16 ; <i32> [#uses=1] + %tmp39 = bitcast i32 %tmp37 to i32 ; <i32> [#uses=1] + %tmp5 = or i32 %tmp39, %tmp110 ; <i32> [#uses=1] + ret i32 %tmp5 +} + +; CHECK: test6 +; CHECK: pkhtb r0, r0, r1, asr #12 +define i32 @test6(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, -65536 ; <i32> [#uses=1] + %tmp37 = lshr i32 %Y, 12 ; <i32> [#uses=1] + %tmp38 = bitcast i32 %tmp37 to i32 ; <i32> [#uses=1] + %tmp4 = and i32 %tmp38, 65535 ; <i32> [#uses=1] + %tmp59 = or i32 %tmp4, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp59 +} + +; CHECK: test7 +; CHECK: pkhtb r0, r0, r1, asr #18 +define i32 @test7(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, -65536 ; <i32> [#uses=1] + %tmp3 = ashr i32 %Y, 18 ; <i32> [#uses=1] + %tmp4 = and i32 %tmp3, 65535 ; <i32> [#uses=1] + %tmp57 = or i32 %tmp4, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp57 +} + +; CHECK: test8 +; CHECK: pkhtb r0, r0, r1, asr #22 +define i32 @test8(i32 %X, i32 %Y) { + %tmp1 = and i32 %X, -65536 + %tmp3 = lshr i32 %Y, 22 + %tmp57 = or i32 %tmp3, %tmp1 + ret i32 %tmp57 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-rev.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-rev.ll new file mode 100644 index 0000000..b469bbd --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-rev.ll
@@ -0,0 +1,23 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+v7,+t2xtpk | FileCheck %s + +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: rev r0, r0 + %tmp = tail call i32 @llvm.bswap.i32(i32 %a) + ret i32 %tmp +} + +declare i32 @llvm.bswap.i32(i32) nounwind readnone + +define i32 @f2(i32 %X) { +; CHECK: f2: +; CHECK: revsh r0, r0 + %tmp1 = lshr i32 %X, 8 + %tmp1.upgrd.1 = trunc i32 %tmp1 to i16 + %tmp3 = trunc i32 %X to i16 + %tmp2 = and i16 %tmp1.upgrd.1, 255 + %tmp4 = shl i16 %tmp3, 8 + %tmp5 = or i16 %tmp2, %tmp4 + %tmp5.upgrd.2 = sext i16 %tmp5 to i32 + ret i32 %tmp5.upgrd.2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-rev16.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-rev16.ll new file mode 100644 index 0000000..39b6ac3 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-rev16.ll
@@ -0,0 +1,32 @@ +; XFAIL: * +; fixme rev16 pattern is not matching + +; RUN: llc < %s -march=thumb -mattr=+thumb2 | grep {rev16\\W*r\[0-9\]*,\\W*r\[0-9\]*} | count 1 + +; 0xff00ff00 = 4278255360 +; 0x00ff00ff = 16711935 +define i32 @f1(i32 %a) { + %l8 = shl i32 %a, 8 + %r8 = lshr i32 %a, 8 + %mask_l8 = and i32 %l8, 4278255360 + %mask_r8 = and i32 %r8, 16711935 + %tmp = or i32 %mask_l8, %mask_r8 + ret i32 %tmp +} + +; 0xff000000 = 4278190080 +; 0x00ff0000 = 16711680 +; 0x0000ff00 = 65280 +; 0x000000ff = 255 +define i32 @f2(i32 %a) { + %l8 = shl i32 %a, 8 + %r8 = lshr i32 %a, 8 + %masklo_l8 = and i32 %l8, 65280 + %maskhi_l8 = and i32 %l8, 4278190080 + %masklo_r8 = and i32 %r8, 255 + %maskhi_r8 = and i32 %r8, 16711680 + %tmp1 = or i32 %masklo_l8, %masklo_r8 + %tmp2 = or i32 %maskhi_l8, %maskhi_r8 + %tmp = or i32 %tmp1, %tmp2 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-ror.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-ror.ll new file mode 100644 index 0000000..590c333 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-ror.ll
@@ -0,0 +1,24 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + + +; CHECK: f1: +; CHECK: ror.w r0, r0, #22 +define i32 @f1(i32 %a) { + %l8 = shl i32 %a, 10 + %r8 = lshr i32 %a, 22 + %tmp = or i32 %l8, %r8 + ret i32 %tmp +} + +; CHECK: f2: +; CHECK-NOT: and +; CHECK: ror +define i32 @f2(i32 %v, i32 %nbits) { +entry: + %and = and i32 %nbits, 31 + %shr = lshr i32 %v, %and + %sub = sub i32 32, %and + %shl = shl i32 %v, %sub + %or = or i32 %shl, %shr + ret i32 %or +} \ No newline at end of file
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb.ll new file mode 100644 index 0000000..15185be --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb.ll
@@ -0,0 +1,35 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { + %tmp = shl i32 %b, 5 + %tmp1 = sub i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f1: +; CHECK: rsb r0, r0, r1, lsl #5 + +define i32 @f2(i32 %a, i32 %b) { + %tmp = lshr i32 %b, 6 + %tmp1 = sub i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f2: +; CHECK: rsb r0, r0, r1, lsr #6 + +define i32 @f3(i32 %a, i32 %b) { + %tmp = ashr i32 %b, 7 + %tmp1 = sub i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f3: +; CHECK: rsb r0, r0, r1, asr #7 + +define i32 @f4(i32 %a, i32 %b) { + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = sub i32 %tmp, %a + ret i32 %tmp1 +} +; CHECK: f4: +; CHECK: rsb r0, r0, r0, ror #8
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb2.ll new file mode 100644 index 0000000..61fb619 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-rsb2.ll
@@ -0,0 +1,41 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 171 = 0x000000ab +define i32 @f1(i32 %a) { + %tmp = sub i32 171, %a + ret i32 %tmp +} +; CHECK: f1: +; CHECK: rsb.w r0, r0, #171 + +; 1179666 = 0x00120012 +define i32 @f2(i32 %a) { + %tmp = sub i32 1179666, %a + ret i32 %tmp +} +; CHECK: f2: +; CHECK: rsb.w r0, r0, #1179666 + +; 872428544 = 0x34003400 +define i32 @f3(i32 %a) { + %tmp = sub i32 872428544, %a + ret i32 %tmp +} +; CHECK: f3: +; CHECK: rsb.w r0, r0, #872428544 + +; 1448498774 = 0x56565656 +define i32 @f4(i32 %a) { + %tmp = sub i32 1448498774, %a + ret i32 %tmp +} +; CHECK: f4: +; CHECK: rsb.w r0, r0, #1448498774 + +; 66846720 = 0x03fc0000 +define i32 @f5(i32 %a) { + %tmp = sub i32 66846720, %a + ret i32 %tmp +} +; CHECK: f5: +; CHECK: rsb.w r0, r0, #66846720
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sbc.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sbc.ll new file mode 100644 index 0000000..492e5f0 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sbc.ll
@@ -0,0 +1,68 @@ +; RUN: llc -march=thumb -mattr=+thumb2 < %s | FileCheck %s + +define i64 @f1(i64 %a, i64 %b) { +; CHECK: f1 +; CHECK: subs r0, r0, r2 + %tmp = sub i64 %a, %b + ret i64 %tmp +} + +; 734439407618 = 0x000000ab00000002 +define i64 @f2(i64 %a) { +; CHECK: f2 +; CHECK: subs r0, #2 +; CHECK: sbc r1, r1, #171 + %tmp = sub i64 %a, 734439407618 + ret i64 %tmp +} + +; 5066626890203138 = 0x0012001200000002 +define i64 @f3(i64 %a) { +; CHECK: f3 +; CHECK: subs r0, #2 +; CHECK: sbc r1, r1, #1179666 + %tmp = sub i64 %a, 5066626890203138 + ret i64 %tmp +} + +; 3747052064576897026 = 0x3400340000000002 +define i64 @f4(i64 %a) { +; CHECK: f4 +; CHECK: subs r0, #2 +; CHECK: sbc r1, r1, #872428544 + %tmp = sub i64 %a, 3747052064576897026 + ret i64 %tmp +} + +; 6221254862626095106 = 0x5656565600000002 +define i64 @f5(i64 %a) { +; CHECK: f5 +; CHECK: subs r0, #2 +; CHECK: adc r1, r1, #-1448498775 + %tmp = sub i64 %a, 6221254862626095106 + ret i64 %tmp +} + +; 287104476244869122 = 0x03fc000000000002 +define i64 @f6(i64 %a) { +; CHECK: f6 +; CHECK: subs r0, #2 +; CHECK: sbc r1, r1, #66846720 + %tmp = sub i64 %a, 287104476244869122 + ret i64 %tmp +} + +; Example from numerics code that manually computes wider-than-64 values. +; +; CHECK: livecarry: +; CHECK: adds +; CHECK: adc +define i64 @livecarry(i64 %carry, i32 %digit) nounwind { + %ch = lshr i64 %carry, 32 + %cl = and i64 %carry, 4294967295 + %truncdigit = zext i32 %digit to i64 + %prod = add i64 %cl, %truncdigit + %ph = lshr i64 %prod, 32 + %carryresult = add i64 %ch, %ph + ret i64 %carryresult +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-select.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-select.ll new file mode 100644 index 0000000..2dcf8aa --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-select.ll
@@ -0,0 +1,98 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a.s) { +entry: +; CHECK: f1: +; CHECK: it eq +; CHECK: moveq + + %tmp = icmp eq i32 %a.s, 4 + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f2(i32 %a.s) { +entry: +; CHECK: f2: +; CHECK: it gt +; CHECK: movgt + %tmp = icmp sgt i32 %a.s, 4 + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f3(i32 %a.s, i32 %b.s) { +entry: +; CHECK: f3: +; CHECK: it lt +; CHECK: movlt + %tmp = icmp slt i32 %a.s, %b.s + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f4(i32 %a.s, i32 %b.s) { +entry: +; CHECK: f4: +; CHECK: it le +; CHECK: movle + + %tmp = icmp sle i32 %a.s, %b.s + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f5(i32 %a.u, i32 %b.u) { +entry: +; CHECK: f5: +; CHECK: it ls +; CHECK: movls + %tmp = icmp ule i32 %a.u, %b.u + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f6(i32 %a.u, i32 %b.u) { +entry: +; CHECK: f6: +; CHECK: it hi +; CHECK: movhi + %tmp = icmp ugt i32 %a.u, %b.u + %tmp1.s = select i1 %tmp, i32 2, i32 3 + ret i32 %tmp1.s +} + +define i32 @f7(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f7: +; CHECK: it hi +; CHECK: lsrhi.w + %tmp1 = icmp ugt i32 %a, %b + %tmp2 = udiv i32 %c, 3 + %tmp3 = select i1 %tmp1, i32 %tmp2, i32 3 + ret i32 %tmp3 +} + +define i32 @f8(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f8: +; CHECK: it lo +; CHECK: lsllo.w + %tmp1 = icmp ult i32 %a, %b + %tmp2 = mul i32 %c, 4 + %tmp3 = select i1 %tmp1, i32 %tmp2, i32 3 + ret i32 %tmp3 +} + +define i32 @f9(i32 %a, i32 %b, i32 %c) { +entry: +; CHECK: f9: +; CHECK: it ge +; CHECK: rorge.w + %tmp1 = icmp sge i32 %a, %b + %tmp2 = shl i32 %c, 10 + %tmp3 = lshr i32 %c, 22 + %tmp4 = or i32 %tmp2, %tmp3 + %tmp5 = select i1 %tmp1, i32 %tmp4, i32 3 + ret i32 %tmp5 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-select_xform.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-select_xform.ll new file mode 100644 index 0000000..ceefabb --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-select_xform.ll
@@ -0,0 +1,39 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @t1(i32 %a, i32 %b, i32 %c) nounwind { +; CHECK: t1 +; CHECK: mvn r0, #-2147483648 +; CHECK: add r0, r1 +; CHECK: cmp r2, #10 +; CHECK: it gt +; CHECK: movgt r0, r1 + %tmp1 = icmp sgt i32 %c, 10 + %tmp2 = select i1 %tmp1, i32 0, i32 2147483647 + %tmp3 = add i32 %tmp2, %b + ret i32 %tmp3 +} + +define i32 @t2(i32 %a, i32 %b, i32 %c) nounwind { +; CHECK: t2 +; CHECK: add.w r0, r1, #-2147483648 +; CHECK: cmp r2, #10 +; CHECK: it gt +; CHECK: movgt r0, r1 + + %tmp1 = icmp sgt i32 %c, 10 + %tmp2 = select i1 %tmp1, i32 0, i32 2147483648 + %tmp3 = add i32 %tmp2, %b + ret i32 %tmp3 +} + +define i32 @t3(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { +; CHECK: t3 +; CHECK: sub.w r0, r1, #10 +; CHECK: cmp r2, #10 +; CHECK: it gt +; CHECK: movgt r0, r1 + %tmp1 = icmp sgt i32 %c, 10 + %tmp2 = select i1 %tmp1, i32 0, i32 10 + %tmp3 = sub i32 %b, %tmp2 + ret i32 %tmp3 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-shifter.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-shifter.ll new file mode 100644 index 0000000..98854a1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-shifter.ll
@@ -0,0 +1,48 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s + +define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) { +; CHECK: t2ADDrs_lsl +; CHECK: add.w r0, r0, r1, lsl #16 + %A = shl i32 %Y, 16 + %B = add i32 %X, %A + ret i32 %B +} + +define i32 @t2ADDrs_lsr(i32 %X, i32 %Y) { +; CHECK: t2ADDrs_lsr +; CHECK: add.w r0, r0, r1, lsr #16 + %A = lshr i32 %Y, 16 + %B = add i32 %X, %A + ret i32 %B +} + +define i32 @t2ADDrs_asr(i32 %X, i32 %Y) { +; CHECK: t2ADDrs_asr +; CHECK: add.w r0, r0, r1, asr #16 + %A = ashr i32 %Y, 16 + %B = add i32 %X, %A + ret i32 %B +} + +; i32 ror(n) = (x >> n) | (x << (32 - n)) +define i32 @t2ADDrs_ror(i32 %X, i32 %Y) { +; CHECK: t2ADDrs_ror +; CHECK: add.w r0, r0, r1, ror #16 + %A = lshr i32 %Y, 16 + %B = shl i32 %Y, 16 + %C = or i32 %B, %A + %R = add i32 %X, %C + ret i32 %R +} + +define i32 @t2ADDrs_noRegShift(i32 %X, i32 %Y, i8 %sh) { +; CHECK: t2ADDrs_noRegShift +; CHECK: uxtb r2, r2 +; CHECK: lsls r1, r2 +; CHECK: add r0, r1 + %shift.upgrd.1 = zext i8 %sh to i32 + %A = shl i32 %Y, %shift.upgrd.1 + %B = add i32 %X, %A + ret i32 %B +} +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-smla.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-smla.ll new file mode 100644 index 0000000..c128ecc --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-smla.ll
@@ -0,0 +1,11 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk,+t2dsp | FileCheck %s + +define i32 @f3(i32 %a, i16 %x, i32 %y) { +; CHECK: f3 +; CHECK: smlabt r0, r1, r2, r0 + %tmp = sext i16 %x to i32 ; <i32> [#uses=1] + %tmp2 = ashr i32 %y, 16 ; <i32> [#uses=1] + %tmp3 = mul i32 %tmp2, %tmp ; <i32> [#uses=1] + %tmp5 = add i32 %tmp3, %a ; <i32> [#uses=1] + ret i32 %tmp5 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-smul.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-smul.ll new file mode 100644 index 0000000..7a13269 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-smul.ll
@@ -0,0 +1,24 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk,+t2dsp | 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: smulbt r0, r1, r0 + %tmp = load i16* @x ; <i16> [#uses=1] + %tmp1 = add i16 %tmp, 2 ; <i16> [#uses=1] + %tmp2 = sext i16 %tmp1 to i32 ; <i32> [#uses=1] + %tmp3 = ashr i32 %y, 16 ; <i32> [#uses=1] + %tmp4 = mul i32 %tmp2, %tmp3 ; <i32> [#uses=1] + ret i32 %tmp4 +} + +define i32 @f2(i32 %x, i32 %y) { +; CHECK: f2 +; CHECK: smultt r0, r1, r0 + %tmp1 = ashr i32 %x, 16 ; <i32> [#uses=1] + %tmp3 = ashr i32 %y, 16 ; <i32> [#uses=1] + %tmp4 = mul i32 %tmp3, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp4 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-spill-q.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-spill-q.ll new file mode 100644 index 0000000..d9a0617 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-spill-q.ll
@@ -0,0 +1,91 @@ +; RUN: llc < %s -mtriple=thumbv7-elf -mattr=+neon | FileCheck %s +; PR4789 + +%bar = type { float, float, float } +%baz = type { i32, [16 x %bar], [16 x float], [16 x i32], i8 } +%foo = type { <4 x float> } +%quux = type { i32 (...)**, %baz*, i32 } +%quuz = type { %quux, i32, %bar, [128 x i8], [16 x %foo], %foo, %foo, %foo } + +declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly + +define void @aaa(%quuz* %this, i8* %block) { +; CHECK: aaa: +; CHECK: bic r4, r4, #15 +; CHECK: vst1.64 {{.*}}[{{.*}}, :128] +; CHECK: vld1.64 {{.*}}[{{.*}}, :128] +entry: + %aligned_vec = alloca <4 x float>, align 16 + %"alloca point" = bitcast i32 0 to i32 + %vecptr = bitcast <4 x float>* %aligned_vec to i8* + %0 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %vecptr, i32 1) nounwind + store float 6.300000e+01, float* undef, align 4 + %1 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] + store float 0.000000e+00, float* undef, align 4 + %2 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind ; <<4 x float>> [#uses=1] + %ld3 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld4 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld5 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld6 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld7 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld8 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld9 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld10 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld11 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %ld12 = call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* undef, i32 1) nounwind + store float 0.000000e+00, float* undef, align 4 + %val173 = load <4 x float>* undef ; <<4 x float>> [#uses=1] + br label %bb4 + +bb4: ; preds = %bb193, %entry + %besterror.0.2264 = phi <4 x float> [ undef, %entry ], [ %besterror.0.0, %bb193 ] ; <<4 x float>> [#uses=2] + %part0.0.0261 = phi <4 x float> [ zeroinitializer, %entry ], [ %23, %bb193 ] ; <<4 x float>> [#uses=2] + %3 = fmul <4 x float> zeroinitializer, %0 ; <<4 x float>> [#uses=2] + %4 = fadd <4 x float> %3, %part0.0.0261 ; <<4 x float>> [#uses=1] + %5 = shufflevector <4 x float> %3, <4 x float> undef, <2 x i32> <i32 2, i32 3> ; <<2 x float>> [#uses=1] + %6 = shufflevector <2 x float> %5, <2 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1> ; <<4 x float>> [#uses=1] + %7 = fmul <4 x float> %1, undef ; <<4 x float>> [#uses=1] + %8 = fadd <4 x float> %7, <float 5.000000e-01, float 5.000000e-01, float 5.000000e-01, float 5.000000e-01> ; <<4 x float>> [#uses=1] + %9 = fptosi <4 x float> %8 to <4 x i32> ; <<4 x i32>> [#uses=1] + %10 = sitofp <4 x i32> %9 to <4 x float> ; <<4 x float>> [#uses=1] + %11 = fmul <4 x float> %10, %2 ; <<4 x float>> [#uses=1] + %12 = fmul <4 x float> undef, %6 ; <<4 x float>> [#uses=1] + %13 = fmul <4 x float> %11, %4 ; <<4 x float>> [#uses=1] + %14 = fsub <4 x float> %12, %13 ; <<4 x float>> [#uses=1] + %15 = fsub <4 x float> %14, undef ; <<4 x float>> [#uses=1] + %16 = fmul <4 x float> %15, <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float 2.000000e+00> ; <<4 x float>> [#uses=1] + %17 = fadd <4 x float> %16, undef ; <<4 x float>> [#uses=1] + %18 = fmul <4 x float> %17, %val173 ; <<4 x float>> [#uses=1] + %19 = shufflevector <4 x float> %18, <4 x float> undef, <2 x i32> <i32 2, i32 3> ; <<2 x float>> [#uses=1] + %20 = shufflevector <2 x float> %19, <2 x float> undef, <4 x i32> zeroinitializer ; <<4 x float>> [#uses=1] + %tmp1 = fadd <4 x float> %20, %ld3 + %tmp2 = fadd <4 x float> %tmp1, %ld4 + %tmp3 = fadd <4 x float> %tmp2, %ld5 + %tmp4 = fadd <4 x float> %tmp3, %ld6 + %tmp5 = fadd <4 x float> %tmp4, %ld7 + %tmp6 = fadd <4 x float> %tmp5, %ld8 + %tmp7 = fadd <4 x float> %tmp6, %ld9 + %tmp8 = fadd <4 x float> %tmp7, %ld10 + %tmp9 = fadd <4 x float> %tmp8, %ld11 + %21 = fadd <4 x float> %tmp9, %ld12 + %22 = fcmp ogt <4 x float> %besterror.0.2264, %21 ; <<4 x i1>> [#uses=0] + %tmp = extractelement <4 x i1> %22, i32 0 + br i1 %tmp, label %bb193, label %bb186 + +bb186: ; preds = %bb4 + br label %bb193 + +bb193: ; preds = %bb186, %bb4 + %besterror.0.0 = phi <4 x float> [ %21, %bb186 ], [ %besterror.0.2264, %bb4 ] ; <<4 x float>> [#uses=1] + %23 = fadd <4 x float> %part0.0.0261, zeroinitializer ; <<4 x float>> [#uses=1] + br label %bb4 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-str.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-str.ll new file mode 100644 index 0000000..11bb936 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-str.ll
@@ -0,0 +1,76 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32* %v) { +; CHECK: f1: +; CHECK: str r0, [r1] + store i32 %a, i32* %v + ret i32 %a +} + +define i32 @f2(i32 %a, i32* %v) { +; CHECK: f2: +; CHECK: str.w r0, [r1, #4092] + %tmp2 = getelementptr i32* %v, i32 1023 + store i32 %a, i32* %tmp2 + ret i32 %a +} + +define i32 @f2a(i32 %a, i32* %v) { +; CHECK: f2a: +; CHECK: str r0, [r1, #-128] + %tmp2 = getelementptr i32* %v, i32 -32 + store i32 %a, i32* %tmp2 + ret i32 %a +} + +define i32 @f3(i32 %a, i32* %v) { +; CHECK: f3: +; CHECK: mov.w r2, #4096 +; CHECK: str r0, [r1, r2] + %tmp2 = getelementptr i32* %v, i32 1024 + store i32 %a, i32* %tmp2 + ret i32 %a +} + +define i32 @f4(i32 %a, i32 %base) { +entry: +; CHECK: f4: +; CHECK: str r0, [r1, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i32* + store i32 %a, i32* %tmp2 + ret i32 %a +} + +define i32 @f5(i32 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: str r0, [r1, r2] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i32* + store i32 %a, i32* %tmp2 + ret i32 %a +} + +define i32 @f6(i32 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: str.w r0, [r1, r2, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i32* + store i32 %a, i32* %tmp3 + ret i32 %a +} + +define i32 @f7(i32 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r2, r2, #2 +; CHECK: str r0, [r1, r2] + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i32* + store i32 %a, i32* %tmp3 + ret i32 %a +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-str_post.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-str_post.ll new file mode 100644 index 0000000..bbfb447 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-str_post.ll
@@ -0,0 +1,22 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i16 @test1(i32* %X, i16* %A) { +; CHECK: test1: +; CHECK: strh {{.*}}[{{.*}}], #-4 + %Y = load i32* %X ; <i32> [#uses=1] + %tmp1 = trunc i32 %Y to i16 ; <i16> [#uses=1] + store i16 %tmp1, i16* %A + %tmp2 = ptrtoint i16* %A to i16 ; <i16> [#uses=1] + %tmp3 = sub i16 %tmp2, 4 ; <i16> [#uses=1] + ret i16 %tmp3 +} + +define i32 @test2(i32* %X, i32* %A) { +; CHECK: test2: +; CHECK: str {{.*}}[{{.*}}], + %Y = load i32* %X ; <i32> [#uses=1] + store i32 %Y, i32* %A + %tmp1 = ptrtoint i32* %A to i32 ; <i32> [#uses=1] + %tmp2 = sub i32 %tmp1, 4 ; <i32> [#uses=1] + ret i32 %tmp2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-str_pre.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-str_pre.ll new file mode 100644 index 0000000..1e6616a --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-str_pre.ll
@@ -0,0 +1,21 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define void @test1(i32* %X, i32* %A, i32** %dest) { +; CHECK: test1 +; CHECK: str r1, [r0, #16]! + %B = load i32* %A ; <i32> [#uses=1] + %Y = getelementptr i32* %X, i32 4 ; <i32*> [#uses=2] + store i32 %B, i32* %Y + store i32* %Y, i32** %dest + ret void +} + +define i16* @test2(i16* %X, i32* %A) { +; CHECK: test2 +; CHECK: strh r1, [r0, #8]! + %B = load i32* %A ; <i32> [#uses=1] + %Y = getelementptr i16* %X, i32 4 ; <i16*> [#uses=2] + %tmp = trunc i32 %B to i16 ; <i16> [#uses=1] + store i16 %tmp, i16* %Y + ret i16* %Y +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-strb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-strb.ll new file mode 100644 index 0000000..7978e7f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-strb.ll
@@ -0,0 +1,76 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i8 @f1(i8 %a, i8* %v) { +; CHECK: f1: +; CHECK: strb r0, [r1] + store i8 %a, i8* %v + ret i8 %a +} + +define i8 @f2(i8 %a, i8* %v) { +; CHECK: f2: +; CHECK: strb.w r0, [r1, #4092] + %tmp2 = getelementptr i8* %v, i32 4092 + store i8 %a, i8* %tmp2 + ret i8 %a +} + +define i8 @f2a(i8 %a, i8* %v) { +; CHECK: f2a: +; CHECK: strb r0, [r1, #-128] + %tmp2 = getelementptr i8* %v, i32 -128 + store i8 %a, i8* %tmp2 + ret i8 %a +} + +define i8 @f3(i8 %a, i8* %v) { +; CHECK: f3: +; CHECK: mov.w r2, #4096 +; CHECK: strb r0, [r1, r2] + %tmp2 = getelementptr i8* %v, i32 4096 + store i8 %a, i8* %tmp2 + ret i8 %a +} + +define i8 @f4(i8 %a, i32 %base) { +entry: +; CHECK: f4: +; CHECK: strb r0, [r1, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i8* + store i8 %a, i8* %tmp2 + ret i8 %a +} + +define i8 @f5(i8 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: strb r0, [r1, r2] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i8* + store i8 %a, i8* %tmp2 + ret i8 %a +} + +define i8 @f6(i8 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: strb.w r0, [r1, r2, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i8* + store i8 %a, i8* %tmp3 + ret i8 %a +} + +define i8 @f7(i8 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r2, r2, #2 +; CHECK: strb r0, [r1, r2] + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i8* + store i8 %a, i8* %tmp3 + ret i8 %a +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-strh.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-strh.ll new file mode 100644 index 0000000..97110a7 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-strh.ll
@@ -0,0 +1,76 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i16 @f1(i16 %a, i16* %v) { +; CHECK: f1: +; CHECK: strh r0, [r1] + store i16 %a, i16* %v + ret i16 %a +} + +define i16 @f2(i16 %a, i16* %v) { +; CHECK: f2: +; CHECK: strh.w r0, [r1, #4092] + %tmp2 = getelementptr i16* %v, i32 2046 + store i16 %a, i16* %tmp2 + ret i16 %a +} + +define i16 @f2a(i16 %a, i16* %v) { +; CHECK: f2a: +; CHECK: strh r0, [r1, #-128] + %tmp2 = getelementptr i16* %v, i32 -64 + store i16 %a, i16* %tmp2 + ret i16 %a +} + +define i16 @f3(i16 %a, i16* %v) { +; CHECK: f3: +; CHECK: mov.w r2, #4096 +; CHECK: strh r0, [r1, r2] + %tmp2 = getelementptr i16* %v, i32 2048 + store i16 %a, i16* %tmp2 + ret i16 %a +} + +define i16 @f4(i16 %a, i32 %base) { +entry: +; CHECK: f4: +; CHECK: strh r0, [r1, #-128] + %tmp1 = sub i32 %base, 128 + %tmp2 = inttoptr i32 %tmp1 to i16* + store i16 %a, i16* %tmp2 + ret i16 %a +} + +define i16 @f5(i16 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f5: +; CHECK: strh r0, [r1, r2] + %tmp1 = add i32 %base, %offset + %tmp2 = inttoptr i32 %tmp1 to i16* + store i16 %a, i16* %tmp2 + ret i16 %a +} + +define i16 @f6(i16 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f6: +; CHECK: strh.w r0, [r1, r2, lsl #2] + %tmp1 = shl i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i16* + store i16 %a, i16* %tmp3 + ret i16 %a +} + +define i16 @f7(i16 %a, i32 %base, i32 %offset) { +entry: +; CHECK: f7: +; CHECK: lsrs r2, r2, #2 +; CHECK: strh r0, [r1, r2] + %tmp1 = lshr i32 %offset, 2 + %tmp2 = add i32 %base, %tmp1 + %tmp3 = inttoptr i32 %tmp2 to i16* + store i16 %a, i16* %tmp3 + ret i16 %a +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sub.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub.ll new file mode 100644 index 0000000..95335a2 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub.ll
@@ -0,0 +1,49 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +; 171 = 0x000000ab +define i32 @f1(i32 %a) { +; CHECK: f1: +; CHECK: subs r0, #171 + %tmp = sub i32 %a, 171 + ret i32 %tmp +} + +; 1179666 = 0x00120012 +define i32 @f2(i32 %a) { +; CHECK: f2: +; CHECK: sub.w r0, r0, #1179666 + %tmp = sub i32 %a, 1179666 + ret i32 %tmp +} + +; 872428544 = 0x34003400 +define i32 @f3(i32 %a) { +; CHECK: f3: +; CHECK: sub.w r0, r0, #872428544 + %tmp = sub i32 %a, 872428544 + ret i32 %tmp +} + +; 1448498774 = 0x56565656 +define i32 @f4(i32 %a) { +; CHECK: f4: +; CHECK: sub.w r0, r0, #1448498774 + %tmp = sub i32 %a, 1448498774 + ret i32 %tmp +} + +; 510 = 0x000001fe +define i32 @f5(i32 %a) { +; CHECK: f5: +; CHECK: sub.w r0, r0, #510 + %tmp = sub i32 %a, 510 + ret i32 %tmp +} + +; Don't change this to an add. +define i32 @f6(i32 %a) { +; CHECK: f6: +; CHECK: subs r0, #1 + %tmp = sub i32 %a, 1 + ret i32 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sub2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub2.ll new file mode 100644 index 0000000..bb99cbd --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub2.ll
@@ -0,0 +1,8 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a) { + %tmp = sub i32 %a, 4095 + ret i32 %tmp +} +; CHECK: f1: +; CHECK: subw r0, r0, #4095
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sub3.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub3.ll new file mode 100644 index 0000000..1dbda57 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub3.ll
@@ -0,0 +1,55 @@ +; RUN: llc -march=thumb -mattr=+thumb2 < %s | FileCheck %s + +; 171 = 0x000000ab +define i64 @f1(i64 %a) { +; CHECK: f1 +; CHECK: subs r0, #171 +; CHECK: sbc r1, r1, #0 + %tmp = sub i64 %a, 171 + ret i64 %tmp +} + +; 1179666 = 0x00120012 +define i64 @f2(i64 %a) { +; CHECK: f2 +; CHECK: subs.w r0, r0, #1179666 +; CHECK: sbc r1, r1, #0 + %tmp = sub i64 %a, 1179666 + ret i64 %tmp +} + +; 872428544 = 0x34003400 +define i64 @f3(i64 %a) { +; CHECK: f3 +; CHECK: subs.w r0, r0, #872428544 +; CHECK: sbc r1, r1, #0 + %tmp = sub i64 %a, 872428544 + ret i64 %tmp +} + +; 1448498774 = 0x56565656 +define i64 @f4(i64 %a) { +; CHECK: f4 +; CHECK: subs.w r0, r0, #1448498774 +; CHECK: sbc r1, r1, #0 + %tmp = sub i64 %a, 1448498774 + ret i64 %tmp +} + +; 66846720 = 0x03fc0000 +define i64 @f5(i64 %a) { +; CHECK: f5 +; CHECK: subs.w r0, r0, #66846720 +; CHECK: sbc r1, r1, #0 + %tmp = sub i64 %a, 66846720 + ret i64 %tmp +} + +; 734439407618 = 0x000000ab00000002 +define i64 @f6(i64 %a) { +; CHECK: f6 +; CHECK: subs r0, #2 +; CHECK: sbc r1, r1, #171 + %tmp = sub i64 %a, 734439407618 + ret i64 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sub4.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub4.ll new file mode 100644 index 0000000..a040d17 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub4.ll
@@ -0,0 +1,42 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 | FileCheck %s + +define i32 @f1(i32 %a, i32 %b) { +; CHECK: f1: +; CHECK: subs r0, r0, r1 + %tmp = sub i32 %a, %b + ret i32 %tmp +} + +define i32 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: sub.w r0, r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = sub i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f3(i32 %a, i32 %b) { +; CHECK: f3: +; CHECK: sub.w r0, r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = sub i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: sub.w r0, r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = sub i32 %a, %tmp + ret i32 %tmp1 +} + +define i32 @f5(i32 %a, i32 %b) { +; CHECK: f5: +; CHECK: sub.w r0, r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = sub i32 %a, %tmp + ret i32 %tmp1 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sub5.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub5.ll new file mode 100644 index 0000000..6edd789 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sub5.ll
@@ -0,0 +1,10 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -mattr=+32bit | FileCheck %s + +define i64 @f1(i64 %a, i64 %b) { +; CHECK: f1: +; CHECK: subs.w r0, r0, r2 +; To test dead_carry, +32bit prevents sbc conveting to 16-bit sbcs +; CHECK: sbc.w r1, r1, r3 + %tmp = sub i64 %a, %b + ret i64 %tmp +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt-uxt.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt-uxt.ll new file mode 100644 index 0000000..ab888e6 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt-uxt.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -march=thumb -mcpu=cortex-m3 | FileCheck %s + +define i32 @test1(i16 zeroext %z) nounwind { +; CHECK: test1: +; CHECK: sxth + %r = sext i16 %z to i32 + ret i32 %r +} + +define i32 @test2(i8 zeroext %z) nounwind { +; CHECK: test2: +; CHECK: sxtb + %r = sext i8 %z to i32 + ret i32 %r +} + +define i32 @test3(i16 signext %z) nounwind { +; CHECK: test3: +; CHECK: uxth + %r = zext i16 %z to i32 + ret i32 %r +} + +define i32 @test4(i8 signext %z) nounwind { +; CHECK: test4: +; CHECK: uxtb + %r = zext i8 %z to i32 + ret i32 %r +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt_rot.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt_rot.ll new file mode 100644 index 0000000..f3d0edf --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-sxt_rot.ll
@@ -0,0 +1,31 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s + +define i32 @test0(i8 %A) { +; CHECK: test0 +; CHECK: sxtb r0, r0 + %B = sext i8 %A to i32 + ret i32 %B +} + +define signext i8 @test1(i32 %A) { +; CHECK: test1 +; CHECK: sxtb.w 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) { +; CHECK: test2 +; CHECK: lsrs r0, r0, #8 +; 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/src/LLVM/test/CodeGen/Thumb2/thumb2-tbb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-tbb.ll new file mode 100644 index 0000000..5dc3cc3 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-tbb.ll
@@ -0,0 +1,57 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -relocation-model=pic | FileCheck %s + +define void @bar(i32 %n.u) { +entry: +; CHECK: bar: +; CHECK: tbb +; CHECK: .align 1 + + switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ] +bb: + tail call void(...)* @foo1() + ret void +bb1: + tail call void(...)* @foo2() + ret void +bb2: + tail call void(...)* @foo6() + ret void +bb3: + tail call void(...)* @foo3() + ret void +bb4: + tail call void(...)* @foo4() + ret void +bb5: + tail call void(...)* @foo5() + ret void +bb6: + tail call void(...)* @foo1() + ret void +bb7: + tail call void(...)* @foo2() + ret void +bb8: + tail call void(...)* @foo6() + ret void +bb9: + tail call void(...)* @foo3() + ret void +bb10: + tail call void(...)* @foo4() + ret void +bb11: + tail call void(...)* @foo5() + ret void +bb12: + tail call void(...)* @foo6() + ret void +} + +declare void @foo1(...) +declare void @foo2(...) +declare void @foo6(...) +declare void @foo3(...) +declare void @foo4(...) +declare void @foo5(...)
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-tbh.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-tbh.ll new file mode 100644 index 0000000..cd9c8e1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-tbh.ll
@@ -0,0 +1,84 @@ +; RUN: llc < %s -mtriple=thumbv7-apple-darwin -relocation-model=pic | FileCheck %s + +; Thumb2 target should reorder the bb's in order to use tbb / tbh. + + %struct.R_flstr = type { i32, i32, i8* } + %struct._T_tstr = type { i32, %struct.R_flstr*, %struct._T_tstr* } +@_C_nextcmd = external global i32 ; <i32*> [#uses=3] +@.str31 = external constant [28 x i8], align 1 ; <[28 x i8]*> [#uses=1] +@_T_gtol = external global %struct._T_tstr* ; <%struct._T_tstr**> [#uses=2] + +declare i32 @strlen(i8* nocapture) nounwind readonly + +declare void @Z_fatal(i8*) noreturn nounwind + +declare noalias i8* @calloc(i32, i32) nounwind + +define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { +; CHECK: main: +; CHECK: tbb +entry: + br label %bb42.i + +bb1.i2: ; preds = %bb42.i + br label %bb40.i + +bb5.i: ; preds = %bb42.i + %0 = or i32 %argc, 32 ; <i32> [#uses=1] + br label %bb40.i + +bb7.i: ; preds = %bb42.i + call void @_T_addtol(%struct._T_tstr** @_T_gtol, i32 0, i8* null) nounwind + unreachable + +bb15.i: ; preds = %bb42.i + call void @_T_addtol(%struct._T_tstr** @_T_gtol, i32 2, i8* null) nounwind + unreachable + +bb23.i: ; preds = %bb42.i + %1 = call i32 @strlen(i8* null) nounwind readonly ; <i32> [#uses=0] + unreachable + +bb33.i: ; preds = %bb42.i + store i32 0, i32* @_C_nextcmd, align 4 + %2 = call noalias i8* @calloc(i32 21, i32 1) nounwind ; <i8*> [#uses=0] + unreachable + +bb34.i: ; preds = %bb42.i + %3 = load i32* @_C_nextcmd, align 4 ; <i32> [#uses=1] + %4 = add i32 %3, 1 ; <i32> [#uses=1] + store i32 %4, i32* @_C_nextcmd, align 4 + %5 = call noalias i8* @calloc(i32 22, i32 1) nounwind ; <i8*> [#uses=0] + unreachable + +bb35.i: ; preds = %bb42.i + %6 = call noalias i8* @calloc(i32 20, i32 1) nounwind ; <i8*> [#uses=0] + unreachable + +bb37.i: ; preds = %bb42.i + %7 = call noalias i8* @calloc(i32 14, i32 1) nounwind ; <i8*> [#uses=0] + unreachable + +bb39.i: ; preds = %bb42.i + call void @Z_fatal(i8* getelementptr ([28 x i8]* @.str31, i32 0, i32 0)) nounwind + unreachable + +bb40.i: ; preds = %bb42.i, %bb5.i, %bb1.i2 + br label %bb42.i + +bb42.i: ; preds = %bb40.i, %entry + switch i32 %argc, label %bb39.i [ + i32 67, label %bb33.i + i32 70, label %bb35.i + i32 77, label %bb37.i + i32 83, label %bb34.i + i32 97, label %bb7.i + i32 100, label %bb5.i + i32 101, label %bb40.i + i32 102, label %bb23.i + i32 105, label %bb15.i + i32 116, label %bb1.i2 + ] +} + +declare void @_T_addtol(%struct._T_tstr** nocapture, i32, i8*) nounwind
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-teq.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-teq.ll new file mode 100644 index 0000000..00c928f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-teq.ll
@@ -0,0 +1,57 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; test as 'mov.w r0, #0'. So far, that requires physreg joining. + +; 0x000000bb = 187 +define i1 @f2(i32 %a) { + %tmp = xor i32 %a, 187 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f2: +; CHECK: teq.w r0, #187 + +; 0x00aa00aa = 11141290 +define i1 @f3(i32 %a) { + %tmp = xor i32 %a, 11141290 + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} +; CHECK: f3: +; CHECK: teq.w r0, #11141290 + +; 0xcc00cc00 = 3422604288 +define i1 @f6(i32 %a) { + %tmp = xor i32 %a, 3422604288 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f6: +; CHECK: teq.w r0, #-872363008 + +; 0xdddddddd = 3722304989 +define i1 @f7(i32 %a) { + %tmp = xor i32 %a, 3722304989 + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} +; CHECK: f7: +; CHECK: teq.w r0, #-572662307 + +; 0xdddddddd = 3722304989 +define i1 @f8(i32 %a) { + %tmp = xor i32 %a, 3722304989 + %tmp1 = icmp ne i32 0, %tmp + ret i1 %tmp1 +} + +; 0x00110000 = 1114112 +define i1 @f10(i32 %a) { + %tmp = xor i32 %a, 1114112 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f10: +; CHECK: teq.w r0, #1114112 +
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-teq2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-teq2.ll new file mode 100644 index 0000000..8acae90 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-teq2.ll
@@ -0,0 +1,58 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; tst as 'mov.w r0, #0'. So far, that requires physreg joining. + +define i1 @f2(i32 %a, i32 %b) { +; CHECK: f2 +; CHECK: teq.w r0, r1 + %tmp = xor i32 %a, %b + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} + +define i1 @f4(i32 %a, i32 %b) { +; CHECK: f4 +; CHECK: teq.w r0, r1 + %tmp = xor i32 %a, %b + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} + +define i1 @f6(i32 %a, i32 %b) { +; CHECK: f6 +; CHECK: teq.w r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = xor i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f7(i32 %a, i32 %b) { +; CHECK: f7 +; CHECK: teq.w r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = xor i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f8(i32 %a, i32 %b) { +; CHECK: f8 +; CHECK: teq.w r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = xor i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f9(i32 %a, i32 %b) { +; CHECK: f9 +; CHECK: teq.w r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = xor i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-tst.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-tst.ll new file mode 100644 index 0000000..43e208c --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-tst.ll
@@ -0,0 +1,49 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; tst as 'mov.w r0, #0'. So far, that requires physreg joining. + +; 0x000000bb = 187 +define i1 @f2(i32 %a) { + %tmp = and i32 %a, 187 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f2: +; CHECK: tst.w r0, #187 + +; 0x00aa00aa = 11141290 +define i1 @f3(i32 %a) { + %tmp = and i32 %a, 11141290 + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} +; CHECK: f3: +; CHECK: tst.w r0, #11141290 + +; 0xcc00cc00 = 3422604288 +define i1 @f6(i32 %a) { + %tmp = and i32 %a, 3422604288 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f6: +; CHECK: tst.w r0, #-872363008 + +; 0xdddddddd = 3722304989 +define i1 @f7(i32 %a) { + %tmp = and i32 %a, 3722304989 + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} +; CHECK: f7: +; CHECK: tst.w r0, #-572662307 + +; 0x00110000 = 1114112 +define i1 @f10(i32 %a) { + %tmp = and i32 %a, 1114112 + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} +; CHECK: f10: +; CHECK: tst.w r0, #1114112
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-tst2.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-tst2.ll new file mode 100644 index 0000000..bfe016f --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-tst2.ll
@@ -0,0 +1,58 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2 -join-physregs | FileCheck %s + +; These tests implicitly depend on 'movs r0, #0' being rematerialized below the +; tst as 'mov.w r0, #0'. So far, that requires physreg joining. + +define i1 @f2(i32 %a, i32 %b) { +; CHECK: f2: +; CHECK: tst r0, r1 + %tmp = and i32 %a, %b + %tmp1 = icmp eq i32 %tmp, 0 + ret i1 %tmp1 +} + +define i1 @f4(i32 %a, i32 %b) { +; CHECK: f4: +; CHECK: tst r0, r1 + %tmp = and i32 %a, %b + %tmp1 = icmp eq i32 0, %tmp + ret i1 %tmp1 +} + +define i1 @f6(i32 %a, i32 %b) { +; CHECK: f6: +; CHECK: tst.w r0, r1, lsl #5 + %tmp = shl i32 %b, 5 + %tmp1 = and i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f7(i32 %a, i32 %b) { +; CHECK: f7: +; CHECK: tst.w r0, r1, lsr #6 + %tmp = lshr i32 %b, 6 + %tmp1 = and i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f8(i32 %a, i32 %b) { +; CHECK: f8: +; CHECK: tst.w r0, r1, asr #7 + %tmp = ashr i32 %b, 7 + %tmp1 = and i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +} + +define i1 @f9(i32 %a, i32 %b) { +; CHECK: f9: +; CHECK: tst.w r0, r0, ror #8 + %l8 = shl i32 %a, 24 + %r8 = lshr i32 %a, 8 + %tmp = or i32 %l8, %r8 + %tmp1 = and i32 %a, %tmp + %tmp2 = icmp eq i32 %tmp1, 0 + ret i1 %tmp2 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-uxt_rot.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-uxt_rot.ll new file mode 100644 index 0000000..03189aa --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-uxt_rot.ll
@@ -0,0 +1,28 @@ +; RUN: llc < %s -march=thumb -mattr=+thumb2,+t2xtpk | FileCheck %s + +define zeroext i8 @test1(i32 %A.u) { +; CHECK: test1 +; CHECK: uxtb r0, r0 + %B.u = trunc i32 %A.u to i8 + ret i8 %B.u +} + +define zeroext i32 @test2(i32 %A.u, i32 %B.u) { +; CHECK: test2 +; CHECK: uxtab r0, r0, r1 + %C.u = trunc i32 %B.u to i8 + %D.u = zext i8 %C.u to i32 + %E.u = add i32 %A.u, %D.u + ret i32 %E.u +} + +define zeroext i32 @test3(i32 %A.u) { +; CHECK: test3 +; CHECK: uxth.w r0, r0, ror #8 + %B.u = lshr i32 %A.u, 8 + %C.u = shl i32 %A.u, 24 + %D.u = or i32 %B.u, %C.u + %E.u = trunc i32 %D.u to i16 + %F.u = zext i16 %E.u to i32 + ret i32 %F.u +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/thumb2-uxtb.ll b/src/LLVM/test/CodeGen/Thumb2/thumb2-uxtb.ll new file mode 100644 index 0000000..35914b1 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/thumb2-uxtb.ll
@@ -0,0 +1,141 @@ +; RUN: llc < %s -march=thumb -mcpu=cortex-a8 | FileCheck %s -check-prefix=ARMv7A +; RUN: llc < %s -march=thumb -mcpu=cortex-m3 | FileCheck %s -check-prefix=ARMv7M + +define i32 @test1(i32 %x) { +; ARMv7A: test1 +; ARMv7A: uxtb16 r0, r0 + +; ARMv7M: test1 +; ARMv7M: bic r0, r0, #-16711936 + %tmp1 = and i32 %x, 16711935 ; <i32> [#uses=1] + ret i32 %tmp1 +} + +; PR7503 +define i32 @test2(i32 %x) { +; ARMv7A: test2 +; ARMv7A: uxtb16 r0, r0, ror #8 + +; ARMv7M: test2 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, lsr #8 + %tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1] + ret i32 %tmp2 +} + +define i32 @test3(i32 %x) { +; ARMv7A: test3 +; ARMv7A: uxtb16 r0, r0, ror #8 + +; ARMv7M: test3 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, lsr #8 + %tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1] + ret i32 %tmp2 +} + +define i32 @test4(i32 %x) { +; ARMv7A: test4 +; ARMv7A: uxtb16 r0, r0, ror #8 + +; ARMv7M: test4 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, lsr #8 + %tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1] + %tmp6 = and i32 %tmp1, 16711935 ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @test5(i32 %x) { +; ARMv7A: test5 +; ARMv7A: uxtb16 r0, r0, ror #8 + +; ARMv7M: test5 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, lsr #8 + %tmp1 = lshr i32 %x, 8 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 16711935 ; <i32> [#uses=1] + ret i32 %tmp2 +} + +define i32 @test6(i32 %x) { +; ARMv7A: test6 +; ARMv7A: uxtb16 r0, r0, ror #16 + +; ARMv7M: test6 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, ror #16 + %tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1] + %tmp4 = shl i32 %x, 16 ; <i32> [#uses=1] + %tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1] + %tmp6 = or i32 %tmp2, %tmp5 ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @test7(i32 %x) { +; ARMv7A: test7 +; ARMv7A: uxtb16 r0, r0, ror #16 + +; ARMv7M: test7 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, ror #16 + %tmp1 = lshr i32 %x, 16 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 255 ; <i32> [#uses=1] + %tmp4 = shl i32 %x, 16 ; <i32> [#uses=1] + %tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1] + %tmp6 = or i32 %tmp2, %tmp5 ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @test8(i32 %x) { +; ARMv7A: test8 +; ARMv7A: uxtb16 r0, r0, ror #24 + +; ARMv7M: test8 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, ror #24 + %tmp1 = shl i32 %x, 8 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 16711680 ; <i32> [#uses=1] + %tmp5 = lshr i32 %x, 24 ; <i32> [#uses=1] + %tmp6 = or i32 %tmp2, %tmp5 ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @test9(i32 %x) { +; ARMv7A: test9 +; ARMv7A: uxtb16 r0, r0, ror #24 + +; ARMv7M: test9 +; ARMv7M: mov.w r1, #16711935 +; ARMv7M: and.w r0, r1, r0, ror #24 + %tmp1 = lshr i32 %x, 24 ; <i32> [#uses=1] + %tmp4 = shl i32 %x, 8 ; <i32> [#uses=1] + %tmp5 = and i32 %tmp4, 16711680 ; <i32> [#uses=1] + %tmp6 = or i32 %tmp5, %tmp1 ; <i32> [#uses=1] + ret i32 %tmp6 +} + +define i32 @test10(i32 %p0) { +; ARMv7A: test10 +; ARMv7A: mov.w r1, #16253176 +; ARMv7A: and.w r0, r1, r0, lsr #7 +; ARMv7A: lsrs r1, r0, #5 +; ARMv7A: uxtb16 r1, r1 +; ARMv7A: orrs r0, r1 + +; ARMv7M: test10 +; ARMv7M: mov.w r1, #16253176 +; ARMv7M: mov.w r2, #458759 +; ARMv7M: and.w r0, r1, r0, lsr #7 +; ARMv7M: and.w r1, r2, r0, lsr #5 +; ARMv7M: orrs r0, r1 + %tmp1 = lshr i32 %p0, 7 ; <i32> [#uses=1] + %tmp2 = and i32 %tmp1, 16253176 ; <i32> [#uses=2] + %tmp4 = lshr i32 %tmp2, 5 ; <i32> [#uses=1] + %tmp5 = and i32 %tmp4, 458759 ; <i32> [#uses=1] + %tmp7 = or i32 %tmp5, %tmp2 ; <i32> [#uses=1] + ret i32 %tmp7 +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/tls1.ll b/src/LLVM/test/CodeGen/Thumb2/tls1.ll new file mode 100644 index 0000000..1e55557 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/tls1.ll
@@ -0,0 +1,20 @@ +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \ +; RUN: grep {i(tpoff)} +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \ +; RUN: grep {__aeabi_read_tp} +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi \ +; RUN: -relocation-model=pic | grep {__tls_get_addr} + + +@i = thread_local global i32 15 ; <i32*> [#uses=2] + +define i32 @f() { +entry: + %tmp1 = load i32* @i ; <i32> [#uses=1] + ret i32 %tmp1 +} + +define i32* @g() { +entry: + ret i32* @i +}
diff --git a/src/LLVM/test/CodeGen/Thumb2/tls2.ll b/src/LLVM/test/CodeGen/Thumb2/tls2.ll new file mode 100644 index 0000000..b8a0657 --- /dev/null +++ b/src/LLVM/test/CodeGen/Thumb2/tls2.ll
@@ -0,0 +1,29 @@ +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | FileCheck %s -check-prefix=CHECK-NOT-PIC +; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -relocation-model=pic | FileCheck %s -check-prefix=CHECK-PIC + +@i = external thread_local global i32 ; <i32*> [#uses=2] + +define i32 @f() { +entry: +; CHECK-NOT-PIC: f: +; CHECK-NOT-PIC: add r0, pc +; CHECK-NOT-PIC: ldr r1, [r0] +; CHECK-NOT-PIC: i(gottpoff) + +; CHECK-PIC: f: +; CHECK-PIC: bl __tls_get_addr(PLT) + %tmp1 = load i32* @i ; <i32> [#uses=1] + ret i32 %tmp1 +} + +define i32* @g() { +entry: +; CHECK-NOT-PIC: g: +; CHECK-NOT-PIC: add r0, pc +; CHECK-NOT-PIC: ldr r1, [r0] +; CHECK-NOT-PIC: i(gottpoff) + +; CHECK-PIC: g: +; CHECK-PIC: bl __tls_get_addr(PLT) + ret i32* @i +}