Skip to content

Commit 4502ea8

Browse files
committed
[InstCombine] More precise nuw preservation in ptrtoint of gep fold
We can transfer a nuw flag from the gep to the add. Additionally, the inbounds + nneg case can be relaxed to nusw + nneg. Finally, don't forget to pass the correct context instruction to SimplifyQuery.
1 parent c66e1d6 commit 4502ea8

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2070,7 +2070,9 @@ Instruction *InstCombinerImpl::visitPtrToInt(PtrToIntInst &CI) {
20702070
Base->getType() == Ty) {
20712071
Value *Offset = EmitGEPOffset(GEP);
20722072
auto *NewOp = BinaryOperator::CreateAdd(Base, Offset);
2073-
if (GEP->isInBounds() && isKnownNonNegative(Offset, SQ))
2073+
if (GEP->hasNoUnsignedWrap() ||
2074+
(GEP->hasNoUnsignedSignedWrap() &&
2075+
isKnownNonNegative(Offset, SQ.getWithInstruction(&CI))))
20742076
NewOp->setHasNoUnsignedWrap(true);
20752077
return NewOp;
20762078
}

llvm/test/Transforms/InstCombine/cast_ptr.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,43 @@ define i32 @ptr_add_in_int_not_inbounds(i32 %x, i32 %y) {
342342
ret i32 %r
343343
}
344344

345+
define i32 @ptr_add_in_int_nuw(i32 %x, i32 %y) {
346+
; CHECK-LABEL: @ptr_add_in_int_nuw(
347+
; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
348+
; CHECK-NEXT: ret i32 [[R]]
349+
;
350+
%ptr = inttoptr i32 %x to ptr
351+
%p2 = getelementptr nuw i8, ptr %ptr, i32 %y
352+
%r = ptrtoint ptr %p2 to i32
353+
ret i32 %r
354+
}
355+
356+
define i32 @ptr_add_in_int_nusw(i32 %x, i32 %y) {
357+
; CHECK-LABEL: @ptr_add_in_int_nusw(
358+
; CHECK-NEXT: [[R:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
359+
; CHECK-NEXT: ret i32 [[R]]
360+
;
361+
%ptr = inttoptr i32 %x to ptr
362+
%p2 = getelementptr nusw i8, ptr %ptr, i32 %y
363+
%r = ptrtoint ptr %p2 to i32
364+
ret i32 %r
365+
}
366+
367+
define i32 @ptr_add_in_int_nusw_nneg(i32 %x, i32 %y) {
368+
; CHECK-LABEL: @ptr_add_in_int_nusw_nneg(
369+
; CHECK-NEXT: [[NNEG:%.*]] = icmp sgt i32 [[Y:%.*]], -1
370+
; CHECK-NEXT: call void @llvm.assume(i1 [[NNEG]])
371+
; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], [[Y]]
372+
; CHECK-NEXT: ret i32 [[R]]
373+
;
374+
%nneg = icmp sge i32 %y, 0
375+
call void @llvm.assume(i1 %nneg)
376+
%ptr = inttoptr i32 %x to ptr
377+
%p2 = getelementptr nusw i8, ptr %ptr, i32 %y
378+
%r = ptrtoint ptr %p2 to i32
379+
ret i32 %r
380+
}
381+
345382
define i32 @ptr_add_in_int_const(i32 %x) {
346383
; CHECK-LABEL: @ptr_add_in_int_const(
347384
; CHECK-NEXT: [[R:%.*]] = add nuw i32 [[X:%.*]], 4096

0 commit comments

Comments
 (0)