1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S < %s | FileCheck %s
3
4; Given:
5;   add (add (xor %x, -1), %y), 1
6; Transform it to:
7;   sub %y, %x
8
9;------------------------------------------------------------------------------;
10; Scalar tests
11;------------------------------------------------------------------------------;
12
13define i32 @t0(i32 %x, i32 %y) {
14; CHECK-LABEL: @t0(
15; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]]
16; CHECK-NEXT:    ret i32 [[T2]]
17;
18  %t0 = xor i32 %x, -1
19  %t1 = add i32 %t0, %y
20  %t2 = add i32 %t1, 1
21  ret i32 %t2
22}
23
24;------------------------------------------------------------------------------;
25; Vector tests
26;------------------------------------------------------------------------------;
27
28define <4 x i32> @t1_vec_splat(<4 x i32> %x, <4 x i32> %y) {
29; CHECK-LABEL: @t1_vec_splat(
30; CHECK-NEXT:    [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
31; CHECK-NEXT:    ret <4 x i32> [[T2]]
32;
33  %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
34  %t1 = add <4 x i32> %t0, %y
35  %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1>
36  ret <4 x i32> %t2
37}
38
39define <4 x i32> @t2_vec_undef0(<4 x i32> %x, <4 x i32> %y) {
40; CHECK-LABEL: @t2_vec_undef0(
41; CHECK-NEXT:    [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
42; CHECK-NEXT:    ret <4 x i32> [[T2]]
43;
44  %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 undef, i32 -1>
45  %t1 = add <4 x i32> %t0, %y
46  %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 1, i32 1>
47  ret <4 x i32> %t2
48}
49
50define <4 x i32> @t3_vec_undef1(<4 x i32> %x, <4 x i32> %y) {
51; CHECK-LABEL: @t3_vec_undef1(
52; CHECK-NEXT:    [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
53; CHECK-NEXT:    ret <4 x i32> [[T2]]
54;
55  %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>
56  %t1 = add <4 x i32> %t0, %y
57  %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 undef, i32 1>
58  ret <4 x i32> %t2
59}
60
61define <4 x i32> @t4_vec_undef2(<4 x i32> %x, <4 x i32> %y) {
62; CHECK-LABEL: @t4_vec_undef2(
63; CHECK-NEXT:    [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
64; CHECK-NEXT:    ret <4 x i32> [[T2]]
65;
66  %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 undef, i32 -1>
67  %t1 = add <4 x i32> %t0, %y
68  %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 undef, i32 1>
69  ret <4 x i32> %t2
70}
71
72;------------------------------------------------------------------------------;
73; One-use tests
74;------------------------------------------------------------------------------;
75
76declare void @use32(i32)
77
78define i32 @t5(i32 %x, i32 %y) {
79; CHECK-LABEL: @t5(
80; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
81; CHECK-NEXT:    call void @use32(i32 [[T0]])
82; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y:%.*]], [[X]]
83; CHECK-NEXT:    ret i32 [[T2]]
84;
85  %t0 = xor i32 %x, -1
86  call void @use32(i32 %t0)
87  %t1 = add i32 %t0, %y
88  %t2 = add i32 %t1, 1
89  ret i32 %t2
90}
91
92define i32 @t6(i32 %x, i32 %y) {
93; CHECK-LABEL: @t6(
94; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
95; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]]
96; CHECK-NEXT:    call void @use32(i32 [[T1]])
97; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y]], [[X]]
98; CHECK-NEXT:    ret i32 [[T2]]
99;
100  %t0 = xor i32 %x, -1
101  %t1 = add i32 %t0, %y
102  call void @use32(i32 %t1)
103  %t2 = add i32 %t1, 1
104  ret i32 %t2
105}
106
107define i32 @t7(i32 %x, i32 %y) {
108; CHECK-LABEL: @t7(
109; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
110; CHECK-NEXT:    call void @use32(i32 [[T0]])
111; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]]
112; CHECK-NEXT:    call void @use32(i32 [[T1]])
113; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y]], [[X]]
114; CHECK-NEXT:    ret i32 [[T2]]
115;
116  %t0 = xor i32 %x, -1
117  call void @use32(i32 %t0)
118  %t1 = add i32 %t0, %y
119  call void @use32(i32 %t1)
120  %t2 = add i32 %t1, 1
121  ret i32 %t2
122}
123
124;------------------------------------------------------------------------------;
125; Commutativity
126;------------------------------------------------------------------------------;
127
128declare i32 @gen32()
129
130define i32 @t8_commutative0(i32 %x) {
131; CHECK-LABEL: @t8_commutative0(
132; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
133; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
134; CHECK-NEXT:    call void @use32(i32 [[T0]])
135; CHECK-NEXT:    [[T1:%.*]] = add i32 [[Y]], [[T0]]
136; CHECK-NEXT:    call void @use32(i32 [[T1]])
137; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y]], [[X]]
138; CHECK-NEXT:    ret i32 [[T2]]
139;
140  %y = call i32 @gen32()
141  %t0 = xor i32 %x, -1
142  call void @use32(i32 %t0)
143  %t1 = add i32 %y, %t0 ; swapped
144  call void @use32(i32 %t1)
145  %t2 = add i32 %t1, 1
146  ret i32 %t2
147}
148
149define i32 @t9_commutative1(i32 %x, i32 %y) {
150; CHECK-LABEL: @t9_commutative1(
151; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
152; CHECK-NEXT:    call void @use32(i32 [[T0]])
153; CHECK-NEXT:    [[T1:%.*]] = sub i32 0, [[X]]
154; CHECK-NEXT:    call void @use32(i32 [[T1]])
155; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y:%.*]], [[X]]
156; CHECK-NEXT:    ret i32 [[T2]]
157;
158  %t0 = xor i32 %x, -1
159  call void @use32(i32 %t0)
160  %t1 = add i32 %t0, 1  ; +1 is not last
161  call void @use32(i32 %t1)
162  %t2 = add i32 %t1, %y ;
163  ret i32 %t2
164}
165
166define i32 @t10_commutative2(i32 %x) {
167; CHECK-LABEL: @t10_commutative2(
168; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
169; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
170; CHECK-NEXT:    call void @use32(i32 [[T0]])
171; CHECK-NEXT:    [[T1:%.*]] = sub i32 0, [[X]]
172; CHECK-NEXT:    call void @use32(i32 [[T1]])
173; CHECK-NEXT:    [[T2:%.*]] = sub i32 [[Y]], [[X]]
174; CHECK-NEXT:    ret i32 [[T2]]
175;
176  %y = call i32 @gen32()
177  %t0 = xor i32 %x, -1
178  call void @use32(i32 %t0)
179  %t1 = add i32 %t0, 1  ; +1 is not last
180  call void @use32(i32 %t1)
181  %t2 = add i32 %y, %t1 ; swapped
182  ret i32 %t2
183}
184
185;------------------------------------------------------------------------------;
186; Basic negative tests
187;------------------------------------------------------------------------------;
188
189define i32 @n11(i32 %x, i32 %y) {
190; CHECK-LABEL: @n11(
191; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], 2147483647
192; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]]
193; CHECK-NEXT:    [[T2:%.*]] = add i32 [[T1]], 1
194; CHECK-NEXT:    ret i32 [[T2]]
195;
196  %t0 = xor i32 %x, 2147483647 ; not -1
197  %t1 = add i32 %t0, %y
198  %t2 = add i32 %t1, 1
199  ret i32 %t2
200}
201
202define i32 @n12(i32 %x, i32 %y) {
203; CHECK-LABEL: @n12(
204; CHECK-NEXT:    [[T0:%.*]] = xor i32 [[X:%.*]], -1
205; CHECK-NEXT:    [[T1:%.*]] = add i32 [[T0]], [[Y:%.*]]
206; CHECK-NEXT:    [[T2:%.*]] = add i32 [[T1]], 2
207; CHECK-NEXT:    ret i32 [[T2]]
208;
209  %t0 = xor i32 %x, -1
210  %t1 = add i32 %t0, %y
211  %t2 = add i32 %t1, 2 ; not +1
212  ret i32 %t2
213}
214