llvm.org GIT mirror
[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).
 916 916 917 917 /// Return true if we can simplify X / Y to 0. Remainder can adapt that answer 918 918 /// 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,⏎ 920 920 unsigned MaxRecurse, bool IsSigned) { 921 921 // Recursion is always used, so bail out at once if we already hit the limit. 922 922 if (!MaxRecurse--) 923 923 return false; 924 924 925 925 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 } 927 961 return false; 928 962 } 929 963 930 964 // 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); 933 967 } 934 968 935 969 /// These are simplifications common to SDiv and UDiv.
 531 531 ret i32 %div 532 532 } 533 533 534 ; When the divisor is known larger than the quotient, 535 ; InstSimplify should kill it before InstCombine sees it. 536 534 537 define i32 @shrink_no2(i8 %x) { 535 538 ; 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⏎ 539 540 ; 540 541 %conv = sext i8 %x to i32 541 542 %div = sdiv i32 %conv, -129 542 543 ret i32 %div 543 544 } 544 545 545 ; 17 bits are needed to represent 65535 as a signed value, so this shouldn't fold. 546 547 546 define i32 @shrink_no3(i16 %x) { 548 547 ; 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⏎ 552 549 ; 553 550 %conv = sext i16 %x to i32 554 551 %div = sdiv i32 %conv, 65535
 59 59 60 60 define i32 @div2(i32 %V) { 61 61 ; 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⏎ 65 63 ; 66 64 %A = sdiv i32 %V, -1 67 65 %B = sdiv i32 %A, -2147483648
 1 1 2 2 define i32 @sdiv_sext_big_divisor(i8 %x) { 3 3 ; 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⏎ 7 5 ; 8 6 %conv = sext i8 %x to i32 9 7 %div = sdiv i32 %conv, 129 23 21 24 22 define i32 @sdiv_sext_small_divisor(i8 %x) { 25 23 ; 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⏎ 29 25 ; 30 26 %conv = sext i8 %x to i32 31 27 %div = sdiv i32 %conv, -129 45 41 46 42 define i32 @sdiv_zext_big_divisor(i8 %x) { 47 43 ; 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⏎ 51 45 ; 52 46 %conv = zext i8 %x to i32 53 47 %div = sdiv i32 %conv, 256 67 61 68 62 define i32 @sdiv_zext_small_divisor(i8 %x) { 69 63 ; 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⏎ 73 65 ; 74 66 %conv = zext i8 %x to i32 75 67 %div = sdiv i32 %conv, -256 89 81 90 82 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 91 83 ; 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⏎ 95 85 ; 96 86 %and = and i32 %x, 253 97 87 %div = sdiv i32 %and, 254 111 101 112 102 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 113 103 ; 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⏎ 117 105 ; 118 106 %and = and i32 %x, 253 119 107 %div = sdiv i32 %and, -254 133 121 134 122 define i32 @sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 135 123 ; 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⏎ 139 125 ; 140 126 %or = or i32 %x, -253 141 127 %div = sdiv i32 %or, 254 155 141 156 142 define i32 @sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 157 143 ; 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⏎ 161 145 ; 162 146 %or = or i32 %x, -253 163 147 %div = sdiv i32 %or, -254 178 162 define i32 @srem_sext_big_divisor(i8 %x) { 179 163 ; CHECK-LABEL: @srem_sext_big_divisor( 180 164 ; 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]]⏎ 183 166 ; 184 167 %conv = sext i8 %x to i32 185 168 %rem = srem i32 %conv, 129 200 183 define i32 @srem_sext_small_divisor(i8 %x) { 201 184 ; CHECK-LABEL: @srem_sext_small_divisor( 202 185 ; 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]]⏎ 205 187 ; 206 188 %conv = sext i8 %x to i32 207 189 %rem = srem i32 %conv, -129 222 204 define i32 @srem_zext_big_divisor(i8 %x) { 223 205 ; CHECK-LABEL: @srem_zext_big_divisor( 224 206 ; 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]]⏎ 227 208 ; 228 209 %conv = zext i8 %x to i32 229 210 %rem = srem i32 %conv, 256 244 225 define i32 @srem_zext_small_divisor(i8 %x) { 245 226 ; CHECK-LABEL: @srem_zext_small_divisor( 246 227 ; 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]]⏎ 249 229 ; 250 230 %conv = zext i8 %x to i32 251 231 %rem = srem i32 %conv, -256 266 246 define i32 @srem_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { 267 247 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_clear_bits( 268 248 ; 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]]⏎ 271 250 ; 272 251 %and = and i32 %x, 253 273 252 %rem = srem i32 %and, 254 288 267 define i32 @srem_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { 289 268 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_clear_bits( 290 269 ; 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]]⏎ 293 271 ; 294 272 %and = and i32 %x, 253 295 273 %rem = srem i32 %and, -254 310 288 define i32 @srem_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { 311 289 ; CHECK-LABEL: @srem_dividend_known_smaller_than_pos_divisor_set_bits( 312 290 ; 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]]⏎ 315 292 ; 316 293 %or = or i32 %x, -253 317 294 %rem = srem i32 %or, 254 332 309 define i32 @srem_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { 333 310 ; CHECK-LABEL: @srem_dividend_known_smaller_than_neg_divisor_set_bits( 334 311 ; 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]]⏎ 337 313 ; 338 314 %or = or i32 %x, -253 339 315 %rem = srem i32 %or, -254 351 327 ret i32 %rem 352 328 } 353 329 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