1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
5 ; add (add (xor %x, -1), %y), 1
9 ;------------------------------------------------------------------------------;
11 ;------------------------------------------------------------------------------;
13 define i32 @t0(i32 %x, i32 %y) {
15 ; CHECK-NEXT: [[T2:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]]
16 ; CHECK-NEXT: ret i32 [[T2]]
24 ;------------------------------------------------------------------------------;
26 ;------------------------------------------------------------------------------;
28 define <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]]
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>
39 define <4 x i32> @t2_vec_poison0(<4 x i32> %x, <4 x i32> %y) {
40 ; CHECK-LABEL: @t2_vec_poison0(
41 ; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
42 ; CHECK-NEXT: ret <4 x i32> [[T2]]
44 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 poison, 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>
50 define <4 x i32> @t3_vec_poison1(<4 x i32> %x, <4 x i32> %y) {
51 ; CHECK-LABEL: @t3_vec_poison1(
52 ; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
53 ; CHECK-NEXT: ret <4 x i32> [[T2]]
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 poison, i32 1>
61 define <4 x i32> @t4_vec_poison2(<4 x i32> %x, <4 x i32> %y) {
62 ; CHECK-LABEL: @t4_vec_poison2(
63 ; CHECK-NEXT: [[T2:%.*]] = sub <4 x i32> [[Y:%.*]], [[X:%.*]]
64 ; CHECK-NEXT: ret <4 x i32> [[T2]]
66 %t0 = xor <4 x i32> %x, <i32 -1, i32 -1, i32 poison, i32 -1>
67 %t1 = add <4 x i32> %t0, %y
68 %t2 = add <4 x i32> %t1, <i32 1, i32 1, i32 poison, i32 1>
72 ;------------------------------------------------------------------------------;
74 ;------------------------------------------------------------------------------;
76 declare void @use32(i32)
78 define i32 @t5(i32 %x, i32 %y) {
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]]
86 call void @use32(i32 %t0)
92 define i32 @t6(i32 %x, i32 %y) {
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]]
101 %t1 = add i32 %t0, %y
102 call void @use32(i32 %t1)
107 define i32 @t7(i32 %x, i32 %y) {
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]]
117 call void @use32(i32 %t0)
118 %t1 = add i32 %t0, %y
119 call void @use32(i32 %t1)
124 ;------------------------------------------------------------------------------;
126 ;------------------------------------------------------------------------------;
130 define 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]]
140 %y = call i32 @gen32()
142 call void @use32(i32 %t0)
143 %t1 = add i32 %y, %t0 ; swapped
144 call void @use32(i32 %t1)
149 define 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]]
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 ;
166 define 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]]
176 %y = call i32 @gen32()
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
185 ;------------------------------------------------------------------------------;
186 ; Basic negative tests
187 ;------------------------------------------------------------------------------;
189 define i32 @n11(i32 %x, i32 %y) {
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]]
196 %t0 = xor i32 %x, 2147483647 ; not -1
197 %t1 = add i32 %t0, %y
202 define i32 @n12(i32 %x, i32 %y) {
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]]
210 %t1 = add i32 %t0, %y
211 %t2 = add i32 %t1, 2 ; not +1