1; RUN: llc < %s -mtriple=armv7-apple-darwin | FileCheck %s
2
3; Make sure that we merge the consecutive load/store sequence below and use a
4; word (16 bit) instead of a byte copy.
5; CHECK: MergeLoadStoreBaseIndexOffset
6; CHECK: ldrh    [[REG:r[0-9]+]], [{{.*}}]
7; CHECK: strh    [[REG]], [r1], #2
8define void @MergeLoadStoreBaseIndexOffset(i32* %a, i8* %b, i8* %c, i32 %n) {
9  br label %1
10
11; <label>:1
12  %.09 = phi i32 [ %n, %0 ], [ %11, %1 ]
13  %.08 = phi i8* [ %b, %0 ], [ %10, %1 ]
14  %.0 = phi i32* [ %a, %0 ], [ %2, %1 ]
15  %2 = getelementptr inbounds i32* %.0, i32 1
16  %3 = load i32* %.0, align 1
17  %4 = getelementptr inbounds i8* %c, i32 %3
18  %5 = load i8* %4, align 1
19  %6 = add i32 %3, 1
20  %7 = getelementptr inbounds i8* %c, i32 %6
21  %8 = load i8* %7, align 1
22  store i8 %5, i8* %.08, align 1
23  %9 = getelementptr inbounds i8* %.08, i32 1
24  store i8 %8, i8* %9, align 1
25  %10 = getelementptr inbounds i8* %.08, i32 2
26  %11 = add nsw i32 %.09, -1
27  %12 = icmp eq i32 %11, 0
28  br i1 %12, label %13, label %1
29
30; <label>:13
31  ret void
32}
33
34; Make sure that we merge the consecutive load/store sequence below and use a
35; word (16 bit) instead of a byte copy even if there are intermediate sign
36; extensions.
37; CHECK: MergeLoadStoreBaseIndexOffsetSext
38; CHECK: ldrh    [[REG:r[0-9]+]], [{{.*}}]
39; CHECK: strh    [[REG]], [r1], #2
40define void @MergeLoadStoreBaseIndexOffsetSext(i8* %a, i8* %b, i8* %c, i32 %n) {
41  br label %1
42
43; <label>:1
44  %.09 = phi i32 [ %n, %0 ], [ %12, %1 ]
45  %.08 = phi i8* [ %b, %0 ], [ %11, %1 ]
46  %.0 = phi i8* [ %a, %0 ], [ %2, %1 ]
47  %2 = getelementptr inbounds i8* %.0, i32 1
48  %3 = load i8* %.0, align 1
49  %4 = sext i8 %3 to i32
50  %5 = getelementptr inbounds i8* %c, i32 %4
51  %6 = load i8* %5, align 1
52  %7 = add i32 %4, 1
53  %8 = getelementptr inbounds i8* %c, i32 %7
54  %9 = load i8* %8, align 1
55  store i8 %6, i8* %.08, align 1
56  %10 = getelementptr inbounds i8* %.08, i32 1
57  store i8 %9, i8* %10, align 1
58  %11 = getelementptr inbounds i8* %.08, i32 2
59  %12 = add nsw i32 %.09, -1
60  %13 = icmp eq i32 %12, 0
61  br i1 %13, label %14, label %1
62
63; <label>:14
64  ret void
65}
66
67; However, we can only merge ignore sign extensions when they are on all memory
68; computations;
69; CHECK: loadStoreBaseIndexOffsetSextNoSex
70; CHECK-NOT: ldrh    [[REG:r[0-9]+]], [{{.*}}]
71; CHECK-NOT: strh    [[REG]], [r1], #2
72define void @loadStoreBaseIndexOffsetSextNoSex(i8* %a, i8* %b, i8* %c, i32 %n) {
73  br label %1
74
75; <label>:1
76  %.09 = phi i32 [ %n, %0 ], [ %12, %1 ]
77  %.08 = phi i8* [ %b, %0 ], [ %11, %1 ]
78  %.0 = phi i8* [ %a, %0 ], [ %2, %1 ]
79  %2 = getelementptr inbounds i8* %.0, i32 1
80  %3 = load i8* %.0, align 1
81  %4 = sext i8 %3 to i32
82  %5 = getelementptr inbounds i8* %c, i32 %4
83  %6 = load i8* %5, align 1
84  %7 = add i8 %3, 1
85  %wrap.4 = sext i8 %7 to i32
86  %8 = getelementptr inbounds i8* %c, i32 %wrap.4
87  %9 = load i8* %8, align 1
88  store i8 %6, i8* %.08, align 1
89  %10 = getelementptr inbounds i8* %.08, i32 1
90  store i8 %9, i8* %10, align 1
91  %11 = getelementptr inbounds i8* %.08, i32 2
92  %12 = add nsw i32 %.09, -1
93  %13 = icmp eq i32 %12, 0
94  br i1 %13, label %14, label %1
95
96; <label>:14
97  ret void
98}
99