llvm.org GIT mirror llvm / bc0f9d9
[InstSimplify] fold sdiv/srem based on compare of dividend and divisor This should bring signed div/rem analysis up to the same level as unsigned. We use icmp simplification to determine when the divisor is known greater than the dividend. Each positive test is followed by a negative test to show that we're not overstepping the boundaries of the known bits. There are extra tests for the signed-min-value special cases. Alive proofs: http://rise4fun.com/Alive/WI5 Differential Revision: https://reviews.llvm.org/D37713 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313264 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 2 years ago
4 changed file(s) with 84 addition(s) and 55 deletion(s). Raw diff Collapse all Expand all
916916
917917 /// Return true if we can simplify X / Y to 0. Remainder can adapt that answer
918918 /// to simplify X % Y to X.
919 static bool isDivZero(Value *Op0, Value *Op1, const SimplifyQuery &Q,
919 static bool isDivZero(Value *X, Value *Y, const SimplifyQuery &Q,
920920 unsigned MaxRecurse, bool IsSigned) {
921921 // Recursion is always used, so bail out at once if we already hit the limit.
922922 if (!MaxRecurse--)
923923 return false;
924924
925925 if (IsSigned) {
926 // TODO: Handle signed.
926 // |X| / |Y| --> 0
927 //
928 // We require that 1 operand is a simple constant. That could be extended to
929 // 2 variables if we computed the sign bit for each.
930 //
931 // Make sure that a constant is not the minimum signed value because taking
932 // the abs() of that is undefined.
933 Type *Ty = X->getType();
934 const APInt *C;
935 if (match(X, m_APInt(C)) && !C->isMinSignedValue()) {
936 // Is the variable divisor magnitude always greater than the constant
937 // dividend magnitude?
938 // |Y| > |C| --> Y < -abs(C) or Y > abs(C)
939 Constant *PosDividendC = ConstantInt::get(Ty, C->abs());
940 Constant *NegDividendC = ConstantInt::get(Ty, -C->abs());
941 if (isICmpTrue(CmpInst::ICMP_SLT, Y, NegDividendC, Q, MaxRecurse) ||
942 isICmpTrue(CmpInst::ICMP_SGT, Y, PosDividendC, Q, MaxRecurse))
943 return true;
944 }
945 if (match(Y, m_APInt(C))) {
946 // Special-case: we can't take the abs() of a minimum signed value. If
947 // that's the divisor, then all we have to do is prove that the dividend
948 // is also not the minimum signed value.
949 if (C->isMinSignedValue())
950 return isICmpTrue(CmpInst::ICMP_NE, X, Y, Q, MaxRecurse);
951
952 // Is the variable dividend magnitude always less than the constant
953 // divisor magnitude?
954 // |X| < |C| --> X > -abs(C) and X < abs(C)
955 Constant *PosDivisorC = ConstantInt::get(Ty, C->abs());
956 Constant *NegDivisorC = ConstantInt::get(Ty, -C->abs());
957 if (isICmpTrue(CmpInst::ICMP_SGT, X, NegDivisorC, Q, MaxRecurse) &&
958 isICmpTrue(CmpInst::ICMP_SLT, X, PosDivisorC, Q, MaxRecurse))
959 return true;
960 }
927961 return false;
928962 }
929963
930964 // IsSigned == false.
931 // Is the quotient unsigned less than the divisor?
932 return isICmpTrue(ICmpInst::ICMP_ULT, Op0, Op1, Q, MaxRecurse);
965 // Is the dividend unsigned less than the divisor?
966 return isICmpTrue(ICmpInst::ICMP_ULT, X, Y, Q, MaxRecurse);
933967 }
934968
935969 /// These are simplifications common to SDiv and UDiv.
531531 ret i32 %div
532532 }
533533
534 ; When the divisor is known larger than the quotient,
535 ; InstSimplify should kill it before InstCombine sees it.
536
534537 define i32 @shrink_no2(i8 %x) {
535538 ; CHECK-LABEL: @shrink_no2(
536 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32
537 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -129
538 ; CHECK-NEXT: ret i32 [[DIV]]
539 ; CHECK-NEXT: ret i32 0
539540 ;
540541 %conv = sext i8 %x to i32
541542 %div = sdiv i32 %conv, -129
542543 ret i32 %div
543544 }
544545
545 ; 17 bits are needed to represent 65535 as a signed value, so this shouldn't fold.
546
547546 define i32 @shrink_no3(i16 %x) {
548547 ; CHECK-LABEL: @shrink_no3(
549 ; CHECK-NEXT: [[CONV:%.*]] = sext i16 %x to i32
550 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 65535
551 ; CHECK-NEXT: ret i32 [[DIV]]
548 ; CHECK-NEXT: ret i32 0
552549 ;
553550 %conv = sext i16 %x to i32
554551 %div = sdiv i32 %conv, 65535
5959
6060 define i32 @div2(i32 %V) {
6161 ; CHECK-LABEL: @div2(
62 ; CHECK-NEXT: [[A:%.*]] = sdiv i32 %V, -1
63 ; CHECK-NEXT: [[B:%.*]] = sdiv i32 [[A]], -2147483648
64 ; CHECK-NEXT: ret i32 [[B]]
62 ; CHECK-NEXT: ret i32 0
6563 ;
6664 %A = sdiv i32 %V, -1
6765 %B = sdiv i32 %A, -2147483648
11
22 define i32 @sdiv_sext_big_divisor(i8 %x) {
33 ; CHECK-LABEL: @sdiv_sext_big_divisor(
4 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32
5 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 129
6 ; CHECK-NEXT: ret i32 [[DIV]]
4 ; CHECK-NEXT: ret i32 0
75 ;
86 %conv = sext i8 %x to i32
97 %div = sdiv i32 %conv, 129
2321
2422 define i32 @sdiv_sext_small_divisor(i8 %x) {
2523 ; CHECK-LABEL: @sdiv_sext_small_divisor(
26 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32
27 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -129
28 ; CHECK-NEXT: ret i32 [[DIV]]
24 ; CHECK-NEXT: ret i32 0
2925 ;
3026 %conv = sext i8 %x to i32
3127 %div = sdiv i32 %conv, -129
4541
4642 define i32 @sdiv_zext_big_divisor(i8 %x) {
4743 ; CHECK-LABEL: @sdiv_zext_big_divisor(
48 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32
49 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 256
50 ; CHECK-NEXT: ret i32 [[DIV]]
44 ; CHECK-NEXT: ret i32 0
5145 ;
5246 %conv = zext i8 %x to i32
5347 %div = sdiv i32 %conv, 256
6761
6862 define i32 @sdiv_zext_small_divisor(i8 %x) {
6963 ; CHECK-LABEL: @sdiv_zext_small_divisor(
70 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32
71 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -256
72 ; CHECK-NEXT: ret i32 [[DIV]]
64 ; CHECK-NEXT: ret i32 0
7365 ;
7466 %conv = zext i8 %x to i32
7567 %div = sdiv i32 %conv, -256
8981
9082 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
9183 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(
92 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253
93 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], 254
94 ; CHECK-NEXT: ret i32 [[DIV]]
84 ; CHECK-NEXT: ret i32 0
9585 ;
9686 %and = and i32 %x, 253
9787 %div = sdiv i32 %and, 254
111101
112102 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
113103 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(
114 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253
115 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], -254
116 ; CHECK-NEXT: ret i32 [[DIV]]
104 ; CHECK-NEXT: ret i32 0
117105 ;
118106 %and = and i32 %x, 253
119107 %div = sdiv i32 %and, -254
133121
134122 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
135123 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(
136 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253
137 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], 254
138 ; CHECK-NEXT: ret i32 [[DIV]]
124 ; CHECK-NEXT: ret i32 0
139125 ;
140126 %or = or i32 %x, -253
141127 %div = sdiv i32 %or, 254
155141
156142 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
157143 ; CHECK-LABEL: @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(
158 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253
159 ; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], -254
160 ; CHECK-NEXT: ret i32 [[DIV]]
144 ; CHECK-NEXT: ret i32 0
161145 ;
162146 %or = or i32 %x, -253
163147 %div = sdiv i32 %or, -254
178162 define i32 @srem_sext_big_divisor(i8 %x) {
179163 ; CHECK-LABEL: @srem_sext_big_divisor(
180164 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32
181 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], 129
182 ; CHECK-NEXT: ret i32 [[REM]]
165 ; CHECK-NEXT: ret i32 [[CONV]]
183166 ;
184167 %conv = sext i8 %x to i32
185168 %rem = srem i32 %conv, 129
200183 define i32 @srem_sext_small_divisor(i8 %x) {
201184 ; CHECK-LABEL: @srem_sext_small_divisor(
202185 ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32
203 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], -129
204 ; CHECK-NEXT: ret i32 [[REM]]
186 ; CHECK-NEXT: ret i32 [[CONV]]
205187 ;
206188 %conv = sext i8 %x to i32
207189 %rem = srem i32 %conv, -129
222204 define i32 @srem_zext_big_divisor(i8 %x) {
223205 ; CHECK-LABEL: @srem_zext_big_divisor(
224206 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32
225 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], 256
226 ; CHECK-NEXT: ret i32 [[REM]]
207 ; CHECK-NEXT: ret i32 [[CONV]]
227208 ;
228209 %conv = zext i8 %x to i32
229210 %rem = srem i32 %conv, 256
244225 define i32 @srem_zext_small_divisor(i8 %x) {
245226 ; CHECK-LABEL: @srem_zext_small_divisor(
246227 ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32
247 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[CONV]], -256
248 ; CHECK-NEXT: ret i32 [[REM]]
228 ; CHECK-NEXT: ret i32 [[CONV]]
249229 ;
250230 %conv = zext i8 %x to i32
251231 %rem = srem i32 %conv, -256
266246 define i32 @srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) {
267247 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_clear_bits(
268248 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253
269 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[AND]], 254
270 ; CHECK-NEXT: ret i32 [[REM]]
249 ; CHECK-NEXT: ret i32 [[AND]]
271250 ;
272251 %and = and i32 %x, 253
273252 %rem = srem i32 %and, 254
288267 define i32 @srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) {
289268 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_clear_bits(
290269 ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253
291 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[AND]], -254
292 ; CHECK-NEXT: ret i32 [[REM]]
270 ; CHECK-NEXT: ret i32 [[AND]]
293271 ;
294272 %and = and i32 %x, 253
295273 %rem = srem i32 %and, -254
310288 define i32 @srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) {
311289 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_set_bits(
312290 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253
313 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[OR]], 254
314 ; CHECK-NEXT: ret i32 [[REM]]
291 ; CHECK-NEXT: ret i32 [[OR]]
315292 ;
316293 %or = or i32 %x, -253
317294 %rem = srem i32 %or, 254
332309 define i32 @srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) {
333310 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_set_bits(
334311 ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253
335 ; CHECK-NEXT: [[REM:%.*]] = srem i32 [[OR]], -254
336 ; CHECK-NEXT: ret i32 [[REM]]
312 ; CHECK-NEXT: ret i32 [[OR]]
337313 ;
338314 %or = or i32 %x, -253
339315 %rem = srem i32 %or, -254
351327 ret i32 %rem
352328 }
353329
330 ; Make sure that we're handling the minimum signed constant correctly - can't fold this.
331
332 define i16 @sdiv_min_dividend(i8 %x) {
333 ; CHECK-LABEL: @sdiv_min_dividend(
334 ; CHECK-NEXT: [[Z:%.*]] = zext i8 %x to i16
335 ; CHECK-NEXT: [[D:%.*]] = sdiv i16 -32768, [[Z]]
336 ; CHECK-NEXT: ret i16 [[D]]
337 ;
338 %z = zext i8 %x to i16
339 %d = sdiv i16 -32768, %z
340 ret i16 %d
341 }
342
343 ; If the quotient is known to not be -32768, then this can fold.
344
345 define i16 @sdiv_min_divisor(i8 %x) {
346 ; CHECK-LABEL: @sdiv_min_divisor(
347 ; CHECK-NEXT: ret i16 0
348 ;
349 %z = zext i8 %x to i16
350 %d = sdiv i16 %z, -32768
351 ret i16 %d
352 }
353