From 65d838b6dde5d637ae5263fef46ceb9ce3dd6a93 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 23 Apr 2025 20:21:30 +0000 Subject: [PATCH 1/2] [FunctionAttrs] Bail if initializes range overflows 64-bit signed int Otherwise the range doesn't make sense since we interpret it as signed. Fixes #134115 --- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 8 ++++++-- llvm/test/Transforms/FunctionAttrs/initializes.ll | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index bbfed2ac2c090..5af68df6f4463 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -661,8 +661,12 @@ ArgumentAccessInfo getArgumentAccessInfo(const Instruction *I, auto TypeSize = DL.getTypeStoreSize(Ty); if (!TypeSize.isScalable() && Offset) { int64_t Size = TypeSize.getFixedValue(); - return ConstantRange(APInt(64, *Offset, true), - APInt(64, *Offset + Size, true)); + APInt Low(64, *Offset, true); + APInt High(64, *Offset + Size, true); + // Bail if the range overflows signed 64-bit int. + if (Low.sge(High)) + return std::nullopt; + return ConstantRange(Low, High); } return std::nullopt; }; diff --git a/llvm/test/Transforms/FunctionAttrs/initializes.ll b/llvm/test/Transforms/FunctionAttrs/initializes.ll index 861c61d683ae0..937595b5e9b74 100644 --- a/llvm/test/Transforms/FunctionAttrs/initializes.ll +++ b/llvm/test/Transforms/FunctionAttrs/initializes.ll @@ -635,3 +635,17 @@ define void @memset_offset_1_size_0(ptr %dst, ptr %src) { call void @llvm.memmove.p0.p0.i64(ptr %dst.1, ptr %src, i64 0, i1 false) ret void } + +; We should bail if the range overflows a singed 64-bit int. +define void @range_overflows_signed_64_bit_int(ptr %arg) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) +; CHECK-LABEL: define void @range_overflows_signed_64_bit_int( +; CHECK-SAME: ptr writeonly captures(none) [[ARG:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i8, ptr [[ARG]], i64 9223372036854775804 +; CHECK-NEXT: store i32 0, ptr [[GETELEMENTPTR]], align 4 +; CHECK-NEXT: ret void +; + %getelementptr = getelementptr i8, ptr %arg, i64 9223372036854775804 + store i32 0, ptr %getelementptr + ret void +} From f41fecf39e35e52866477f9ca30588d12f1ec4c3 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Wed, 23 Apr 2025 21:00:43 +0000 Subject: [PATCH 2/2] use sadd_ov --- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 5af68df6f4463..74e8a849803d2 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -662,9 +662,10 @@ ArgumentAccessInfo getArgumentAccessInfo(const Instruction *I, if (!TypeSize.isScalable() && Offset) { int64_t Size = TypeSize.getFixedValue(); APInt Low(64, *Offset, true); - APInt High(64, *Offset + Size, true); + bool Overflow; + APInt High = Low.sadd_ov(APInt(64, Size, true), Overflow); // Bail if the range overflows signed 64-bit int. - if (Low.sge(High)) + if (Overflow) return std::nullopt; return ConstantRange(Low, High); }