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 @@ -3917,11 +3917,15 @@ APInt AP2Abs = C2->getValue().abs(); if (AP1Abs.uge(AP2Abs)) { ConstantInt *C3 = Builder.getInt(AP1 - AP2); - Value *NewAdd = Builder.CreateNSWAdd(A, C3); + bool HasNUW = BO0->hasNoUnsignedWrap() && C3->getValue().ule(AP1); + bool HasNSW = BO0->hasNoSignedWrap(); + Value *NewAdd = Builder.CreateAdd(A, C3, "", HasNUW, HasNSW); return new ICmpInst(Pred, NewAdd, C); } else { ConstantInt *C3 = Builder.getInt(AP2 - AP1); - Value *NewAdd = Builder.CreateNSWAdd(C, C3); + bool HasNUW = BO1->hasNoUnsignedWrap() && C3->getValue().ule(AP2); + bool HasNSW = BO1->hasNoSignedWrap(); + Value *NewAdd = Builder.CreateAdd(C, C3, "", HasNUW, HasNSW); return new ICmpInst(Pred, A, NewAdd); } } diff --git a/llvm/test/Transforms/InstCombine/icmp-add.ll b/llvm/test/Transforms/InstCombine/icmp-add.ll --- a/llvm/test/Transforms/InstCombine/icmp-add.ll +++ b/llvm/test/Transforms/InstCombine/icmp-add.ll @@ -666,7 +666,7 @@ define i1 @without_nsw_nuw(i8 %x, i8 %y) { ; CHECK-LABEL: @without_nsw_nuw( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], 2 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: ret i1 [[TOBOOL]] ; @@ -678,7 +678,7 @@ define i1 @with_nsw_nuw(i8 %x, i8 %y) { ; CHECK-LABEL: @with_nsw_nuw( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[X:%.*]], 2 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: ret i1 [[TOBOOL]] ; @@ -702,7 +702,7 @@ define i1 @with_nsw_small(i8 %x, i8 %y) { ; CHECK-LABEL: @with_nsw_small( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[Y:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 2 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[TOBOOL]] ; @@ -714,7 +714,7 @@ define i1 @with_nuw_large(i8 %x, i8 %y) { ; CHECK-LABEL: @with_nuw_large( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 2 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[Y:%.*]] ; CHECK-NEXT: ret i1 [[TOBOOL]] ; @@ -726,7 +726,7 @@ define i1 @with_nuw_small(i8 %x, i8 %y) { ; CHECK-LABEL: @with_nuw_small( -; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[Y:%.*]], 2 +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], 2 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[X:%.*]] ; CHECK-NEXT: ret i1 [[TOBOOL]] ; @@ -735,3 +735,15 @@ %tobool = icmp eq i8 %t2, %t1 ret i1 %tobool } + +define i1 @with_nuw_large_negative(i8 %x, i8 %y) { +; CHECK-LABEL: @with_nuw_large_negative( +; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -2 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[TMP1]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[TOBOOL]] +; + %t1 = add nuw i8 %x, -37 + %t2 = add i8 %y, -35 + %tobool = icmp eq i8 %t2, %t1 + ret i1 %tobool +}