@@ -2537,14 +2537,19 @@ static bool hoistAdd(ICmpInst::Predicate Pred, Value *VariantLHS,
25372537                     Value *InvariantRHS, ICmpInst &ICmp, Loop &L,
25382538                     ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU,
25392539                     AssumptionCache *AC, DominatorTree *DT) {
2540-   assert (ICmpInst::isSigned (Pred) && " Not supported yet!"  );
25412540  assert (!L.isLoopInvariant (VariantLHS) && " Precondition."  );
25422541  assert (L.isLoopInvariant (InvariantRHS) && " Precondition."  );
25432542
2543+   bool  IsSigned = ICmpInst::isSigned (Pred);
2544+ 
25442545  //  Try to represent VariantLHS as sum of invariant and variant operands.
25452546  using  namespace  PatternMatch ; 
25462547  Value *VariantOp, *InvariantOp;
2547-   if  (!match (VariantLHS, m_NSWAdd (m_Value (VariantOp), m_Value (InvariantOp))))
2548+   if  (IsSigned &&
2549+       !match (VariantLHS, m_NSWAdd (m_Value (VariantOp), m_Value (InvariantOp))))
2550+     return  false ;
2551+   if  (!IsSigned &&
2552+       !match (VariantLHS, m_NUWAdd (m_Value (VariantOp), m_Value (InvariantOp))))
25482553    return  false ;
25492554
25502555  //  LHS itself is a loop-variant, try to represent it in the form:
@@ -2559,17 +2564,20 @@ static bool hoistAdd(ICmpInst::Predicate Pred, Value *VariantLHS,
25592564  //  normal linear arithmetics). Overflows make things much more complicated, so
25602565  //  we want to avoid this.
25612566  auto  &DL = L.getHeader ()->getDataLayout ();
2562-   bool  ProvedNoOverflowAfterReassociate =
2563-       computeOverflowForSignedSub (InvariantRHS, InvariantOp,
2564-                                   SimplifyQuery (DL, DT, AC, &ICmp)) ==
2565-       llvm::OverflowResult::NeverOverflows;
2566-   if  (!ProvedNoOverflowAfterReassociate)
2567+   SimplifyQuery SQ (DL, DT, AC, &ICmp);
2568+   if  (IsSigned && computeOverflowForSignedSub (InvariantRHS, InvariantOp, SQ) !=
2569+                       llvm::OverflowResult::NeverOverflows)
2570+     return  false ;
2571+   if  (!IsSigned &&
2572+       computeOverflowForUnsignedSub (InvariantRHS, InvariantOp, SQ) !=
2573+           llvm::OverflowResult::NeverOverflows)
25672574    return  false ;
25682575  auto  *Preheader = L.getLoopPreheader ();
25692576  assert (Preheader && " Loop is not in simplify form?"  );
25702577  IRBuilder<> Builder (Preheader->getTerminator ());
2571-   Value *NewCmpOp = Builder.CreateSub (InvariantRHS, InvariantOp, " invariant.op"  ,
2572-                                       /* HasNUW*/   false , /* HasNSW*/   true );
2578+   Value *NewCmpOp =
2579+       Builder.CreateSub (InvariantRHS, InvariantOp, " invariant.op"  ,
2580+                         /* HasNUW*/   !IsSigned, /* HasNSW*/   IsSigned);
25732581  ICmp.setPredicate (Pred);
25742582  ICmp.setOperand (0 , VariantOp);
25752583  ICmp.setOperand (1 , NewCmpOp);
@@ -2584,14 +2592,19 @@ static bool hoistSub(ICmpInst::Predicate Pred, Value *VariantLHS,
25842592                     Value *InvariantRHS, ICmpInst &ICmp, Loop &L,
25852593                     ICFLoopSafetyInfo &SafetyInfo, MemorySSAUpdater &MSSAU,
25862594                     AssumptionCache *AC, DominatorTree *DT) {
2587-   assert (ICmpInst::isSigned (Pred) && " Not supported yet!"  );
25882595  assert (!L.isLoopInvariant (VariantLHS) && " Precondition."  );
25892596  assert (L.isLoopInvariant (InvariantRHS) && " Precondition."  );
25902597
2598+   bool  IsSigned = ICmpInst::isSigned (Pred);
2599+ 
25912600  //  Try to represent VariantLHS as sum of invariant and variant operands.
25922601  using  namespace  PatternMatch ; 
25932602  Value *VariantOp, *InvariantOp;
2594-   if  (!match (VariantLHS, m_NSWSub (m_Value (VariantOp), m_Value (InvariantOp))))
2603+   if  (IsSigned &&
2604+       !match (VariantLHS, m_NSWSub (m_Value (VariantOp), m_Value (InvariantOp))))
2605+     return  false ;
2606+   if  (!IsSigned &&
2607+       !match (VariantLHS, m_NUWSub (m_Value (VariantOp), m_Value (InvariantOp))))
25952608    return  false ;
25962609
25972610  bool  VariantSubtracted = false ;
@@ -2613,26 +2626,36 @@ static bool hoistSub(ICmpInst::Predicate Pred, Value *VariantLHS,
26132626  //  "C1 - C2" does not overflow.
26142627  auto  &DL = L.getHeader ()->getDataLayout ();
26152628  SimplifyQuery SQ (DL, DT, AC, &ICmp);
2616-   if  (VariantSubtracted) {
2629+   if  (VariantSubtracted && IsSigned ) {
26172630    //  C1 - LV < C2 --> LV > C1 - C2
26182631    if  (computeOverflowForSignedSub (InvariantOp, InvariantRHS, SQ) !=
26192632        llvm::OverflowResult::NeverOverflows)
26202633      return  false ;
2621-   } else  {
2634+   } else  if  (VariantSubtracted && !IsSigned) {
2635+     //  C1 - LV < C2 --> LV > C1 - C2
2636+     if  (computeOverflowForUnsignedSub (InvariantOp, InvariantRHS, SQ) !=
2637+         llvm::OverflowResult::NeverOverflows)
2638+       return  false ;
2639+   } else  if  (!VariantSubtracted && IsSigned) {
26222640    //  LV - C1 < C2 --> LV < C1 + C2
26232641    if  (computeOverflowForSignedAdd (InvariantOp, InvariantRHS, SQ) !=
26242642        llvm::OverflowResult::NeverOverflows)
26252643      return  false ;
2644+   } else  { //  !VariantSubtracted && !IsSigned
2645+     //  LV - C1 < C2 --> LV < C1 + C2
2646+     if  (computeOverflowForUnsignedAdd (InvariantOp, InvariantRHS, SQ) !=
2647+         llvm::OverflowResult::NeverOverflows)
2648+       return  false ;
26262649  }
26272650  auto  *Preheader = L.getLoopPreheader ();
26282651  assert (Preheader && " Loop is not in simplify form?"  );
26292652  IRBuilder<> Builder (Preheader->getTerminator ());
26302653  Value *NewCmpOp =
26312654      VariantSubtracted
26322655          ? Builder.CreateSub (InvariantOp, InvariantRHS, " invariant.op"  ,
2633-                               /* HasNUW*/   false , /* HasNSW*/   true )
2656+                               /* HasNUW*/   !IsSigned , /* HasNSW*/   IsSigned )
26342657          : Builder.CreateAdd (InvariantOp, InvariantRHS, " invariant.op"  ,
2635-                               /* HasNUW*/   false , /* HasNSW*/   true );
2658+                               /* HasNUW*/   !IsSigned , /* HasNSW*/   IsSigned );
26362659  ICmp.setPredicate (Pred);
26372660  ICmp.setOperand (0 , VariantOp);
26382661  ICmp.setOperand (1 , NewCmpOp);
@@ -2650,10 +2673,6 @@ static bool hoistAddSub(Instruction &I, Loop &L, ICFLoopSafetyInfo &SafetyInfo,
26502673  if  (!match (&I, m_ICmp (Pred, m_Value (LHS), m_Value (RHS))))
26512674    return  false ;
26522675
2653-   //  TODO: Support unsigned predicates?
2654-   if  (!ICmpInst::isSigned (Pred))
2655-     return  false ;
2656- 
26572676  //  Put variant operand to LHS position.
26582677  if  (L.isLoopInvariant (LHS)) {
26592678    std::swap (LHS, RHS);
0 commit comments