llvm-project/llvm/test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll
Yingwei Zheng 1228becf7d
[FuncAttrs] Deduce noundef attributes for return values (#76553)
This patch deduces `noundef` attributes for return values.
IIUC, a function returns `noundef` values iff all of its return values
are guaranteed not to be `undef` or `poison`.
Definition of `noundef` from LangRef:
```
noundef
This attribute applies to parameters and return values. If the value representation contains any 
undefined or poison bits, the behavior is undefined. Note that this does not refer to padding 
introduced by the type’s storage representation.
```
Alive2: https://alive2.llvm.org/ce/z/g8Eis6

Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=30dcc33c4ea3ab50397a7adbe85fe977d4a400bd&to=c5e8738d4bfbf1e97e3f455fded90b791f223d74&stat=instructions:u
|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|+0.01%|+0.01%|-0.01%|+0.01%|+0.03%|-0.04%|+0.01%|

The motivation of this patch is to reduce the number of `freeze` insts
and enable more optimizations.
2023-12-31 20:44:48 +08:00

43 lines
1.2 KiB
LLVM

; RUN: opt -passes=function-attrs -S < %s | FileCheck %s
; This checks for a previously existing iterator wraparound bug in
; FunctionAttrs, and in the process covers corner cases with varargs.
declare void @llvm.va_start(ptr)
declare void @llvm.va_end(ptr)
define void @va_func(ptr readonly %b, ...) readonly nounwind {
; CHECK-LABEL: define void @va_func(ptr nocapture readonly %b, ...)
entry:
%valist = alloca i8
call void @llvm.va_start(ptr %valist)
call void @llvm.va_end(ptr %valist)
%x = call i32 @caller(ptr %b)
ret void
}
define i32 @caller(ptr %x) {
; CHECK-LABEL: define noundef i32 @caller(ptr nocapture readonly %x)
entry:
call void(ptr,...) @va_func(ptr null, i32 0, i32 0, i32 0, ptr %x)
ret i32 42
}
define void @va_func2(ptr readonly %b, ...) {
; CHECK-LABEL: define void @va_func2(ptr nocapture readonly %b, ...)
entry:
%valist = alloca i8
call void @llvm.va_start(ptr %valist)
call void @llvm.va_end(ptr %valist)
%x = call i32 @caller(ptr %b)
ret void
}
define i32 @caller2(ptr %x, ptr %y) {
; CHECK-LABEL: define noundef i32 @caller2(ptr nocapture readonly %x, ptr %y)
entry:
call void(ptr,...) @va_func2(ptr %x, i32 0, i32 0, i32 0, ptr %y)
ret i32 42
}