[llvm] [FunctionAttrs] Bail if initializes range overflows 64-bit signed int (PR #137053)

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 23 13:24:08 PDT 2025


https://github.com/aeubanks created https://github.com/llvm/llvm-project/pull/137053

Otherwise the range doesn't make sense since we interpret it as signed.

Fixes #134115

>From 65d838b6dde5d637ae5263fef46ceb9ce3dd6a93 Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Wed, 23 Apr 2025 20:21:30 +0000
Subject: [PATCH] [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
+}



More information about the llvm-commits mailing list