[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / sub-of-negatible.ll
blob2d9910352683babee78d4f1186f1c00040dff85c
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -instcombine -S | FileCheck %s
4 declare void @use8(i8)
6 ; Constant can be freely negated.
7 define i8 @t0(i8 %x) {
8 ; CHECK-LABEL: @t0(
9 ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
10 ; CHECK-NEXT:    ret i8 [[T0]]
12   %t0 = sub i8 %x, -42
13   ret i8 %t0
16 ; Negation can be negated for free
17 define i8 @t1(i8 %x, i8 %y) {
18 ; CHECK-LABEL: @t1(
19 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
20 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
21 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[Y]]
22 ; CHECK-NEXT:    ret i8 [[T1]]
24   %t0 = sub i8 0, %y
25   call void @use8(i8 %t0)
26   %t1 = sub i8 %x, %t0
27   ret i8 %t1
30 ; Shift-left can be negated if all uses can be updated
31 define i8 @t2(i8 %x, i8 %y) {
32 ; CHECK-LABEL: @t2(
33 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
34 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
35 ; CHECK-NEXT:    ret i8 [[T1]]
37   %t0 = shl i8 -42, %y
38   %t1 = sub i8 %x, %t0
39   ret i8 %t1
41 define i8 @n2(i8 %x, i8 %y) {
42 ; CHECK-LABEL: @n2(
43 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
44 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
45 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
46 ; CHECK-NEXT:    ret i8 [[T1]]
48   %t0 = shl i8 -42, %y
49   call void @use8(i8 %t0)
50   %t1 = sub i8 %x, %t0
51   ret i8 %t1
53 define i8 @t3(i8 %x, i8 %y, i8 %z) {
54 ; CHECK-LABEL: @t3(
55 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
56 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
57 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]]
58 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
59 ; CHECK-NEXT:    ret i8 [[T2]]
61   %t0 = sub i8 0, %z
62   call void @use8(i8 %t0)
63   %t1 = shl i8 %t0, %y
64   %t2 = sub i8 %x, %t1
65   ret i8 %t2
67 define i8 @n3(i8 %x, i8 %y, i8 %z) {
68 ; CHECK-LABEL: @n3(
69 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
70 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
71 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]]
72 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
73 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
74 ; CHECK-NEXT:    ret i8 [[T2]]
76   %t0 = sub i8 0, %z
77   call void @use8(i8 %t0)
78   %t1 = shl i8 %t0, %y
79   call void @use8(i8 %t1)
80   %t2 = sub i8 %x, %t1
81   ret i8 %t2
84 ; Select can be negated if all it's operands can be negated and all the users of select can be updated
85 define i8 @t4(i8 %x, i1 %y) {
86 ; CHECK-LABEL: @t4(
87 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
88 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
89 ; CHECK-NEXT:    ret i8 [[T1]]
91   %t0 = select i1 %y, i8 -42, i8 44
92   %t1 = sub i8 %x, %t0
93   ret i8 %t1
95 define i8 @n4(i8 %x, i1 %y) {
96 ; CHECK-LABEL: @n4(
97 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
98 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
99 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
100 ; CHECK-NEXT:    ret i8 [[T1]]
102   %t0 = select i1 %y, i8 -42, i8 44
103   call void @use8(i8 %t0)
104   %t1 = sub i8 %x, %t0
105   ret i8 %t1
107 define i8 @n5(i8 %x, i1 %y, i8 %z) {
108 ; CHECK-LABEL: @n5(
109 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]]
110 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
111 ; CHECK-NEXT:    ret i8 [[T1]]
113   %t0 = select i1 %y, i8 -42, i8 %z
114   %t1 = sub i8 %x, %t0
115   ret i8 %t1
117 define i8 @t6(i8 %x, i1 %y, i8 %z) {
118 ; CHECK-LABEL: @t6(
119 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
120 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
121 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[T0]]
122 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
123 ; CHECK-NEXT:    ret i8 [[T2]]
125   %t0 = sub i8 0, %z
126   call void @use8(i8 %t0)
127   %t1 = select i1 %y, i8 -42, i8 %t0
128   %t2 = sub i8 %x, %t1
129   ret i8 %t2
131 define i8 @t7(i8 %x, i1 %y, i8 %z) {
132 ; CHECK-LABEL: @t7(
133 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 1, [[Z:%.*]]
134 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
135 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
136 ; CHECK-NEXT:    ret i8 [[T2]]
138   %t0 = shl i8 1, %z
139   %t1 = select i1 %y, i8 0, i8 %t0
140   %t2 = sub i8 %x, %t1
141   ret i8 %t2
143 define i8 @n8(i8 %x, i1 %y, i8 %z) {
144 ; CHECK-LABEL: @n8(
145 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 1, [[Z:%.*]]
146 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
147 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
148 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
149 ; CHECK-NEXT:    ret i8 [[T2]]
151   %t0 = shl i8 1, %z
152   call void @use8(i8 %t0)
153   %t1 = select i1 %y, i8 0, i8 %t0
154   %t2 = sub i8 %x, %t1
155   ret i8 %t2
158 ; Subtraction can be negated if the first operand can be negated
159 ; x - (y - z) -> x - y + z -> x + (-y) + z
160 define i8 @t9(i8 %x, i8 %y, i8 %z) {
161 ; CHECK-LABEL: @t9(
162 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
163 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
164 ; CHECK-NEXT:    [[T11:%.*]] = add i8 [[Y:%.*]], [[Z]]
165 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T11]], [[X:%.*]]
166 ; CHECK-NEXT:    ret i8 [[T2]]
168   %t0 = sub i8 0, %z
169   call void @use8(i8 %t0)
170   %t1 = sub i8 %t0, %y
171   %t2 = sub i8 %x, %t1
172   ret i8 %t2
174 define i8 @n10(i8 %x, i8 %y, i8 %z) {
175 ; CHECK-LABEL: @n10(
176 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
177 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
178 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[T0]], [[Y:%.*]]
179 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
180 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
181 ; CHECK-NEXT:    ret i8 [[T2]]
183   %t0 = sub i8 0, %z
184   call void @use8(i8 %t0)
185   %t1 = sub i8 %t0, %y
186   call void @use8(i8 %t1)
187   %t2 = sub i8 %x, %t1
188   ret i8 %t2
190 define i8 @n11(i8 %x, i8 %y, i8 %z) {
191 ; CHECK-LABEL: @n11(
192 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
193 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
194 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[Y:%.*]], [[Z]]
195 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
196 ; CHECK-NEXT:    ret i8 [[T2]]
198   %t0 = sub i8 0, %z
199   call void @use8(i8 %t0)
200   %t1 = sub i8 %y, %t0
201   %t2 = sub i8 %x, %t1
202   ret i8 %t2
205 ; Addition can be negated if both operands can be negated
206 ; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))
207 define i8 @t12(i8 %x, i8 %y, i8 %z) {
208 ; CHECK-LABEL: @t12(
209 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
210 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
211 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
212 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
213 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
214 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
215 ; CHECK-NEXT:    ret i8 [[T3]]
217   %t0 = sub i8 0, %y
218   call void @use8(i8 %t0)
219   %t1 = sub i8 0, %z
220   call void @use8(i8 %t1)
221   %t2 = add i8 %t0, %t1
222   %t3 = sub i8 %x, %t2
223   ret i8 %t3
225 define i8 @n13(i8 %x, i8 %y, i8 %z) {
226 ; CHECK-LABEL: @n13(
227 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
228 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
229 ; CHECK-NEXT:    [[T11:%.*]] = sub i8 [[Y]], [[Z:%.*]]
230 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T11]], [[X:%.*]]
231 ; CHECK-NEXT:    ret i8 [[T2]]
233   %t0 = sub i8 0, %y
234   call void @use8(i8 %t0)
235   %t1 = add i8 %t0, %z
236   %t2 = sub i8 %x, %t1
237   ret i8 %t2
239 define i8 @n14(i8 %x, i8 %y, i8 %z) {
240 ; CHECK-LABEL: @n14(
241 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
242 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
243 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
244 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
245 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
246 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]
247 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
248 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
249 ; CHECK-NEXT:    ret i8 [[T3]]
251   %t0 = sub i8 0, %y
252   call void @use8(i8 %t0)
253   %t1 = sub i8 0, %z
254   call void @use8(i8 %t1)
255   %t2 = add i8 %t0, %t1
256   call void @use8(i8 %t2)
257   %t3 = sub i8 %x, %t2
258   ret i8 %t3
261 ; Multiplication can be negated if either one of operands can be negated
262 ; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)
263 define i8 @t15(i8 %x, i8 %y, i8 %z) {
264 ; CHECK-LABEL: @t15(
265 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
266 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
267 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[Z:%.*]], [[Y]]
268 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[X:%.*]]
269 ; CHECK-NEXT:    ret i8 [[T2]]
271   %t0 = sub i8 0, %y
272   call void @use8(i8 %t0)
273   %t1 = mul i8 %t0, %z
274   %t2 = sub i8 %x, %t1
275   ret i8 %t2
277 define i8 @n16(i8 %x, i8 %y, i8 %z) {
278 ; CHECK-LABEL: @n16(
279 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
280 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
281 ; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[T0]], [[Z:%.*]]
282 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
283 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
284 ; CHECK-NEXT:    ret i8 [[T2]]
286   %t0 = sub i8 0, %y
287   call void @use8(i8 %t0)
288   %t1 = mul i8 %t0, %z
289   call void @use8(i8 %t1)
290   %t2 = sub i8 %x, %t1
291   ret i8 %t2