llvm.org GIT mirror llvm / 9268a4a
revert rL345717 : [InstSimplify] fold icmp based on range of abs/nabs This can miscompile as shown in PR39510: https://bugs.llvm.org/show_bug.cgi?id=39510 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345780 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 11 months ago
2 changed file(s) with 75 addition(s) and 57 deletion(s). Raw diff Collapse all Expand all
29952995 return nullptr;
29962996 }
29972997
2998 static Value *simplifyICmpWithAbsNabs(CmpInst::Predicate Pred, Value *Op0,
2999 Value *Op1) {
3000 // We need a comparison with a constant.
3001 const APInt *C;
3002 if (!match(Op1, m_APInt(C)))
3003 return nullptr;
3004
3005 // matchSelectPattern returns the negation part of an abs pattern in SP1.
3006 // If the negate has an NSW flag, abs(INT_MIN) is undefined. Without that
3007 // constraint, we can't make a contiguous range for the result of abs.
3008 ICmpInst::Predicate AbsPred = ICmpInst::BAD_ICMP_PREDICATE;
3009 Value *SP0, *SP1;
3010 SelectPatternFlavor SPF = matchSelectPattern(Op0, SP0, SP1).Flavor;
3011 if (SPF == SelectPatternFlavor::SPF_ABS &&
3012 cast(SP1)->hasNoSignedWrap())
3013 // The result of abs(X) is >= 0 (with nsw).
3014 AbsPred = ICmpInst::ICMP_SGE;
3015 if (SPF == SelectPatternFlavor::SPF_NABS)
3016 // The result of -abs(X) is <= 0.
3017 AbsPred = ICmpInst::ICMP_SLE;
3018
3019 if (AbsPred == ICmpInst::BAD_ICMP_PREDICATE)
3020 return nullptr;
3021
3022 // Intersect the range of abs/nabs with the range of this icmp.
3023 // If there is no intersection, the icmp must be false.
3024 // If the intersection equals the range of abs/nabs, the icmp must be true.
3025 APInt Zero = APInt::getNullValue(C->getBitWidth());
3026 ConstantRange AbsRange = ConstantRange::makeExactICmpRegion(AbsPred, Zero);
3027 ConstantRange CmpRange = ConstantRange::makeExactICmpRegion(Pred, *C);
3028 ConstantRange Intersection = AbsRange.intersectWith(CmpRange);
3029 if (Intersection.isEmptySet())
3030 return getFalse(GetCompareTy(Op0));
3031 if (Intersection == AbsRange)
3032 return getTrue(GetCompareTy(Op0));
3033
3034 return nullptr;
3035 }
3036
30372998 /// Simplify integer comparisons where at least one operand of the compare
30382999 /// matches an integer min/max idiom.
30393000 static Value *simplifyICmpWithMinMax(CmpInst::Predicate Pred, Value *LHS,
34633424 return V;
34643425
34653426 if (Value *V = simplifyICmpWithMinMax(Pred, LHS, RHS, Q, MaxRecurse))
3466 return V;
3467
3468 if (Value *V = simplifyICmpWithAbsNabs(Pred, LHS, RHS))
34693427 return V;
34703428
34713429 // Simplify comparisons of related pointers using a powerful, recursive
44
55 define i1 @abs_nsw_is_positive(i32 %x) {
66 ; CHECK-LABEL: @abs_nsw_is_positive(
7 ; CHECK-NEXT: ret i1 true
7 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
8 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
9 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
10 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], -1
11 ; CHECK-NEXT: ret i1 [[R]]
812 ;
913 %cmp = icmp slt i32 %x, 0
1014 %negx = sub nsw i32 0, %x
3034
3135 define i1 @abs_nsw_is_positive_reduced_range(i32 %x) {
3236 ; CHECK-LABEL: @abs_nsw_is_positive_reduced_range(
33 ; CHECK-NEXT: ret i1 true
37 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
38 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
39 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
40 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], -42
41 ; CHECK-NEXT: ret i1 [[R]]
3442 ;
3543 %cmp = icmp slt i32 %x, 0
3644 %negx = sub nsw i32 0, %x
9098
9199 define i1 @abs_nsw_is_not_negative_sle(i32 %x) {
92100 ; CHECK-LABEL: @abs_nsw_is_not_negative_sle(
93 ; CHECK-NEXT: ret i1 false
101 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
102 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
103 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
104 ; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[ABS]], -1
105 ; CHECK-NEXT: ret i1 [[R]]
94106 ;
95107 %cmp = icmp slt i32 %x, 1
96108 %negx = sub nsw i32 0, %x
103115
104116 define i1 @abs_nsw_is_not_negative_reduced_range(i32 %x) {
105117 ; CHECK-LABEL: @abs_nsw_is_not_negative_reduced_range(
106 ; CHECK-NEXT: ret i1 false
118 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
119 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
120 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
121 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[ABS]], -24
122 ; CHECK-NEXT: ret i1 [[R]]
107123 ;
108124 %cmp = icmp slt i32 %x, 0
109125 %negx = sub nsw i32 0, %x
150166
151167 define i1 @nabs_is_negative_or_0(i32 %x) {
152168 ; CHECK-LABEL: @nabs_is_negative_or_0(
153 ; CHECK-NEXT: ret i1 true
169 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
170 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
171 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
172 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[NABS]], 1
173 ; CHECK-NEXT: ret i1 [[R]]
154174 ;
155175 %cmp = icmp slt i32 %x, 0
156176 %negx = sub i32 0, %x
163183
164184 define i1 @nabs_is_negative_or_0_sle(i32 %x) {
165185 ; CHECK-LABEL: @nabs_is_negative_or_0_sle(
166 ; CHECK-NEXT: ret i1 true
186 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
187 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
188 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
189 ; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[NABS]], 0
190 ; CHECK-NEXT: ret i1 [[R]]
167191 ;
168192 %cmp = icmp slt i32 %x, 1
169193 %negx = sub i32 0, %x
176200
177201 define i1 @nabs_is_negative_or_0_reduced_range(i32 %x) {
178202 ; CHECK-LABEL: @nabs_is_negative_or_0_reduced_range(
179 ; CHECK-NEXT: ret i1 true
203 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
204 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
205 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
206 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[NABS]], 421
207 ; CHECK-NEXT: ret i1 [[R]]
180208 ;
181209 %cmp = icmp slt i32 %x, 1
182210 %negx = sub i32 0, %x
206234
207235 define i1 @nabs_is_not_over_0(i32 %x) {
208236 ; CHECK-LABEL: @nabs_is_not_over_0(
209 ; CHECK-NEXT: ret i1 false
237 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
238 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
239 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
240 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[NABS]], 0
241 ; CHECK-NEXT: ret i1 [[R]]
210242 ;
211243 %cmp = icmp slt i32 %x, 0
212244 %negx = sub i32 0, %x
219251
220252 define i1 @nabs_is_not_over_0_sle(i32 %x) {
221253 ; CHECK-LABEL: @nabs_is_not_over_0_sle(
222 ; CHECK-NEXT: ret i1 false
254 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
255 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
256 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
257 ; CHECK-NEXT: [[R:%.*]] = icmp sge i32 [[NABS]], 1
258 ; CHECK-NEXT: ret i1 [[R]]
223259 ;
224260 %cmp = icmp slt i32 %x, 1
225261 %negx = sub i32 0, %x
232268
233269 define i1 @nabs_is_not_over_0_reduced_range(i32 %x) {
234270 ; CHECK-LABEL: @nabs_is_not_over_0_reduced_range(
235 ; CHECK-NEXT: ret i1 false
271 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
272 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
273 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
274 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[NABS]], 4223
275 ; CHECK-NEXT: ret i1 [[R]]
236276 ;
237277 %cmp = icmp slt i32 %x, 1
238278 %negx = sub i32 0, %x
277317
278318 define i1 @abs_nsw_is_positive_ult(i8 %x) {
279319 ; CHECK-LABEL: @abs_nsw_is_positive_ult(
280 ; CHECK-NEXT: ret i1 true
320 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
321 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i8 0, [[X]]
322 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEGX]], i8 [[X]]
323 ; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[ABS]], -117
324 ; CHECK-NEXT: ret i1 [[R]]
281325 ;
282326 %cmp = icmp slt i8 %x, 0
283327 %negx = sub nsw i8 0, %x
290334
291335 define i1 @abs_nsw_is_not_negative_ugt(i8 %x) {
292336 ; CHECK-LABEL: @abs_nsw_is_not_negative_ugt(
293 ; CHECK-NEXT: ret i1 false
337 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
338 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i8 0, [[X]]
339 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i8 [[NEGX]], i8 [[X]]
340 ; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[ABS]], 127
341 ; CHECK-NEXT: ret i1 [[R]]
294342 ;
295343 %cmp = icmp slt i8 %x, 0
296344 %negx = sub nsw i8 0, %x
303351
304352 define <2 x i1> @abs_nsw_is_not_negative_vec_splat(<2 x i32> %x) {
305353 ; CHECK-LABEL: @abs_nsw_is_not_negative_vec_splat(
306 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
354 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
355 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X]]
356 ; CHECK-NEXT: [[ABS:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[NEGX]], <2 x i32> [[X]]
357 ; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i32> [[ABS]],
358 ; CHECK-NEXT: ret <2 x i1> [[R]]
307359 ;
308360 %cmp = icmp slt <2 x i32> %x, zeroinitializer
309361 %negx = sub nsw <2 x i32> zeroinitializer, %x
316368
317369 define i1 @nabs_is_negative_or_0_ne(i8 %x) {
318370 ; CHECK-LABEL: @nabs_is_negative_or_0_ne(
319 ; CHECK-NEXT: ret i1 true
371 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
372 ; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X]]
373 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i8 [[X]], i8 [[NEGX]]
374 ; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[NABS]], 12
375 ; CHECK-NEXT: ret i1 [[R]]
320376 ;
321377 %cmp = icmp slt i8 %x, 0
322378 %negx = sub i8 0, %x
329385
330386 define <3 x i1> @nabs_is_not_over_0_sle_vec_splat(<3 x i33> %x) {
331387 ; CHECK-LABEL: @nabs_is_not_over_0_sle_vec_splat(
332 ; CHECK-NEXT: ret <3 x i1> zeroinitializer
388 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt <3 x i33> [[X:%.*]],
389 ; CHECK-NEXT: [[NEGX:%.*]] = sub <3 x i33> zeroinitializer, [[X]]
390 ; CHECK-NEXT: [[NABS:%.*]] = select <3 x i1> [[CMP]], <3 x i33> [[X]], <3 x i33> [[NEGX]]
391 ; CHECK-NEXT: [[R:%.*]] = icmp sge <3 x i33> [[NABS]],
392 ; CHECK-NEXT: ret <3 x i1> [[R]]
333393 ;
334394 %cmp = icmp slt <3 x i33> %x,
335395 %negx = sub <3 x i33> zeroinitializer, %x