diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 7b1268939e9c4b..8f83047020936f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -2070,7 +2070,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) { Base->getType() == Ty) { Value *Offset = EmitGEPOffset(GEP); auto *NewOp = BinaryOperator::CreateAdd(Base, Offset); - if (GEP->isInBounds() && isKnownNonNegative(Offset, SQ)) + if (GEP->hasNoUnsignedWrap() || + (GEP->hasNoUnsignedSignedWrap() && + isKnownNonNegative(Offset, SQ.getWithInstruction(&CI)))) NewOp->setHasNoUnsignedWrap(true); return NewOp; } diff --git a/llvm/test/Transforms/InstCombine/cast_ptr.ll b/llvm/test/Transforms/InstCombine/cast_ptr.ll index 786ea876ddea7a..9f2d128ecc3771 100644 --- a/llvm/test/Transforms/InstCombine/cast_ptr.ll +++ b/llvm/test/Transforms/InstCombine/cast_ptr.ll @@ -342,6 +342,43 @@ define i32 @ptr_add_in_int_not_inbounds(i32 %x, i32 %y) { ret i32 %r } +define i32 @ptr_add_in_int_nuw(i32 %x, i32 %y) { +; CHECK-LABEL: @ptr_add_in_int_nuw( +; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i32 [[R]] +; + %ptr = inttoptr i32 %x to ptr + %p2 = getelementptr nuw i8, ptr %ptr, i32 %y + %r = ptrtoint ptr %p2 to i32 + ret i32 %r +} + +define i32 @ptr_add_in_int_nusw(i32 %x, i32 %y) { +; CHECK-LABEL: @ptr_add_in_int_nusw( +; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i32 [[R]] +; + %ptr = inttoptr i32 %x to ptr + %p2 = getelementptr nusw i8, ptr %ptr, i32 %y + %r = ptrtoint ptr %p2 to i32 + ret i32 %r +} + +define i32 @ptr_add_in_int_nusw_nneg(i32 %x, i32 %y) { +; CHECK-LABEL: @ptr_add_in_int_nusw_nneg( +; CHECK-NEXT: [[NNEG:%.*]] = icmp sgt i32 [[Y:%.*]], -1 +; CHECK-NEXT: call void @llvm.assume(i1 [[NNEG]]) +; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y]] +; CHECK-NEXT: ret i32 [[R]] +; + %nneg = icmp sge i32 %y, 0 + call void @llvm.assume(i1 %nneg) + %ptr = inttoptr i32 %x to ptr + %p2 = getelementptr nusw i8, ptr %ptr, i32 %y + %r = ptrtoint ptr %p2 to i32 + ret i32 %r +} + define i32 @ptr_add_in_int_const(i32 %x) { ; CHECK-LABEL: @ptr_add_in_int_const( ; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], 4096