1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -instcombine -S | FileCheck %s
6 ; Constant can be freely negated.
9 ; CHECK-NEXT: [[T0:%.*]] = add i8 [[X:%.*]], 42
10 ; CHECK-NEXT: ret i8 [[T0]]
16 ; Negation can be negated for free
17 define i8 @t1(i8 %x, i8 %y) {
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]]
25 call void @use8(i8 %t0)
30 ; Shift-left can be negated if all uses can be updated
31 define i8 @t2(i8 %x, i8 %y) {
33 ; CHECK-NEXT: [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
34 ; CHECK-NEXT: [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
35 ; CHECK-NEXT: ret i8 [[T1]]
41 define i8 @n2(i8 %x, i8 %y) {
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]]
49 call void @use8(i8 %t0)
53 define i8 @t3(i8 %x, i8 %y, i8 %z) {
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]]
62 call void @use8(i8 %t0)
67 define i8 @n3(i8 %x, i8 %y, i8 %z) {
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]]
77 call void @use8(i8 %t0)
79 call void @use8(i8 %t1)
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) {
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
95 define i8 @n4(i8 %x, i1 %y) {
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)
107 define i8 @n5(i8 %x, i1 %y, i8 %z) {
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
117 define i8 @t6(i8 %x, i1 %y, i8 %z) {
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]]
126 call void @use8(i8 %t0)
127 %t1 = select i1 %y, i8 -42, i8 %t0
131 define i8 @t7(i8 %x, i1 %y, i8 %z) {
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]]
139 %t1 = select i1 %y, i8 0, i8 %t0
143 define i8 @n8(i8 %x, i1 %y, i8 %z) {
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]]
152 call void @use8(i8 %t0)
153 %t1 = select i1 %y, i8 0, i8 %t0
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) {
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]]
169 call void @use8(i8 %t0)
174 define i8 @n10(i8 %x, i8 %y, i8 %z) {
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]]
184 call void @use8(i8 %t0)
186 call void @use8(i8 %t1)
190 define i8 @n11(i8 %x, i8 %y, i8 %z) {
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]]
199 call void @use8(i8 %t0)
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) {
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]]
218 call void @use8(i8 %t0)
220 call void @use8(i8 %t1)
221 %t2 = add i8 %t0, %t1
225 define i8 @n13(i8 %x, i8 %y, i8 %z) {
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]]
234 call void @use8(i8 %t0)
239 define i8 @n14(i8 %x, i8 %y, i8 %z) {
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]]
252 call void @use8(i8 %t0)
254 call void @use8(i8 %t1)
255 %t2 = add i8 %t0, %t1
256 call void @use8(i8 %t2)
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) {
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]]
272 call void @use8(i8 %t0)
277 define i8 @n16(i8 %x, i8 %y, i8 %z) {
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]]
287 call void @use8(i8 %t0)
289 call void @use8(i8 %t1)