Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -3913,6 +3913,11 @@ if (Value *V = simplifyICmpWithDominatingAssume(Pred, LHS, RHS, Q)) return V; + std::optional Checked = + isImpliedByDomCondition(Pred, LHS, RHS, Q.CxtI, Q.DL); + if (Checked && *Checked == true) + return getTrue(ITy); + // Simplify comparisons of related pointers using a powerful, recursive // GEP-walk when we have target data available.. if (LHS->getType()->isPointerTy()) Index: llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll =================================================================== --- llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll +++ llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll @@ -108,13 +108,39 @@ ret i64 %out } -; TODO: https://alive2.llvm.org/ce/z/eHkgRa +; https://alive2.llvm.org/ce/z/eHkgRa define noundef i8 @urem_with_dominating_condition(i8 %x, i8 %n) { ; CHECK-LABEL: @urem_with_dominating_condition( ; CHECK-NEXT: start: -; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]] +; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]] +; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[X_FR]], [[N:%.*]] ; CHECK-NEXT: br i1 [[COND]], label [[DOTBB0:%.*]], label [[DOTBB1:%.*]] ; CHECK: .bb0: +; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1 +; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i8 [[ADD]], [[N]] +; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP0]], i8 0, i8 [[ADD]] +; CHECK-NEXT: ret i8 [[OUT]] +; CHECK: .bb1: +; CHECK-NEXT: ret i8 0 +; +start: + %cond = icmp ult i8 %x, %n + br i1 %cond, label %.bb0, label %.bb1 ; Should also works for a dominating condition +.bb0: + %add = add i8 %x, 1 + %out = urem i8 %add, %n + ret i8 %out +.bb1: + ret i8 0 +} + +; Negative test +define noundef i8 @urem_with_opposite_condition(i8 %x, i8 %n) { +; CHECK-LABEL: @urem_with_opposite_condition( +; CHECK-NEXT: start: +; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[X:%.*]], [[N:%.*]] +; CHECK-NEXT: br i1 [[COND]], label [[DOTBB1:%.*]], label [[DOTBB0:%.*]] +; CHECK: .bb0: ; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1 ; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]] ; CHECK-NEXT: ret i8 [[OUT]] @@ -123,7 +149,7 @@ ; start: %cond = icmp ult i8 %x, %n - br i1 %cond, label %.bb0, label %.bb1 ; Should also works for a dominating condition + br i1 %cond, label %.bb1, label %.bb0 ; Revert the condition .bb0: %add = add i8 %x, 1 %out = urem i8 %add, %n