Skip to content

Commit

Permalink
[InstSimplify] Allow gep inbounds x, 0 -> x in non-refining op replac…
Browse files Browse the repository at this point in the history
…ement

After the semantics change from https://reviews.llvm.org/D154051,
gep inbounds x, 0 can no longer produce poison. As such, we can
also perform this fold during non-refining operand replacement
and avoid unnecessary drops of the inbounds flag.

The online alive2 version has not been update to the new
semantics yet, but we can use the following proof locally:

    define ptr @src(ptr %base, i64 %offset) {
      %cmp = icmp eq i64 %offset, 0
      %gep = getelementptr inbounds i8, ptr %base, i64 %offset
      %sel = select i1 %cmp, ptr %base, ptr %gep
      ret ptr %sel
    }

    define ptr @tgt(ptr %base, i64 %offset) {
      %gep = getelementptr inbounds i8, ptr %base, i64 %offset
      ret ptr %gep
    }
  • Loading branch information
nikic committed Jul 14, 2023
1 parent 91b8481 commit 5475441
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 6 deletions.
8 changes: 4 additions & 4 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4320,10 +4320,10 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
return RepOp;
}

if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
// getelementptr x, 0 -> x
if (NewOps.size() == 2 && match(NewOps[1], m_Zero()) &&
!GEP->isInBounds())
if (isa<GetElementPtrInst>(I)) {
// getelementptr x, 0 -> x.
// This never returns poison, even if inbounds is set.
if (NewOps.size() == 2 && match(NewOps[1], m_Zero()))
return NewOps[0];
}
} else if (MaxRecurse) {
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2892,10 +2892,9 @@ define i32 @select_replacement_loop2(i32 %arg, i32 %arg2) {
ret i32 %sel
}

; TODO: Dropping the inbounds flag should not be necessary for this fold.
define ptr @select_replacement_gep_inbounds(ptr %base, i64 %offset) {
; CHECK-LABEL: @select_replacement_gep_inbounds(
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]]
; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i8, ptr [[BASE:%.*]], i64 [[OFFSET:%.*]]
; CHECK-NEXT: ret ptr [[GEP]]
;
%cmp = icmp eq i64 %offset, 0
Expand Down

0 comments on commit 5475441

Please sign in to comment.