@@ -1322,107 +1322,23 @@ Value *InstCombinerImpl::foldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS,
1322
1322
if (LHS0 != RHS0)
1323
1323
return nullptr ;
1324
1324
1325
- // ICMP_[US][GL]E X, C is folded to ICMP_[US][GL]T elsewhere.
1326
- if (PredL == ICmpInst::ICMP_UGE || PredL == ICmpInst::ICMP_ULE ||
1327
- PredR == ICmpInst::ICMP_UGE || PredR == ICmpInst::ICMP_ULE ||
1328
- PredL == ICmpInst::ICMP_SGE || PredL == ICmpInst::ICMP_SLE ||
1329
- PredR == ICmpInst::ICMP_SGE || PredR == ICmpInst::ICMP_SLE)
1325
+ ConstantRange CR1 =
1326
+ ConstantRange::makeExactICmpRegion (PredL, LHSC->getValue ());
1327
+ ConstantRange CR2 =
1328
+ ConstantRange::makeExactICmpRegion (PredR, RHSC->getValue ());
1329
+ Optional<ConstantRange> CR = CR1.exactIntersectWith (CR2);
1330
+ if (!CR)
1330
1331
return nullptr ;
1331
1332
1332
- // We can't fold (ugt x, C) & (sgt x, C2).
1333
- if (!predicatesFoldable (PredL, PredR))
1334
- return nullptr ;
1335
-
1336
- // Ensure that the larger constant is on the RHS.
1337
- bool ShouldSwap;
1338
- if (CmpInst::isSigned (PredL) ||
1339
- (ICmpInst::isEquality (PredL) && CmpInst::isSigned (PredR)))
1340
- ShouldSwap = LHSC->getValue ().sgt (RHSC->getValue ());
1341
- else
1342
- ShouldSwap = LHSC->getValue ().ugt (RHSC->getValue ());
1343
-
1344
- if (ShouldSwap) {
1345
- std::swap (LHS, RHS);
1346
- std::swap (LHSC, RHSC);
1347
- std::swap (PredL, PredR);
1348
- }
1349
-
1350
- // At this point, we know we have two icmp instructions
1351
- // comparing a value against two constants and and'ing the result
1352
- // together. Because of the above check, we know that we only have
1353
- // icmp eq, icmp ne, icmp [su]lt, and icmp [SU]gt here. We also know
1354
- // (from the icmp folding check above), that the two constants
1355
- // are not equal and that the larger constant is on the RHS
1356
- assert (LHSC != RHSC && " Compares not folded above?" );
1357
-
1358
- switch (PredL) {
1359
- default :
1360
- llvm_unreachable (" Unknown integer condition code!" );
1361
- case ICmpInst::ICMP_NE:
1362
- switch (PredR) {
1363
- default :
1364
- llvm_unreachable (" Unknown integer condition code!" );
1365
- case ICmpInst::ICMP_ULT:
1366
- // (X != 13 & X u< 14) -> X < 13
1367
- if (LHSC->getValue () == (RHSC->getValue () - 1 ))
1368
- return Builder.CreateICmpULT (LHS0, LHSC);
1369
- if (LHSC->isZero ()) // (X != 0 & X u< C) -> X-1 u< C-1
1370
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (),
1371
- false , true );
1372
- break ; // (X != 13 & X u< 15) -> no change
1373
- case ICmpInst::ICMP_SLT:
1374
- // (X != 13 & X s< 14) -> X < 13
1375
- if (LHSC->getValue () == (RHSC->getValue () - 1 ))
1376
- return Builder.CreateICmpSLT (LHS0, LHSC);
1377
- // (X != INT_MIN & X s< C) -> X-(INT_MIN+1) u< (C-(INT_MIN+1))
1378
- if (LHSC->isMinValue (true ))
1379
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (),
1380
- true , true );
1381
- break ; // (X != 13 & X s< 15) -> no change
1382
- case ICmpInst::ICMP_NE:
1383
- // Potential folds for this case should already be handled.
1384
- break ;
1385
- }
1386
- break ;
1387
- case ICmpInst::ICMP_UGT:
1388
- switch (PredR) {
1389
- default :
1390
- llvm_unreachable (" Unknown integer condition code!" );
1391
- case ICmpInst::ICMP_NE:
1392
- // (X u> 13 & X != 14) -> X u> 14
1393
- if (RHSC->getValue () == (LHSC->getValue () + 1 ))
1394
- return Builder.CreateICmp (PredL, LHS0, RHSC);
1395
- // X u> C & X != UINT_MAX -> (X-(C+1)) u< UINT_MAX-(C+1)
1396
- if (RHSC->isMaxValue (false ))
1397
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (),
1398
- false , true );
1399
- break ; // (X u> 13 & X != 15) -> no change
1400
- case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) -> (X-14) u< 1
1401
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (),
1402
- false , true );
1403
- }
1404
- break ;
1405
- case ICmpInst::ICMP_SGT:
1406
- switch (PredR) {
1407
- default :
1408
- llvm_unreachable (" Unknown integer condition code!" );
1409
- case ICmpInst::ICMP_NE:
1410
- // (X s> 13 & X != 14) -> X s> 14
1411
- if (RHSC->getValue () == (LHSC->getValue () + 1 ))
1412
- return Builder.CreateICmp (PredL, LHS0, RHSC);
1413
- // X s> C & X != INT_MAX -> (X-(C+1)) u< INT_MAX-(C+1)
1414
- if (RHSC->isMaxValue (true ))
1415
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (),
1416
- true , true );
1417
- break ; // (X s> 13 & X != 15) -> no change
1418
- case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) -> (X-14) u< 1
1419
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue (), true ,
1420
- true );
1421
- }
1422
- break ;
1423
- }
1424
-
1425
- return nullptr ;
1333
+ CmpInst::Predicate Pred;
1334
+ APInt NewRHS, Offset;
1335
+ CR->getEquivalentICmp (Pred, NewRHS, Offset);
1336
+
1337
+ Type *Ty = LHS0->getType ();
1338
+ Value *NewLHS = LHS0;
1339
+ if (Offset != 0 )
1340
+ NewLHS = Builder.CreateAdd (NewLHS, ConstantInt::get (Ty, Offset));
1341
+ return Builder.CreateICmp (Pred, NewLHS, ConstantInt::get (Ty, NewRHS));
1426
1342
}
1427
1343
1428
1344
Value *InstCombinerImpl::foldLogicOfFCmps (FCmpInst *LHS, FCmpInst *RHS,
@@ -2551,100 +2467,23 @@ Value *InstCombinerImpl::foldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
2551
2467
if (LHS0 != RHS0)
2552
2468
return nullptr ;
2553
2469
2554
- // ICMP_[US][GL]E X, C is folded to ICMP_[US][GL]T elsewhere.
2555
- if (PredL == ICmpInst::ICMP_UGE || PredL == ICmpInst::ICMP_ULE ||
2556
- PredR == ICmpInst::ICMP_UGE || PredR == ICmpInst::ICMP_ULE ||
2557
- PredL == ICmpInst::ICMP_SGE || PredL == ICmpInst::ICMP_SLE ||
2558
- PredR == ICmpInst::ICMP_SGE || PredR == ICmpInst::ICMP_SLE)
2470
+ ConstantRange CR1 =
2471
+ ConstantRange::makeExactICmpRegion (PredL, LHSC->getValue ());
2472
+ ConstantRange CR2 =
2473
+ ConstantRange::makeExactICmpRegion (PredR, RHSC->getValue ());
2474
+ Optional<ConstantRange> CR = CR1.exactUnionWith (CR2);
2475
+ if (!CR)
2559
2476
return nullptr ;
2560
2477
2561
- // We can't fold (ugt x, C) | (sgt x, C2).
2562
- if (!predicatesFoldable (PredL, PredR))
2563
- return nullptr ;
2564
-
2565
- // Ensure that the larger constant is on the RHS.
2566
- bool ShouldSwap;
2567
- if (CmpInst::isSigned (PredL) ||
2568
- (ICmpInst::isEquality (PredL) && CmpInst::isSigned (PredR)))
2569
- ShouldSwap = LHSC->getValue ().sgt (RHSC->getValue ());
2570
- else
2571
- ShouldSwap = LHSC->getValue ().ugt (RHSC->getValue ());
2572
-
2573
- if (ShouldSwap) {
2574
- std::swap (LHS, RHS);
2575
- std::swap (LHSC, RHSC);
2576
- std::swap (PredL, PredR);
2577
- }
2578
-
2579
- // At this point, we know we have two icmp instructions
2580
- // comparing a value against two constants and or'ing the result
2581
- // together. Because of the above check, we know that we only have
2582
- // ICMP_EQ, ICMP_NE, ICMP_LT, and ICMP_GT here. We also know (from the
2583
- // icmp folding check above), that the two constants are not
2584
- // equal.
2585
- assert (LHSC != RHSC && " Compares not folded above?" );
2586
-
2587
- switch (PredL) {
2588
- default :
2589
- llvm_unreachable (" Unknown integer condition code!" );
2590
- case ICmpInst::ICMP_EQ:
2591
- switch (PredR) {
2592
- default :
2593
- llvm_unreachable (" Unknown integer condition code!" );
2594
- case ICmpInst::ICMP_EQ:
2595
- // Potential folds for this case should already be handled.
2596
- break ;
2597
- case ICmpInst::ICMP_UGT:
2598
- // (X == 0 || X u> C) -> (X-1) u>= C
2599
- if (LHSC->isMinValue (false ))
2600
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue () + 1 ,
2601
- false , false );
2602
- // (X == 13 | X u> 14) -> no change
2603
- break ;
2604
- case ICmpInst::ICMP_SGT:
2605
- // (X == INT_MIN || X s> C) -> (X-(INT_MIN+1)) u>= C-INT_MIN
2606
- if (LHSC->isMinValue (true ))
2607
- return insertRangeTest (LHS0, LHSC->getValue () + 1 , RHSC->getValue () + 1 ,
2608
- true , false );
2609
- // (X == 13 | X s> 14) -> no change
2610
- break ;
2611
- }
2612
- break ;
2613
- case ICmpInst::ICMP_ULT:
2614
- switch (PredR) {
2615
- default :
2616
- llvm_unreachable (" Unknown integer condition code!" );
2617
- case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
2618
- // (X u< C || X == UINT_MAX) => (X-C) u>= UINT_MAX-C
2619
- if (RHSC->isMaxValue (false ))
2620
- return insertRangeTest (LHS0, LHSC->getValue (), RHSC->getValue (),
2621
- false , false );
2622
- break ;
2623
- case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) -> (X-13) u> 2
2624
- assert (!RHSC->isMaxValue (false ) && " Missed icmp simplification" );
2625
- return insertRangeTest (LHS0, LHSC->getValue (), RHSC->getValue () + 1 ,
2626
- false , false );
2627
- }
2628
- break ;
2629
- case ICmpInst::ICMP_SLT:
2630
- switch (PredR) {
2631
- default :
2632
- llvm_unreachable (" Unknown integer condition code!" );
2633
- case ICmpInst::ICMP_EQ:
2634
- // (X s< C || X == INT_MAX) => (X-C) u>= INT_MAX-C
2635
- if (RHSC->isMaxValue (true ))
2636
- return insertRangeTest (LHS0, LHSC->getValue (), RHSC->getValue (),
2637
- true , false );
2638
- // (X s< 13 | X == 14) -> no change
2639
- break ;
2640
- case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) -> (X-13) u> 2
2641
- assert (!RHSC->isMaxValue (true ) && " Missed icmp simplification" );
2642
- return insertRangeTest (LHS0, LHSC->getValue (), RHSC->getValue () + 1 , true ,
2643
- false );
2644
- }
2645
- break ;
2646
- }
2647
- return nullptr ;
2478
+ CmpInst::Predicate Pred;
2479
+ APInt NewRHS, Offset;
2480
+ CR->getEquivalentICmp (Pred, NewRHS, Offset);
2481
+
2482
+ Type *Ty = LHS0->getType ();
2483
+ Value *NewLHS = LHS0;
2484
+ if (Offset != 0 )
2485
+ NewLHS = Builder.CreateAdd (NewLHS, ConstantInt::get (Ty, Offset));
2486
+ return Builder.CreateICmp (Pred, NewLHS, ConstantInt::get (Ty, NewRHS));
2648
2487
}
2649
2488
2650
2489
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
0 commit comments