diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4134,6 +4134,13 @@ return new ICmpInst(Pred, A, NewAdd); } } + Constant *Cst1, *Cst2; + if (match(B, m_ImmConstant(Cst1)) && match(D, m_ImmConstant(Cst2)) && + ICmpInst::isEquality(Pred)) { + Constant *Diff = ConstantExpr::getSub(Cst2, Cst1); + Value *NewAdd = Builder.CreateAdd(C, Diff); + return new ICmpInst(Pred, A, NewAdd); + } } // Analyze the case when either Op0 or Op1 is a sub instruction. diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -1565,9 +1565,8 @@ define <2 x i1> @icmp_add20_eq_add57_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @icmp_add20_eq_add57_vec_nonsplat( -; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %1 = add <2 x i32> %x, @@ -1614,9 +1613,8 @@ define <2 x i1> @icmp_sub57_ne_sub20_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @icmp_sub57_ne_sub20_vec_nonsplat( -; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i32> [[Y:%.*]], -; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i32> [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret <2 x i1> [[CMP]] ; %1 = add <2 x i32> %x, diff --git a/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll b/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll --- a/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll +++ b/llvm/test/Transforms/PhaseOrdering/loop-rotation-vs-common-code-hoisting.ll @@ -76,19 +76,21 @@ ; ROTATE-NEXT: [[CMP:%.*]] = icmp slt i32 [[WIDTH:%.*]], 1 ; ROTATE-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[FOR_COND_PREHEADER:%.*]] ; ROTATE: for.cond.preheader: -; ROTATE-NEXT: [[SUB:%.*]] = add nsw i32 [[WIDTH]], -1 ; ROTATE-NEXT: [[CMP13_NOT:%.*]] = icmp eq i32 [[WIDTH]], 1 -; ROTATE-NEXT: br i1 [[CMP13_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]] +; ROTATE-NEXT: br i1 [[CMP13_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY_PREHEADER:%.*]] +; ROTATE: for.body.preheader: +; ROTATE-NEXT: [[TMP0:%.*]] = add i32 [[WIDTH]], -2 +; ROTATE-NEXT: br label [[FOR_BODY:%.*]] ; ROTATE: for.cond.cleanup: ; ROTATE-NEXT: tail call void @f0() ; ROTATE-NEXT: tail call void @f2() ; ROTATE-NEXT: br label [[RETURN]] ; ROTATE: for.body: -; ROTATE-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ] +; ROTATE-NEXT: [[I_04:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_BODY_PREHEADER]] ] ; ROTATE-NEXT: tail call void @f0() ; ROTATE-NEXT: tail call void @f1() ; ROTATE-NEXT: [[INC]] = add nuw nsw i32 [[I_04]], 1 -; ROTATE-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[INC]], [[SUB]] +; ROTATE-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[I_04]], [[TMP0]] ; ROTATE-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]] ; ROTATE: return: ; ROTATE-NEXT: ret void