Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}