Skip to content

[FunctionAttrs] Bail if initializes range overflows 64-bit signed int #137053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions llvm/lib/Transforms/IPO/FunctionAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,13 @@ 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);
bool Overflow;
APInt High = Low.sadd_ov(APInt(64, Size, true), Overflow);
// Bail if the range overflows signed 64-bit int.
if (Overflow)
return std::nullopt;
return ConstantRange(Low, High);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check isSignWrappedSet() on the result instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see this, thanks for pointing it out. Although I ended up just using APInt::sadd_ov

}
return std::nullopt;
};
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/Transforms/FunctionAttrs/initializes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading