Skip to content

Commit

Permalink
[FunctionAttrs] Fix incorrect nonnull inference for non-inbounds GEP (#…
Browse files Browse the repository at this point in the history
…91180)

For inbounds GEPs, if the source pointer is non-null, the result must
also be non-null. However, this does not hold for non-inbounds GEPs.

Fixes #91177.

(cherry picked from commit f34d30c)
  • Loading branch information
nikic authored and tstellar committed May 9, 2024
1 parent 0abb89a commit 4a28f8e
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 6 deletions.
7 changes: 6 additions & 1 deletion llvm/lib/Transforms/IPO/FunctionAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1186,10 +1186,15 @@ static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes,
switch (RVI->getOpcode()) {
// Extend the analysis by looking upwards.
case Instruction::BitCast:
case Instruction::GetElementPtr:
case Instruction::AddrSpaceCast:
FlowsToReturn.insert(RVI->getOperand(0));
continue;
case Instruction::GetElementPtr:
if (cast<GEPOperator>(RVI)->isInBounds()) {
FlowsToReturn.insert(RVI->getOperand(0));
continue;
}
return false;
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(RVI);
FlowsToReturn.insert(SI->getTrueValue());
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Transforms/FunctionAttrs/nocapture.ll
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ declare i32 @__gxx_personality_v0(...)

define ptr @lookup_bit(ptr %q, i32 %bitno) readnone nounwind {
; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; FNATTRS-LABEL: define nonnull ptr @lookup_bit
; FNATTRS-LABEL: define ptr @lookup_bit
; FNATTRS-SAME: (ptr [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR0]] {
; FNATTRS-NEXT: [[TMP:%.*]] = ptrtoint ptr [[Q]] to i32
; FNATTRS-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
Expand Down
23 changes: 19 additions & 4 deletions llvm/test/Transforms/FunctionAttrs/nonnull.ll
Original file line number Diff line number Diff line change
Expand Up @@ -905,26 +905,26 @@ define i1 @parent8(ptr %a, ptr %bogus1, ptr %b) personality ptr @esfp{
; FNATTRS-SAME: ptr nonnull [[A:%.*]], ptr nocapture readnone [[BOGUS1:%.*]], ptr nonnull [[B:%.*]]) #[[ATTR7]] personality ptr @esfp {
; FNATTRS-NEXT: entry:
; FNATTRS-NEXT: invoke void @use2nonnull(ptr [[A]], ptr [[B]])
; FNATTRS-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; FNATTRS-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; FNATTRS: cont:
; FNATTRS-NEXT: [[NULL_CHECK:%.*]] = icmp eq ptr [[B]], null
; FNATTRS-NEXT: ret i1 [[NULL_CHECK]]
; FNATTRS: exc:
; FNATTRS-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
; FNATTRS-NEXT: filter [0 x ptr] zeroinitializer
; FNATTRS-NEXT: filter [0 x ptr] zeroinitializer
; FNATTRS-NEXT: unreachable
;
; ATTRIBUTOR-LABEL: define i1 @parent8(
; ATTRIBUTOR-SAME: ptr nonnull [[A:%.*]], ptr nocapture nofree readnone [[BOGUS1:%.*]], ptr nonnull [[B:%.*]]) #[[ATTR8]] personality ptr @esfp {
; ATTRIBUTOR-NEXT: entry:
; ATTRIBUTOR-NEXT: invoke void @use2nonnull(ptr nonnull [[A]], ptr nonnull [[B]])
; ATTRIBUTOR-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; ATTRIBUTOR-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
; ATTRIBUTOR: cont:
; ATTRIBUTOR-NEXT: [[NULL_CHECK:%.*]] = icmp eq ptr [[B]], null
; ATTRIBUTOR-NEXT: ret i1 [[NULL_CHECK]]
; ATTRIBUTOR: exc:
; ATTRIBUTOR-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
; ATTRIBUTOR-NEXT: filter [0 x ptr] zeroinitializer
; ATTRIBUTOR-NEXT: filter [0 x ptr] zeroinitializer
; ATTRIBUTOR-NEXT: unreachable
;

Expand Down Expand Up @@ -1415,5 +1415,20 @@ define void @PR43833_simple(ptr %0, i32 %1) {
br i1 %11, label %7, label %8
}

define ptr @pr91177_non_inbounds_gep(ptr nonnull %arg) {
; FNATTRS-LABEL: define ptr @pr91177_non_inbounds_gep(
; FNATTRS-SAME: ptr nonnull readnone [[ARG:%.*]]) #[[ATTR0]] {
; FNATTRS-NEXT: [[RES:%.*]] = getelementptr i8, ptr [[ARG]], i64 -8
; FNATTRS-NEXT: ret ptr [[RES]]
;
; ATTRIBUTOR-LABEL: define ptr @pr91177_non_inbounds_gep(
; ATTRIBUTOR-SAME: ptr nofree nonnull readnone [[ARG:%.*]]) #[[ATTR0]] {
; ATTRIBUTOR-NEXT: [[RES:%.*]] = getelementptr i8, ptr [[ARG]], i64 -8
; ATTRIBUTOR-NEXT: ret ptr [[RES]]
;
%res = getelementptr i8, ptr %arg, i64 -8
ret ptr %res
}

attributes #0 = { null_pointer_is_valid }
attributes #1 = { nounwind willreturn}

0 comments on commit 4a28f8e

Please sign in to comment.