1; RUN: llc -mtriple=thumbv6m-eabi -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-T1 2; RUN: llc -mtriple=thumbv5e-linux-gnueabi -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-T1 3; RUN: llc -mtriple=thumbv7m -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-T2 4; RUN: llc -mtriple=thumbv7a -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-T2 5 6%struct1 = type { %struct1*, %struct1*, i32 } 7%struct2 = type { i32, i32, i32* } 8 9@x1 = external global %struct1, align 4 10@x2 = external global %struct1, align 4 11 12declare void @fn1(i32, i32) 13declare void @fn2(%struct2*) 14 15; CHECK-LABEL: test1: 16; CHECK-T1: str r0, [r1] 17; CHECK-T1-NEXT: str r1, [r1, #4] 18; CHECK-T2: strd r0, r1, [r1] 19; CHECK-NOT: stm 20define void @test1(i32 %unused, %struct1* %x) { 21 %first = getelementptr inbounds %struct1, %struct1* %x, i32 0, i32 0 22 %second = getelementptr inbounds %struct1, %struct1* %x, i32 0, i32 1 23 store %struct1* @x1, %struct1** %first 24 store %struct1* %x, %struct1** %second 25 ret void 26} 27 28; CHECK-LABEL: test2: 29; CHECK-T1: str r0, [r2] 30; CHECK-T1-NEXT: str r1, [r2, #4] 31; CHECK-T1-NEXT: str r2, [r2, #8] 32; CHECK-T2: stm.w r2, {r0, r1, r2} 33; CHECK-NOT: stm r2!, {r0, r1, r2} 34define i32 @test2(i32 %a, i32 %b, %struct2* %p) { 35entry: 36 %p1 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 0 37 %p2 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 1 38 %p3 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 2 39 store i32 %a, i32* %p1, align 4 40 store i32 %b, i32* %p2, align 4 41 store i32* %p1, i32** %p3, align 4 42 call void @fn1(i32 %a, i32 %b) 43 ret i32 0 44} 45 46; CHECK-LABEL: test3: 47; CHECK-T1: str r0, [r2] 48; CHECK-T1-NEXT: str r1, [r2, #4] 49; CHECK-T1-NEXT: str r2, [r2, #8] 50; CHECK-T2: stm.w r2, {r0, r1, r2} 51; CHECK-NOT: stm r2!, {r0, r1, r2} 52define i32 @test3(i32 %a, i32 %b, %struct2* %p) { 53entry: 54 %p1 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 0 55 %p2 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 1 56 %p3 = getelementptr inbounds %struct2, %struct2* %p, i32 0, i32 2 57 store i32 %a, i32* %p1, align 4 58 store i32 %b, i32* %p2, align 4 59 store i32* %p1, i32** %p3, align 4 60 %p4 = getelementptr inbounds %struct2, %struct2* %p, i32 1 61 call void @fn2(%struct2* %p4) 62 ret i32 0 63} 64 65; FIXME: We should be using stm in both thumb1 and thumb2 66; CHECK-LABEL: test4: 67; CHECK-T1: str r0, [r0] 68; CHECK-T1-NEXT: str r1, [r0, #4] 69; CHECK-T1-NEXT: str r2, [r0, #8] 70; CHECK-T2: stm r0!, {r0, r1, r2} 71define i32 @test4(%struct1* %p, %struct1* %q, i32 %a) { 72entry: 73 %p1 = getelementptr inbounds %struct1, %struct1* %p, i32 0, i32 0 74 %p2 = getelementptr inbounds %struct1, %struct1* %p, i32 0, i32 1 75 %p3 = getelementptr inbounds %struct1, %struct1* %p, i32 0, i32 2 76 store %struct1* %p, %struct1** %p1, align 4 77 store %struct1* %q, %struct1** %p2, align 4 78 store i32 %a, i32* %p3, align 4 79 call void @fn1(i32 %a, i32 %a) 80 ret i32 0 81} 82