diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index afb0ea72b269c..fe9cca01a8f31 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -633,7 +633,7 @@ ArgumentAccessInfo getArgmentAccessInfo(const Instruction *I, [](Value *Length, std::optional Offset) -> std::optional { auto *ConstantLength = dyn_cast(Length); - if (ConstantLength && Offset) + if (ConstantLength && Offset && !ConstantLength->isNegative()) return ConstantRange( APInt(64, *Offset, true), APInt(64, *Offset + ConstantLength->getSExtValue(), true)); diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll index 2aa8385fe4ca7..c607fbeabb508 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(