llvm-project/llvm/test/Transforms/Inline/launder.invariant.group.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

58 lines
2.0 KiB
LLVM

; RUN: opt -S -passes=inline < %s | FileCheck %s
; RUN: opt -S -O3 < %s | FileCheck %s
; RUN: opt -S -passes=inline -inline-threshold=1 < %s | FileCheck %s
%struct.A = type <{ ptr, i32, [4 x i8] }>
; This test checks if value returned from the launder is considered aliasing
; with its argument. Due to bug caused by handling launder in capture tracking
; sometimes it would be considered noalias.
; CHECK-LABEL: define {{(noundef )?}}i32 @bar(ptr noalias
define i32 @bar(ptr noalias) {
; CHECK-NOT: noalias
%2 = call ptr @llvm.launder.invariant.group.p0(ptr %0)
%3 = getelementptr inbounds i8, ptr %2, i64 8
store i32 42, ptr %3, align 8
%4 = getelementptr inbounds %struct.A, ptr %0, i64 0, i32 1
%5 = load i32, ptr %4, align 8
ret i32 %5
}
; CHECK-LABEL: define {{(noundef )?}}i32 @foo(ptr noalias
define i32 @foo(ptr noalias) {
; CHECK-NOT: call i32 @bar(
; CHECK-NOT: !noalias
%2 = tail call i32 @bar(ptr %0)
ret i32 %2
}
; This test checks if invariant group intrinsics have zero cost for inlining.
; CHECK-LABEL: define ptr @caller(ptr
define ptr @caller(ptr %p) {
; CHECK-NOT: call ptr @lot_of_launders_and_strips
%a1 = call ptr @lot_of_launders_and_strips(ptr %p)
%a2 = call ptr @lot_of_launders_and_strips(ptr %a1)
%a3 = call ptr @lot_of_launders_and_strips(ptr %a2)
%a4 = call ptr @lot_of_launders_and_strips(ptr %a3)
ret ptr %a4
}
define ptr @lot_of_launders_and_strips(ptr %p) {
%a1 = call ptr @llvm.launder.invariant.group.p0(ptr %p)
%a2 = call ptr @llvm.launder.invariant.group.p0(ptr %a1)
%a3 = call ptr @llvm.launder.invariant.group.p0(ptr %a2)
%a4 = call ptr @llvm.launder.invariant.group.p0(ptr %a3)
%s1 = call ptr @llvm.strip.invariant.group.p0(ptr %a4)
%s2 = call ptr @llvm.strip.invariant.group.p0(ptr %s1)
%s3 = call ptr @llvm.strip.invariant.group.p0(ptr %s2)
%s4 = call ptr @llvm.strip.invariant.group.p0(ptr %s3)
ret ptr %s4
}
declare ptr @llvm.launder.invariant.group.p0(ptr)
declare ptr @llvm.strip.invariant.group.p0(ptr)