[llvm] Skip negative length while inferring initializes attr (PR #120874)

Haopeng Liu via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 22 09:35:09 PST 2024


https://github.com/haopliu updated https://github.com/llvm/llvm-project/pull/120874

>From 3c5d0c41f288d09fd798039fabb882bf1a8ffeca Mon Sep 17 00:00:00 2001
From: Haopeng Liu <haopliu at google.com>
Date: Sun, 22 Dec 2024 07:11:52 +0000
Subject: [PATCH 1/2] Skip neg length while inferring initializes attr

---
 llvm/lib/Transforms/IPO/FunctionAttrs.cpp         |  5 ++++-
 llvm/test/Transforms/FunctionAttrs/initializes.ll | 11 +++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index afb0ea72b269c8..0a83bb1cd60535 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -633,10 +633,13 @@ ArgumentAccessInfo getArgmentAccessInfo(const Instruction *I,
       [](Value *Length,
          std::optional<int64_t> Offset) -> std::optional<ConstantRange> {
     auto *ConstantLength = dyn_cast<ConstantInt>(Length);
-    if (ConstantLength && Offset)
+    if (ConstantLength && Offset) {
+      if (ConstantLength->getSExtValue() < 0)
+        return std::nullopt;
       return ConstantRange(
           APInt(64, *Offset, true),
           APInt(64, *Offset + ConstantLength->getSExtValue(), true));
+    }
     return std::nullopt;
   };
   if (auto *SI = dyn_cast<StoreInst>(I)) {
diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll
index 2aa8385fe4ca7b..c607fbeabb5087 100644
--- a/llvm/test/Transforms/FunctionAttrs/initializes.ll
+++ b/llvm/test/Transforms/FunctionAttrs/initializes.ll
@@ -423,6 +423,17 @@ define void @memset_offset(ptr %p) {
   ret void
 }
 
+define void @memset_neg(ptr %p) {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
+; CHECK-LABEL: define void @memset_neg(
+; CHECK-SAME: ptr nocapture writeonly [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr [[P]], i8 2, i64 -1, i1 false)
+; CHECK-NEXT:    ret void
+;
+  call void @llvm.memset(ptr %p, i8 2, i64 -1, i1 false)
+  ret void
+}
+
 define void @memset_volatile(ptr %p) {
 ; CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(argmem: write)
 ; CHECK-LABEL: define void @memset_volatile(

>From b32b679b7e8cfbe435bdd23374ccb4e7ae2d54a5 Mon Sep 17 00:00:00 2001
From: Haopeng Liu <haopliu at google.com>
Date: Sun, 22 Dec 2024 17:34:54 +0000
Subject: [PATCH 2/2] Update to use ConstantInt::isNegative()

---
 llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 0a83bb1cd60535..fe9cca01a8f31f 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -633,13 +633,10 @@ ArgumentAccessInfo getArgmentAccessInfo(const Instruction *I,
       [](Value *Length,
          std::optional<int64_t> Offset) -> std::optional<ConstantRange> {
     auto *ConstantLength = dyn_cast<ConstantInt>(Length);
-    if (ConstantLength && Offset) {
-      if (ConstantLength->getSExtValue() < 0)
-        return std::nullopt;
+    if (ConstantLength && Offset && !ConstantLength->isNegative())
       return ConstantRange(
           APInt(64, *Offset, true),
           APInt(64, *Offset + ConstantLength->getSExtValue(), true));
-    }
     return std::nullopt;
   };
   if (auto *SI = dyn_cast<StoreInst>(I)) {



More information about the llvm-commits mailing list