Index: lib/Target/ARM/ARMLoadStoreOptimizer.cpp =================================================================== --- lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -1027,6 +1027,18 @@ if (AssumeMisalignedLoadStores && !mayCombineMisaligned(*STI, *MI)) CanMergeToLSMulti = CanMergeToLSDouble = false; + // vldm / vstm limit are 32 for S variants, 16 for D variants. + unsigned Limit; + switch (Opcode) { + default: + Limit = UINT_MAX; + break; + case ARM::VLDRD: + case ARM::VSTRD: + Limit = 16; + break; + } + // Merge following instructions where possible. for (unsigned I = SIndex+1; I < EIndex; ++I, ++Count) { int NewOffset = MemOps[I].Offset; @@ -1036,6 +1048,8 @@ unsigned Reg = MO.getReg(); if (Reg == ARM::SP || Reg == ARM::PC) break; + if (Count == Limit) + break; // See if the current load/store may be part of a multi load/store. unsigned RegNum = MO.isUndef() ? std::numeric_limits::max() Index: test/CodeGen/ARM/load-multiple-opt.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/load-multiple-opt.ll @@ -0,0 +1,300 @@ +; RUN: llc %s -o - -debug-only=arm-ldst-opt | FileCheck %s +; CHECK-NOT: vstmia r4, {d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31} +; CHECK: vstmia r4, {d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30} +; CHECK-NEXT: vstr d31, [r4, #128] +; CHECK: vstmia r0, {d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14} + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv7--linux-android" + +%struct.ak = type { %struct.bk } +%struct.bk = type { %struct.m } +%struct.m = type { [64 x %struct.bw] } +%struct.bw = type { double, %struct.ak.1 } +%struct.ak.1 = type { %struct.bk.2 } +%struct.bk.2 = type { %struct.m.4 } +%struct.m.4 = type { [64 x double] } +%struct.l = type { i8 } + +; Function Attrs: ssp uwtable +define void @_Z2brR1lI1ME(%struct.ak* noalias sret, %struct.l* nocapture readonly dereferenceable(1)) { + %3 = alloca %struct.bw, align 8 + %4 = tail call %struct.ak* @_ZN2akI2bwEC1Ev(%struct.ak* %0) + %5 = bitcast %struct.bw* %3 to i8* + call void @llvm.lifetime.start.p0i8(i64 520, i8* nonnull %5) + %6 = call %struct.bw* @_ZN2bwC1Ed(%struct.bw* nonnull %3, double 2.000000e+00) + %7 = bitcast %struct.l* %1 to %struct.bw** + %8 = load %struct.bw*, %struct.bw** %7, align 4, !noalias !1 + %9 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 0 + %10 = load double, double* %9, align 8 + %11 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 0 + %12 = load double, double* %11, align 8 + %13 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 1 + %14 = load double, double* %13, align 8 + %15 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 2 + %16 = load double, double* %15, align 8 + %17 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 3 + %18 = load double, double* %17, align 8 + %19 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 4 + %20 = load double, double* %19, align 8 + %21 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 5 + %22 = load double, double* %21, align 8 + %23 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 6 + %24 = load double, double* %23, align 8 + %25 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 7 + %26 = load double, double* %25, align 8 + %27 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 8 + %28 = load double, double* %27, align 8 + %29 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 9 + %30 = load double, double* %29, align 8 + %31 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 10 + %32 = load double, double* %31, align 8 + %33 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 11 + %34 = load double, double* %33, align 8 + %35 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 12 + %36 = load double, double* %35, align 8 + %37 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 13 + %38 = load double, double* %37, align 8 + %39 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 14 + %40 = load double, double* %39, align 8 + %41 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 15 + %42 = load double, double* %41, align 8 + %43 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 16 + %44 = load double, double* %43, align 8 + %45 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 17 + %46 = load double, double* %45, align 8 + %47 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 18 + %48 = load double, double* %47, align 8 + %49 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 19 + %50 = load double, double* %49, align 8 + %51 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 20 + %52 = load double, double* %51, align 8 + %53 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 21 + %54 = load double, double* %53, align 8 + %55 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 22 + %56 = load double, double* %55, align 8 + %57 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 23 + %58 = load double, double* %57, align 8 + %59 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 24 + %60 = load double, double* %59, align 8 + %61 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 25 + %62 = load double, double* %61, align 8 + %63 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 26 + %64 = load double, double* %63, align 8 + %65 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 27 + %66 = load double, double* %65, align 8 + %67 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 28 + %68 = load double, double* %67, align 8 + %69 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 29 + %70 = load double, double* %69, align 8 + %71 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 30 + %72 = load double, double* %71, align 8 + %73 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 31 + %74 = load double, double* %73, align 8 + %75 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 32 + %76 = load double, double* %75, align 8 + %77 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 33 + %78 = load double, double* %77, align 8 + %79 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 34 + %80 = load double, double* %79, align 8 + %81 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 35 + %82 = load double, double* %81, align 8 + %83 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 36 + %84 = load double, double* %83, align 8 + %85 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 37 + %86 = load double, double* %85, align 8 + %87 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 38 + %88 = load double, double* %87, align 8 + %89 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 39 + %90 = load double, double* %89, align 8 + %91 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 40 + %92 = load double, double* %91, align 8 + %93 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 41 + %94 = load double, double* %93, align 8 + %95 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 42 + %96 = load double, double* %95, align 8 + %97 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 43 + %98 = load double, double* %97, align 8 + %99 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 44 + %100 = load double, double* %99, align 8 + %101 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 45 + %102 = load double, double* %101, align 8 + %103 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 46 + %104 = load double, double* %103, align 8 + %105 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 47 + %106 = load double, double* %105, align 8 + %107 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 48 + %108 = load double, double* %107, align 8 + %109 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 49 + %110 = load double, double* %109, align 8 + %111 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 50 + %112 = load double, double* %111, align 8 + %113 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 51 + %114 = load double, double* %113, align 8 + %115 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 52 + %116 = load double, double* %115, align 8 + %117 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 53 + %118 = load double, double* %117, align 8 + %119 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 54 + %120 = load double, double* %119, align 8 + %121 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 55 + %122 = load double, double* %121, align 8 + %123 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 56 + %124 = load double, double* %123, align 8 + %125 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 57 + %126 = load double, double* %125, align 8 + %127 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 58 + %128 = load double, double* %127, align 8 + %129 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 59 + %130 = load double, double* %129, align 8 + %131 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 60 + %132 = load double, double* %131, align 8 + %133 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 61 + %134 = load double, double* %133, align 8 + %135 = getelementptr inbounds %struct.bw, %struct.bw* %8, i32 2, i32 1, i32 0, i32 0, i32 0, i32 62 + %136 = load double, double* %135, align 8 + %137 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 0 + store double %10, double* %137, align 8 + %138 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 0 + store double %12, double* %138, align 8 + %139 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 1 + store double %14, double* %139, align 8 + %140 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 2 + store double %16, double* %140, align 8 + %141 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 3 + store double %18, double* %141, align 8 + %142 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 4 + store double %20, double* %142, align 8 + %143 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 5 + store double %22, double* %143, align 8 + %144 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 6 + store double %24, double* %144, align 8 + %145 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 7 + store double %26, double* %145, align 8 + %146 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 8 + store double %28, double* %146, align 8 + %147 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 9 + store double %30, double* %147, align 8 + %148 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 10 + store double %32, double* %148, align 8 + %149 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 11 + store double %34, double* %149, align 8 + %150 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 12 + store double %36, double* %150, align 8 + %151 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 13 + store double %38, double* %151, align 8 + %152 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 14 + store double %40, double* %152, align 8 + %153 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 15 + store double %42, double* %153, align 8 + %154 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 16 + store double %44, double* %154, align 8 + %155 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 17 + store double %46, double* %155, align 8 + %156 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 18 + store double %48, double* %156, align 8 + %157 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 19 + store double %50, double* %157, align 8 + %158 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 20 + store double %52, double* %158, align 8 + %159 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 21 + store double %54, double* %159, align 8 + %160 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 22 + store double %56, double* %160, align 8 + %161 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 23 + store double %58, double* %161, align 8 + %162 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 24 + store double %60, double* %162, align 8 + %163 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 25 + store double %62, double* %163, align 8 + %164 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 26 + store double %64, double* %164, align 8 + %165 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 27 + store double %66, double* %165, align 8 + %166 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 28 + store double %68, double* %166, align 8 + %167 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 29 + store double %70, double* %167, align 8 + %168 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 30 + store double %72, double* %168, align 8 + %169 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 31 + store double %74, double* %169, align 8 + %170 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 32 + store double %76, double* %170, align 8 + %171 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 33 + store double %78, double* %171, align 8 + %172 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 34 + store double %80, double* %172, align 8 + %173 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 35 + store double %82, double* %173, align 8 + %174 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 36 + store double %84, double* %174, align 8 + %175 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 37 + store double %86, double* %175, align 8 + %176 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 38 + store double %88, double* %176, align 8 + %177 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 39 + store double %90, double* %177, align 8 + %178 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 40 + store double %92, double* %178, align 8 + %179 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 41 + store double %94, double* %179, align 8 + %180 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 42 + store double %96, double* %180, align 8 + %181 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 43 + store double %98, double* %181, align 8 + %182 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 44 + store double %100, double* %182, align 8 + %183 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 45 + store double %102, double* %183, align 8 + %184 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 46 + store double %104, double* %184, align 8 + %185 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 47 + store double %106, double* %185, align 8 + %186 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 48 + store double %108, double* %186, align 8 + %187 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 49 + store double %110, double* %187, align 8 + %188 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 50 + store double %112, double* %188, align 8 + %189 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 51 + store double %114, double* %189, align 8 + %190 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 52 + store double %116, double* %190, align 8 + %191 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 53 + store double %118, double* %191, align 8 + %192 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 54 + store double %120, double* %192, align 8 + %193 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 55 + store double %122, double* %193, align 8 + %194 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 56 + store double %124, double* %194, align 8 + %195 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 57 + store double %126, double* %195, align 8 + %196 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 58 + store double %128, double* %196, align 8 + %197 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 59 + store double %130, double* %197, align 8 + %198 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 60 + store double %132, double* %198, align 8 + %199 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 61 + store double %134, double* %199, align 8 + %200 = getelementptr inbounds %struct.ak, %struct.ak* %0, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 1, i32 0, i32 0, i32 0, i32 62 + store double %136, double* %200, align 8 + call void @llvm.lifetime.end.p0i8(i64 520, i8* nonnull %5) + ret void +} + +declare %struct.ak* @_ZN2akI2bwEC1Ev(%struct.ak* returned) + +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) + +declare %struct.bw* @_ZN2bwC1Ed(%struct.bw* returned, double) + +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) + +!1 = !{!2, !4} +!2 = distinct !{!2, !3, !"_ZNK1M2asEi: argument 0"} +!3 = distinct !{!3, !"_ZNK1M2asEi"} +!4 = distinct !{!4, !5, !"_ZNK1lI1ME3fooEi: argument 0"} +!5 = distinct !{!5, !"_ZNK1lI1ME3fooEi"} Index: test/CodeGen/ARM/load_store_opt_reg_limit.mir =================================================================== --- /dev/null +++ test/CodeGen/ARM/load_store_opt_reg_limit.mir @@ -0,0 +1,51 @@ +# RUN: llc -mtriple=thumbv7--linux-andorid -verify-machineinstrs -run-pass=arm-ldst-opt %s -o - | FileCheck %s +--- | + target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv7--linux-android" + + define void @_Z2brR1lI1ME() { + ret void + } + +... +--- +#CHECK: _Z2brR1lI1ME +name: _Z2brR1lI1ME +# CHECK: VSTMDIA $r4, 14, $noreg, $d15, $d16, $d17, $d18, $d19, $d20, $d21, $d22, $d23, $d24, $d25, $d26, $d27, $d28, $d29, $d30 +# CHECK-NEXT: VSTRD $d31, $r4, 32, 14, $noreg :: (store 8) +# CHECK: VSTMDIA killed $r0, 14, $noreg, $d4, $d5, $d6, $d7, $d8, $d9, $d10, $d11, $d12, $d13, $d14 +body: | + bb.0: + VSTRD $d15, $r4, 0, 14, $noreg :: (store 8) + VSTRD $d16, $r4, 2, 14, $noreg :: (store 8) + VSTRD $d17, $r4, 4, 14, $noreg :: (store 8) + VSTRD $d18, $r4, 6, 14, $noreg :: (store 8) + VSTRD $d19, $r4, 8, 14, $noreg :: (store 8) + VSTRD $d20, $r4, 10, 14, $noreg :: (store 8) + VSTRD $d21, $r4, 12, 14, $noreg :: (store 8) + VSTRD $d22, $r4, 14, 14, $noreg :: (store 8) + VSTRD $d23, $r4, 16, 14, $noreg :: (store 8) + VSTRD $d24, $r4, 18, 14, $noreg :: (store 8) + VSTRD $d25, $r4, 20, 14, $noreg :: (store 8) + VSTRD $d26, $r4, 22, 14, $noreg :: (store 8) + VSTRD $d27, $r4, 24, 14, $noreg :: (store 8) + VSTRD $d28, $r4, 26, 14, $noreg :: (store 8) + VSTRD $d29, $r4, 28, 14, $noreg :: (store 8) + VSTRD $d30, $r4, 30, 14, $noreg :: (store 8) + VSTRD $d31, $r4, 32, 14, $noreg :: (store 8) + VSTRD $d0, $r4, 34, 14, $noreg :: (store 8) + VSTRD $d1, $r4, 36, 14, $noreg :: (store 8) + VSTRD $d3, $r4, 38, 14, $noreg :: (store 8) + VSTRD $d2, $r4, 40, 14, $noreg :: (store 8) + VSTRD $d4, $r4, 42, 14, $noreg :: (store 8) + VSTRD $d5, $r4, 44, 14, $noreg :: (store 8) + VSTRD $d6, $r4, 46, 14, $noreg :: (store 8) + VSTRD $d7, $r4, 48, 14, $noreg :: (store 8) + VSTRD $d8, $r4, 50, 14, $noreg :: (store 8) + VSTRD $d9, $r4, 52, 14, $noreg :: (store 8) + VSTRD $d10, $r4, 54, 14, $noreg :: (store 8) + VSTRD $d11, $r4, 56, 14, $noreg :: (store 8) + VSTRD $d12, $r4, 58, 14, $noreg :: (store 8) + VSTRD $d13, $r4, 60, 14, $noreg :: (store 8) + VSTRD $d14, $r4, 62, 14, $noreg :: (store 8) +...