diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 7ebf265e17ba1f..27c411250d53c5 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -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(RVI)->isInBounds()) { + FlowsToReturn.insert(RVI->getOperand(0)); + continue; + } + return false; case Instruction::Select: { SelectInst *SI = cast(RVI); FlowsToReturn.insert(SI->getTrueValue()); diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll index 3d483f671b1af7..8d6f6a7c73f809 100644 --- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll +++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll @@ -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]] diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll index d9bdb6298ed0fd..ec5545b969e550 100644 --- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll +++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll @@ -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 ; @@ -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}