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
}
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) {
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