[llvm-branch-commits] [llvm] release/18.x: [FunctionAttrs] Fix incorrect nonnull inference for non-inbounds GEP (#91180) (PR #91286)
Tom Stellard via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu May 9 12:18:26 PDT 2024
https://github.com/tstellar updated https://github.com/llvm/llvm-project/pull/91286
>From 4a28f8e3c625e168c1cb9203150e3dc6495bb0fa Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Tue, 7 May 2024 09:47:28 +0900
Subject: [PATCH] [FunctionAttrs] Fix incorrect nonnull inference for
non-inbounds GEP (#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 https://github.com/llvm/llvm-project/issues/91177.
(cherry picked from commit f34d30cdae0f59698f660d5cc8fb993fb3441064)
---
llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 7 +++++-
.../Transforms/FunctionAttrs/nocapture.ll | 2 +-
llvm/test/Transforms/FunctionAttrs/nonnull.ll | 23 +++++++++++++++----
3 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 7ebf265e17ba1..27c411250d53c 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<GEPOperator>(RVI)->isInBounds()) {
+ FlowsToReturn.insert(RVI->getOperand(0));
+ continue;
+ }
+ return false;
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(RVI);
FlowsToReturn.insert(SI->getTrueValue());
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index 3d483f671b1af..8d6f6a7c73f80 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 d9bdb6298ed0f..ec5545b969e55 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}
More information about the llvm-branch-commits
mailing list