1; RUN: opt < %s -reassociate -gvn -instcombine -S | FileCheck %s
2; RUN: opt < %s -passes='reassociate,gvn,instcombine' -S | FileCheck %s
3
4define i32 @test1(i32 %arg) {
5  %tmp1 = sub i32 -12, %arg
6  %tmp2 = add i32 %tmp1, 12
7  ret i32 %tmp2
8
9; CHECK-LABEL: @test1
10; CHECK-NEXT: sub i32 0, %arg
11; CHECK-NEXT: ret i32
12}
13
14define i32 @test2(i32 %reg109, i32 %reg1111) {
15  %reg115 = add i32 %reg109, -30
16  %reg116 = add i32 %reg115, %reg1111
17  %reg117 = add i32 %reg116, 30
18  ret i32 %reg117
19
20; CHECK-LABEL: @test2
21; CHECK-NEXT: %reg117 = add i32 %reg1111, %reg109
22; CHECK-NEXT: ret i32 %reg117
23}
24
25@e = external global i32
26@a = external global i32
27@b = external global i32
28@c = external global i32
29@f = external global i32
30
31define void @test3() {
32  %A = load i32, i32* @a
33  %B = load i32, i32* @b
34  %C = load i32, i32* @c
35  %t1 = add i32 %A, %B
36  %t2 = add i32 %t1, %C
37  %t3 = add i32 %C, %A
38  %t4 = add i32 %t3, %B
39  ; e = (a+b)+c;
40  store i32 %t2, i32* @e
41  ; f = (a+c)+b
42  store i32 %t4, i32* @f
43  ret void
44
45; CHECK-LABEL: @test3
46; CHECK: add i32
47; CHECK: add i32
48; CHECK-NOT: add i32
49; CHECK: ret void
50}
51
52define void @test4() {
53  %A = load i32, i32* @a
54  %B = load i32, i32* @b
55  %C = load i32, i32* @c
56  %t1 = add i32 %A, %B
57  %t2 = add i32 %t1, %C
58  %t3 = add i32 %C, %A
59  %t4 = add i32 %t3, %B
60  ; e = c+(a+b)
61  store i32 %t2, i32* @e
62  ; f = (c+a)+b
63  store i32 %t4, i32* @f
64  ret void
65
66; CHECK-LABEL: @test4
67; CHECK: add i32
68; CHECK: add i32
69; CHECK-NOT: add i32
70; CHECK: ret void
71}
72
73define void @test5() {
74  %A = load i32, i32* @a
75  %B = load i32, i32* @b
76  %C = load i32, i32* @c
77  %t1 = add i32 %B, %A
78  %t2 = add i32 %t1, %C
79  %t3 = add i32 %C, %A
80  %t4 = add i32 %t3, %B
81  ; e = c+(b+a)
82  store i32 %t2, i32* @e
83  ; f = (c+a)+b
84  store i32 %t4, i32* @f
85  ret void
86
87; CHECK-LABEL: @test5
88; CHECK: add i32
89; CHECK: add i32
90; CHECK-NOT: add i32
91; CHECK: ret void
92}
93
94define i32 @test6() {
95  %tmp.0 = load i32, i32* @a
96  %tmp.1 = load i32, i32* @b
97  ; (a+b)
98  %tmp.2 = add i32 %tmp.0, %tmp.1
99  %tmp.4 = load i32, i32* @c
100  ; (a+b)+c
101  %tmp.5 = add i32 %tmp.2, %tmp.4
102  ; (a+c)
103  %tmp.8 = add i32 %tmp.0, %tmp.4
104  ; (a+c)+b
105  %tmp.11 = add i32 %tmp.8, %tmp.1
106  ; X ^ X = 0
107  %RV = xor i32 %tmp.5, %tmp.11
108  ret i32 %RV
109
110; CHECK-LABEL: @test6
111; CHECK: ret i32 0
112}
113
114; This should be one add and two multiplies.
115define i32 @test7(i32 %A, i32 %B, i32 %C) {
116  ; A*A*B + A*C*A
117  %aa = mul i32 %A, %A
118  %aab = mul i32 %aa, %B
119  %ac = mul i32 %A, %C
120  %aac = mul i32 %ac, %A
121  %r = add i32 %aab, %aac
122  ret i32 %r
123
124; CHECK-LABEL: @test7
125; CHECK-NEXT: add i32 %C, %B
126; CHECK-NEXT: mul i32
127; CHECK-NEXT: mul i32
128; CHECK-NEXT: ret i32
129}
130
131define i32 @test8(i32 %X, i32 %Y, i32 %Z) {
132  %A = sub i32 0, %X
133  %B = mul i32 %A, %Y
134  ; (-X)*Y + Z -> Z-X*Y
135  %C = add i32 %B, %Z
136  ret i32 %C
137
138; CHECK-LABEL: @test8
139; CHECK-NEXT: %A = mul i32 %Y, %X
140; CHECK-NEXT: %C = sub i32 %Z, %A
141; CHECK-NEXT: ret i32 %C
142}
143
144; PR5458
145define i32 @test9(i32 %X) {
146  %Y = mul i32 %X, 47
147  %Z = add i32 %Y, %Y
148  ret i32 %Z
149; CHECK-LABEL: @test9
150; CHECK-NEXT: mul i32 %X, 94
151; CHECK-NEXT: ret i32
152}
153
154define i32 @test10(i32 %X) {
155  %Y = add i32 %X ,%X
156  %Z = add i32 %Y, %X
157  ret i32 %Z
158; CHECK-LABEL: @test10
159; CHECK-NEXT: mul i32 %X, 3
160; CHECK-NEXT: ret i32
161}
162
163define i32 @test11(i32 %W) {
164  %X = mul i32 %W, 127
165  %Y = add i32 %X ,%X
166  %Z = add i32 %Y, %X
167  ret i32 %Z
168; CHECK-LABEL: @test11
169; CHECK-NEXT: mul i32 %W, 381
170; CHECK-NEXT: ret i32
171}
172
173declare void @mumble(i32)
174
175define i32 @test12(i32 %X) {
176  %X.neg = sub nsw nuw i32 0, %X
177  call void @mumble(i32 %X.neg)
178  %A = sub i32 1, %X
179  %B = sub i32 2, %X
180  %C = sub i32 3, %X
181  %Y = add i32 %A ,%B
182  %Z = add i32 %Y, %C
183  ret i32 %Z
184; CHECK-LABEL: @test12
185; CHECK: %[[mul:.*]] = mul i32 %X, -3
186; CHECK-NEXT: add i32 %[[mul]], 6
187; CHECK-NEXT: ret i32
188}
189
190define i32 @test13(i32 %X1, i32 %X2, i32 %X3) {
191  %A = sub i32 0, %X1
192  %B = mul i32 %A, %X2   ; -X1*X2
193  %C = mul i32 %X1, %X3  ; X1*X3
194  %D = add i32 %B, %C    ; -X1*X2 + X1*X3 -> X1*(X3-X2)
195  ret i32 %D
196; CHECK-LABEL: @test13
197; CHECK-NEXT: sub i32 %X3, %X2
198; CHECK-NEXT: mul i32 {{.*}}, %X1
199; CHECK-NEXT: ret i32
200}
201
202; PR5359
203define i32 @test14(i32 %X1, i32 %X2) {
204  %B = mul i32 %X1, 47   ; X1*47
205  %C = mul i32 %X2, -47  ; X2*-47
206  %D = add i32 %B, %C    ; X1*47 + X2*-47 -> 47*(X1-X2)
207  ret i32 %D
208
209; CHECK-LABEL: @test14
210; CHECK-NEXT: %[[SUB:.*]] = sub i32 %X1, %X2
211; CHECK-NEXT: mul i32 %[[SUB]], 47
212; CHECK-NEXT: ret i32
213}
214
215; Do not reassociate expressions of type i1
216define i32 @test15(i32 %X1, i32 %X2, i32 %X3) {
217  %A = icmp ne i32 %X1, 0
218  %B = icmp slt i32 %X2, %X3
219  %C = and i1 %A, %B
220  %D = select i1 %C, i32 %X1, i32 0
221  ret i32 %D
222; CHECK-LABEL: @test15
223; CHECK: and i1 %A, %B
224}
225