1; RUN: opt < %s -instsimplify -S | FileCheck %s
2
3define i32 @add1(i32 %x) {
4; CHECK-LABEL: @add1(
5; (X + -1) + 1 -> X
6  %l = add i32 %x, -1
7  %r = add i32 %l, 1
8  ret i32 %r
9; CHECK: ret i32 %x
10}
11
12define i32 @and1(i32 %x, i32 %y) {
13; CHECK-LABEL: @and1(
14; (X & Y) & X -> X & Y
15  %l = and i32 %x, %y
16  %r = and i32 %l, %x
17  ret i32 %r
18; CHECK: ret i32 %l
19}
20
21define i32 @and2(i32 %x, i32 %y) {
22; CHECK-LABEL: @and2(
23; X & (X & Y) -> X & Y
24  %r = and i32 %x, %y
25  %l = and i32 %x, %r
26  ret i32 %l
27; CHECK: ret i32 %r
28}
29
30define i32 @or1(i32 %x, i32 %y) {
31; CHECK-LABEL: @or1(
32; (X | Y) | X -> X | Y
33  %l = or i32 %x, %y
34  %r = or i32 %l, %x
35  ret i32 %r
36; CHECK: ret i32 %l
37}
38
39define i32 @or2(i32 %x, i32 %y) {
40; CHECK-LABEL: @or2(
41; X | (X | Y) -> X | Y
42  %r = or i32 %x, %y
43  %l = or i32 %x, %r
44  ret i32 %l
45; CHECK: ret i32 %r
46}
47
48define i32 @xor1(i32 %x, i32 %y) {
49; CHECK-LABEL: @xor1(
50; (X ^ Y) ^ X = Y
51  %l = xor i32 %x, %y
52  %r = xor i32 %l, %x
53  ret i32 %r
54; CHECK: ret i32 %y
55}
56
57define i32 @xor2(i32 %x, i32 %y) {
58; CHECK-LABEL: @xor2(
59; X ^ (X ^ Y) = Y
60  %r = xor i32 %x, %y
61  %l = xor i32 %x, %r
62  ret i32 %l
63; CHECK: ret i32 %y
64}
65
66define i32 @sub1(i32 %x, i32 %y) {
67; CHECK-LABEL: @sub1(
68  %d = sub i32 %x, %y
69  %r = sub i32 %x, %d
70  ret i32 %r
71; CHECK: ret i32 %y
72}
73
74define i32 @sub2(i32 %x) {
75; CHECK-LABEL: @sub2(
76; X - (X + 1) -> -1
77  %xp1 = add i32 %x, 1
78  %r = sub i32 %x, %xp1
79  ret i32 %r
80; CHECK: ret i32 -1
81}
82
83define i32 @sub3(i32 %x, i32 %y) {
84; CHECK-LABEL: @sub3(
85; ((X + 1) + Y) - (Y + 1) -> X
86  %xp1 = add i32 %x, 1
87  %lhs = add i32 %xp1, %y
88  %rhs = add i32 %y, 1
89  %r = sub i32 %lhs, %rhs
90  ret i32 %r
91; CHECK: ret i32 %x
92}
93
94define i32 @sdiv1(i32 %x, i32 %y) {
95; CHECK-LABEL: @sdiv1(
96; (no overflow X * Y) / Y -> X
97  %mul = mul nsw i32 %x, %y
98  %r = sdiv i32 %mul, %y
99  ret i32 %r
100; CHECK: ret i32 %x
101}
102
103define i32 @sdiv2(i32 %x, i32 %y) {
104; CHECK-LABEL: @sdiv2(
105; (((X / Y) * Y) / Y) -> X / Y
106  %div = sdiv i32 %x, %y
107  %mul = mul i32 %div, %y
108  %r = sdiv i32 %mul, %y
109  ret i32 %r
110; CHECK: ret i32 %div
111}
112
113define i32 @sdiv3(i32 %x, i32 %y) {
114; CHECK-LABEL: @sdiv3(
115; (X rem Y) / Y -> 0
116  %rem = srem i32 %x, %y
117  %div = sdiv i32 %rem, %y
118  ret i32 %div
119; CHECK: ret i32 0
120}
121
122define i32 @sdiv4(i32 %x, i32 %y) {
123; CHECK-LABEL: @sdiv4(
124; (X / Y) * Y -> X if the division is exact
125  %div = sdiv exact i32 %x, %y
126  %mul = mul i32 %div, %y
127  ret i32 %mul
128; CHECK: ret i32 %x
129}
130
131define i32 @sdiv5(i32 %x, i32 %y) {
132; CHECK-LABEL: @sdiv5(
133; Y * (X / Y) -> X if the division is exact
134  %div = sdiv exact i32 %x, %y
135  %mul = mul i32 %y, %div
136  ret i32 %mul
137; CHECK: ret i32 %x
138}
139
140
141define i32 @udiv1(i32 %x, i32 %y) {
142; CHECK-LABEL: @udiv1(
143; (no overflow X * Y) / Y -> X
144  %mul = mul nuw i32 %x, %y
145  %r = udiv i32 %mul, %y
146  ret i32 %r
147; CHECK: ret i32 %x
148}
149
150define i32 @udiv2(i32 %x, i32 %y) {
151; CHECK-LABEL: @udiv2(
152; (((X / Y) * Y) / Y) -> X / Y
153  %div = udiv i32 %x, %y
154  %mul = mul i32 %div, %y
155  %r = udiv i32 %mul, %y
156  ret i32 %r
157; CHECK: ret i32 %div
158}
159
160define i32 @udiv3(i32 %x, i32 %y) {
161; CHECK-LABEL: @udiv3(
162; (X rem Y) / Y -> 0
163  %rem = urem i32 %x, %y
164  %div = udiv i32 %rem, %y
165  ret i32 %div
166; CHECK: ret i32 0
167}
168
169define i32 @udiv4(i32 %x, i32 %y) {
170; CHECK-LABEL: @udiv4(
171; (X / Y) * Y -> X if the division is exact
172  %div = udiv exact i32 %x, %y
173  %mul = mul i32 %div, %y
174  ret i32 %mul
175; CHECK: ret i32 %x
176}
177
178define i32 @udiv5(i32 %x, i32 %y) {
179; CHECK-LABEL: @udiv5(
180; Y * (X / Y) -> X if the division is exact
181  %div = udiv exact i32 %x, %y
182  %mul = mul i32 %y, %div
183  ret i32 %mul
184; CHECK: ret i32 %x
185}
186
187define i16 @trunc1(i32 %x) {
188; CHECK-LABEL: @trunc1(
189  %y = add i32 %x, 1
190  %tx = trunc i32 %x to i16
191  %ty = trunc i32 %y to i16
192  %d = sub i16 %ty, %tx
193  ret i16 %d
194; CHECK: ret i16 1
195}
196