llvm.org GIT mirror llvm / 7e7dc45
Fix ConstantRange::unionWith. Also make it work a little hard in some cases to return the smallest union of two ranges instead of just any range that happens to contain the union. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76360 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 10 years ago
2 changed file(s) with 72 addition(s) and 56 deletion(s). Raw diff Collapse all Expand all
370370
371371 if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this);
372372
373 APInt L = Lower, U = Upper;
374
375373 if (!isWrappedSet() && !CR.isWrappedSet()) {
374 if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) {
375 // If the two ranges are disjoint, find the smaller gap and bridge it.
376 APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
377 if (d1.ult(d2))
378 return ConstantRange(Lower, CR.Upper);
379 else
380 return ConstantRange(CR.Lower, Upper);
381 }
382
383 APInt L = Lower, U = Upper;
376384 if (CR.Lower.ult(L))
377385 L = CR.Lower;
378
379 if (CR.Upper.ugt(U))
386 if ((CR.Upper - 1).ugt(U - 1))
380387 U = CR.Upper;
381 }
382
383 if (isWrappedSet() && !CR.isWrappedSet()) {
384 if ((CR.Lower.ult(Upper) && CR.Upper.ult(Upper)) ||
385 (CR.Lower.ugt(Lower) && CR.Upper.ugt(Lower))) {
388
389 if (L == 0 && U == 0)
390 return ConstantRange(getBitWidth());
391
392 return ConstantRange(L, U);
393 }
394
395 if (!CR.isWrappedSet()) {
396 // ------U L----- and ------U L----- : this
397 // L--U L--U : CR
398 if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower))
386399 return *this;
387 }
388
389 if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) {
400
401 // ------U L----- : this
402 // L---------U : CR
403 if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper))
390404 return ConstantRange(getBitWidth());
391 }
392
393 if (CR.Lower.ule(Upper) && CR.Upper.ule(Lower)) {
394 APInt d1 = CR.Upper - Upper, d2 = Lower - CR.Upper;
395 if (d1.ult(d2)) {
396 U = CR.Upper;
397 } else {
398 L = CR.Upper;
399 }
400 }
401
402 if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower)) {
405
406 // ----U L---- : this
407 // L---U : CR
408 //
409 if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) {
403410 APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
404 if (d1.ult(d2)) {
405 U = CR.Lower + 1;
406 } else {
407 L = CR.Upper - 1;
408 }
409 }
410
411 if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) {
412 APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Lower;
413
414 if (d1.ult(d2)) {
415 U = CR.Lower + 1;
416 } else {
417 L = CR.Lower;
418 }
419 }
420 }
421
422 if (isWrappedSet() && CR.isWrappedSet()) {
423 if (Lower.ult(CR.Upper) || CR.Lower.ult(Upper))
424 return ConstantRange(getBitWidth());
425
426 if (CR.Upper.ugt(U)) {
427 U = CR.Upper;
428 }
429
430 if (CR.Lower.ult(L)) {
431 L = CR.Lower;
432 }
433
434 if (L == U) return ConstantRange(getBitWidth());
435 }
411 if (d1.ult(d2))
412 return ConstantRange(Lower, CR.Upper);
413 else
414 return ConstantRange(CR.Lower, Upper);
415 }
416
417 // ----U L----- : this
418 // L----U : CR
419 if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper))
420 return ConstantRange(CR.Lower, Upper);
421
422 // ------U L---- : this
423 // L-----U : CR
424 if (CR.Lower.ult(Upper) && CR.Upper.ult(Lower))
425 return ConstantRange(Lower, CR.Upper);
426 }
427
428 assert(isWrappedSet() && CR.isWrappedSet() &&
429 "ConstantRange::unionWith missed wrapped union unwrapped case");
430
431 // ------U L---- and ------U L---- : this
432 // -U L----------- and ------------U L : CR
433 if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
434 return ConstantRange(getBitWidth());
435
436 APInt L = Lower, U = Upper;
437 if (CR.Upper.ugt(U))
438 U = CR.Upper;
439 if (CR.Lower.ult(L))
440 L = CR.Lower;
436441
437442 return ConstantRange(L, U);
438443 }
218218 EXPECT_TRUE(Empty.unionWith(Empty).isEmptySet());
219219 EXPECT_TRUE(Full.unionWith(Full).isFullSet());
220220 EXPECT_TRUE(Some.unionWith(Wrap).isFullSet());
221
222 // PR4545
223 EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(
224 ConstantRange(APInt(16, 0), APInt(16, 8))),
225 ConstantRange(APInt(16, 14), APInt(16, 8)));
226 EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
227 ConstantRange(APInt(16, 4), APInt(16, 0))),
228 ConstantRange(16));
229 EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
230 ConstantRange(APInt(16, 2), APInt(16, 1))),
231 ConstantRange(16));
221232 }
222233
223234 TEST_F(ConstantRangeTest, SubtractAPInt) {