Merging r261039:
[oota-llvm.git] / test / CodeGen / X86 / lea-opt.ll
1 ; RUN: llc < %s -mtriple=x86_64-linux -enable-x86-lea-opt | FileCheck %s
2
3 %struct.anon1 = type { i32, i32, i32 }
4 %struct.anon2 = type { i32, [32 x i32], i32 }
5
6 @arr1 = external global [65 x %struct.anon1], align 16
7 @arr2 = external global [65 x %struct.anon2], align 16
8
9 define void @test1(i64 %x) nounwind {
10 entry:
11   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
12   %tmp = load i32, i32* %a, align 4
13   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
14   %tmp1 = load i32, i32* %b, align 4
15   %sub = sub i32 %tmp, %tmp1
16   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
17   %tmp2 = load i32, i32* %c, align 4
18   %add = add nsw i32 %sub, %tmp2
19   switch i32 %add, label %sw.epilog [
20     i32 1, label %sw.bb.1
21     i32 2, label %sw.bb.2
22   ]
23
24 sw.bb.1:                                          ; preds = %entry
25   store i32 111, i32* %b, align 4
26   store i32 222, i32* %c, align 4
27   br label %sw.epilog
28
29 sw.bb.2:                                          ; preds = %entry
30   store i32 333, i32* %b, align 4
31   store i32 444, i32* %c, align 4
32   br label %sw.epilog
33
34 sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
35   ret void
36 ; CHECK-LABEL: test1:
37 ; CHECK:        leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]]
38 ; CHECK:        movl arr1(,[[REG1]],4), {{.*}}
39 ; CHECK:        leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]]
40 ; CHECK:        subl arr1+4(,[[REG1]],4), {{.*}}
41 ; CHECK:        leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]]
42 ; CHECK:        addl arr1+8(,[[REG1]],4), {{.*}}
43 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
44 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
45 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
46 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
47 }
48
49 define void @test2(i64 %x) nounwind optsize {
50 entry:
51   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
52   %tmp = load i32, i32* %a, align 4
53   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
54   %tmp1 = load i32, i32* %b, align 4
55   %sub = sub i32 %tmp, %tmp1
56   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
57   %tmp2 = load i32, i32* %c, align 4
58   %add = add nsw i32 %sub, %tmp2
59   switch i32 %add, label %sw.epilog [
60     i32 1, label %sw.bb.1
61     i32 2, label %sw.bb.2
62   ]
63
64 sw.bb.1:                                          ; preds = %entry
65   store i32 111, i32* %b, align 4
66   store i32 222, i32* %c, align 4
67   br label %sw.epilog
68
69 sw.bb.2:                                          ; preds = %entry
70   store i32 333, i32* %b, align 4
71   store i32 444, i32* %c, align 4
72   br label %sw.epilog
73
74 sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
75   ret void
76 ; CHECK-LABEL: test2:
77 ; CHECK:        leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]]
78 ; CHECK:        leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]]
79 ; CHECK:        movl -4([[REG2]]), {{.*}}
80 ; CHECK:        subl ([[REG2]]), {{.*}}
81 ; CHECK:        leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]]
82 ; CHECK:        addl ([[REG3]]), {{.*}}
83 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
84 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
85 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
86 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
87 }
88
89 ; Check that LEA optimization pass takes into account a resultant address
90 ; displacement when choosing a LEA instruction for replacing a redundant
91 ; address recalculation.
92
93 define void @test3(i64 %x) nounwind optsize {
94 entry:
95   %a = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 2
96   %tmp = load i32, i32* %a, align 4
97   %b = getelementptr inbounds [65 x %struct.anon2], [65 x %struct.anon2]* @arr2, i64 0, i64 %x, i32 0
98   %tmp1 = load i32, i32* %b, align 4
99   %add = add nsw i32 %tmp, %tmp1
100   switch i32 %add, label %sw.epilog [
101     i32 1, label %sw.bb.1
102     i32 2, label %sw.bb.2
103   ]
104
105 sw.bb.1:                                          ; preds = %entry
106   store i32 111, i32* %a, align 4
107   store i32 222, i32* %b, align 4
108   br label %sw.epilog
109
110 sw.bb.2:                                          ; preds = %entry
111   store i32 333, i32* %a, align 4
112   store i32 444, i32* %b, align 4
113   br label %sw.epilog
114
115 sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
116   ret void
117 ; CHECK-LABEL: test3:
118 ; CHECK:        imulq {{.*}}, [[REG1:%[a-z]+]]
119 ; CHECK:        leaq arr2+132([[REG1]]), [[REG2:%[a-z]+]]
120 ; CHECK:        leaq arr2([[REG1]]), [[REG3:%[a-z]+]]
121
122 ; REG3's definition is closer to movl than REG2's, but the pass still chooses
123 ; REG2 because it provides the resultant address displacement fitting 1 byte.
124
125 ; CHECK:        movl ([[REG2]]), {{.*}}
126 ; CHECK:        addl ([[REG3]]), {{.*}}
127 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
128 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
129 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
130 ; CHECK:        movl ${{[1-4]+}}, ([[REG3]])
131 }
132
133 define void @test4(i64 %x) nounwind minsize {
134 entry:
135   %a = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 0
136   %tmp = load i32, i32* %a, align 4
137   %b = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 1
138   %tmp1 = load i32, i32* %b, align 4
139   %sub = sub i32 %tmp, %tmp1
140   %c = getelementptr inbounds [65 x %struct.anon1], [65 x %struct.anon1]* @arr1, i64 0, i64 %x, i32 2
141   %tmp2 = load i32, i32* %c, align 4
142   %add = add nsw i32 %sub, %tmp2
143   switch i32 %add, label %sw.epilog [
144     i32 1, label %sw.bb.1
145     i32 2, label %sw.bb.2
146   ]
147
148 sw.bb.1:                                          ; preds = %entry
149   store i32 111, i32* %b, align 4
150   store i32 222, i32* %c, align 4
151   br label %sw.epilog
152
153 sw.bb.2:                                          ; preds = %entry
154   store i32 333, i32* %b, align 4
155   store i32 444, i32* %c, align 4
156   br label %sw.epilog
157
158 sw.epilog:                                        ; preds = %sw.bb.2, %sw.bb.1, %entry
159   ret void
160 ; CHECK-LABEL: test4:
161 ; CHECK:        leaq arr1+4({{.*}}), [[REG2:%[a-z]+]]
162 ; CHECK:        movl -4([[REG2]]), {{.*}}
163 ; CHECK:        subl ([[REG2]]), {{.*}}
164 ; CHECK:        addl 4([[REG2]]), {{.*}}
165 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
166 ; CHECK:        movl ${{[1-4]+}}, 4([[REG2]])
167 ; CHECK:        movl ${{[1-4]+}}, ([[REG2]])
168 ; CHECK:        movl ${{[1-4]+}}, 4([[REG2]])
169 }