[AArch64] Fix bug in prolog clobbering live reg when shrink wrapping.
[oota-llvm.git] / test / CodeGen / AArch64 / arm64-addr-mode-folding.ll
1 ; RUN: llc -O3 -mtriple arm64-apple-ios3 -aarch64-gep-opt=false %s -o - | FileCheck %s
2 ; <rdar://problem/13621857>
3
4 @block = common global i8* null, align 8
5
6 define i32 @fct(i32 %i1, i32 %i2) {
7 ; CHECK: @fct
8 ; Sign extension is used more than once, thus it should not be folded.
9 ; CodeGenPrepare is not sharing sext across uses, thus this is folded because
10 ; of that.
11 ; _CHECK-NOT_: , sxtw]
12 entry:
13   %idxprom = sext i32 %i1 to i64
14   %0 = load i8*, i8** @block, align 8
15   %arrayidx = getelementptr inbounds i8, i8* %0, i64 %idxprom
16   %1 = load i8, i8* %arrayidx, align 1
17   %idxprom1 = sext i32 %i2 to i64
18   %arrayidx2 = getelementptr inbounds i8, i8* %0, i64 %idxprom1
19   %2 = load i8, i8* %arrayidx2, align 1
20   %cmp = icmp eq i8 %1, %2
21   br i1 %cmp, label %if.end, label %if.then
22
23 if.then:                                          ; preds = %entry
24   %cmp7 = icmp ugt i8 %1, %2
25   %conv8 = zext i1 %cmp7 to i32
26   br label %return
27
28 if.end:                                           ; preds = %entry
29   %inc = add nsw i32 %i1, 1
30   %inc9 = add nsw i32 %i2, 1
31   %idxprom10 = sext i32 %inc to i64
32   %arrayidx11 = getelementptr inbounds i8, i8* %0, i64 %idxprom10
33   %3 = load i8, i8* %arrayidx11, align 1
34   %idxprom12 = sext i32 %inc9 to i64
35   %arrayidx13 = getelementptr inbounds i8, i8* %0, i64 %idxprom12
36   %4 = load i8, i8* %arrayidx13, align 1
37   %cmp16 = icmp eq i8 %3, %4
38   br i1 %cmp16, label %if.end23, label %if.then18
39
40 if.then18:                                        ; preds = %if.end
41   %cmp21 = icmp ugt i8 %3, %4
42   %conv22 = zext i1 %cmp21 to i32
43   br label %return
44
45 if.end23:                                         ; preds = %if.end
46   %inc24 = add nsw i32 %i1, 2
47   %inc25 = add nsw i32 %i2, 2
48   %idxprom26 = sext i32 %inc24 to i64
49   %arrayidx27 = getelementptr inbounds i8, i8* %0, i64 %idxprom26
50   %5 = load i8, i8* %arrayidx27, align 1
51   %idxprom28 = sext i32 %inc25 to i64
52   %arrayidx29 = getelementptr inbounds i8, i8* %0, i64 %idxprom28
53   %6 = load i8, i8* %arrayidx29, align 1
54   %cmp32 = icmp eq i8 %5, %6
55   br i1 %cmp32, label %return, label %if.then34
56
57 if.then34:                                        ; preds = %if.end23
58   %cmp37 = icmp ugt i8 %5, %6
59   %conv38 = zext i1 %cmp37 to i32
60   br label %return
61
62 return:                                           ; preds = %if.end23, %if.then34, %if.then18, %if.then
63   %retval.0 = phi i32 [ %conv8, %if.then ], [ %conv22, %if.then18 ], [ %conv38, %if.then34 ], [ 1, %if.end23 ]
64   ret i32 %retval.0
65 }
66
67 define i32 @fct1(i32 %i1, i32 %i2) optsize {
68 ; CHECK: @fct1
69 ; Addressing are folded when optimizing for code size.
70 ; CHECK: , sxtw]
71 ; CHECK: , sxtw]
72 entry:
73   %idxprom = sext i32 %i1 to i64
74   %0 = load i8*, i8** @block, align 8
75   %arrayidx = getelementptr inbounds i8, i8* %0, i64 %idxprom
76   %1 = load i8, i8* %arrayidx, align 1
77   %idxprom1 = sext i32 %i2 to i64
78   %arrayidx2 = getelementptr inbounds i8, i8* %0, i64 %idxprom1
79   %2 = load i8, i8* %arrayidx2, align 1
80   %cmp = icmp eq i8 %1, %2
81   br i1 %cmp, label %if.end, label %if.then
82
83 if.then:                                          ; preds = %entry
84   %cmp7 = icmp ugt i8 %1, %2
85   %conv8 = zext i1 %cmp7 to i32
86   br label %return
87
88 if.end:                                           ; preds = %entry
89   %inc = add nsw i32 %i1, 1
90   %inc9 = add nsw i32 %i2, 1
91   %idxprom10 = sext i32 %inc to i64
92   %arrayidx11 = getelementptr inbounds i8, i8* %0, i64 %idxprom10
93   %3 = load i8, i8* %arrayidx11, align 1
94   %idxprom12 = sext i32 %inc9 to i64
95   %arrayidx13 = getelementptr inbounds i8, i8* %0, i64 %idxprom12
96   %4 = load i8, i8* %arrayidx13, align 1
97   %cmp16 = icmp eq i8 %3, %4
98   br i1 %cmp16, label %if.end23, label %if.then18
99
100 if.then18:                                        ; preds = %if.end
101   %cmp21 = icmp ugt i8 %3, %4
102   %conv22 = zext i1 %cmp21 to i32
103   br label %return
104
105 if.end23:                                         ; preds = %if.end
106   %inc24 = add nsw i32 %i1, 2
107   %inc25 = add nsw i32 %i2, 2
108   %idxprom26 = sext i32 %inc24 to i64
109   %arrayidx27 = getelementptr inbounds i8, i8* %0, i64 %idxprom26
110   %5 = load i8, i8* %arrayidx27, align 1
111   %idxprom28 = sext i32 %inc25 to i64
112   %arrayidx29 = getelementptr inbounds i8, i8* %0, i64 %idxprom28
113   %6 = load i8, i8* %arrayidx29, align 1
114   %cmp32 = icmp eq i8 %5, %6
115   br i1 %cmp32, label %return, label %if.then34
116
117 if.then34:                                        ; preds = %if.end23
118   %cmp37 = icmp ugt i8 %5, %6
119   %conv38 = zext i1 %cmp37 to i32
120   br label %return
121
122 return:                                           ; preds = %if.end23, %if.then34, %if.then18, %if.then
123   %retval.0 = phi i32 [ %conv8, %if.then ], [ %conv22, %if.then18 ], [ %conv38, %if.then34 ], [ 1, %if.end23 ]
124   ret i32 %retval.0
125 }
126
127 ; CHECK: @test
128 ; CHECK-NOT: , uxtw #2]
129 define i32 @test(i32* %array, i8 zeroext %c, i32 %arg) {
130 entry:
131   %conv = zext i8 %c to i32
132   %add = sub i32 0, %arg
133   %tobool = icmp eq i32 %conv, %add
134   br i1 %tobool, label %if.end, label %if.then
135
136 if.then:                                          ; preds = %entry
137   %idxprom = zext i8 %c to i64
138   %arrayidx = getelementptr inbounds i32, i32* %array, i64 %idxprom
139   %0 = load volatile i32, i32* %arrayidx, align 4
140   %1 = load volatile i32, i32* %arrayidx, align 4
141   %add3 = add nsw i32 %1, %0
142   br label %if.end
143
144 if.end:                                           ; preds = %entry, %if.then
145   %res.0 = phi i32 [ %add3, %if.then ], [ 0, %entry ]
146   ret i32 %res.0
147 }
148
149
150 ; CHECK: @test2
151 ; CHECK: , uxtw #2]
152 ; CHECK: , uxtw #2]
153 define i32 @test2(i32* %array, i8 zeroext %c, i32 %arg) optsize {
154 entry:
155   %conv = zext i8 %c to i32
156   %add = sub i32 0, %arg
157   %tobool = icmp eq i32 %conv, %add
158   br i1 %tobool, label %if.end, label %if.then
159
160 if.then:                                          ; preds = %entry
161   %idxprom = zext i8 %c to i64
162   %arrayidx = getelementptr inbounds i32, i32* %array, i64 %idxprom
163   %0 = load volatile i32, i32* %arrayidx, align 4
164   %1 = load volatile i32, i32* %arrayidx, align 4
165   %add3 = add nsw i32 %1, %0
166   br label %if.end
167
168 if.end:                                           ; preds = %entry, %if.then
169   %res.0 = phi i32 [ %add3, %if.then ], [ 0, %entry ]
170   ret i32 %res.0
171 }