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

60 lines
3.2 KiB
LLVM

; Check the nonflattened part of the ctxsplit profile will be read in thinlto
; postlink phase while flattened part of the ctxsplit profile will not be read.
; RUN: opt < %s -passes='thinlto<O2>' -pgo-kind=pgo-sample-use-pipeline -use-profiled-call-graph=0 -profile-file=%S/Inputs/ctxsplit.extbinary.afdo -S | FileCheck %s --check-prefix=POSTLINK
;
; Check both the flattened and nonflattened parts of the ctxsplit profile will
; be read in thinlto prelink phase.
; RUN: opt < %s -passes='thinlto-pre-link<O2>' -pgo-kind=pgo-sample-use-pipeline -use-profiled-call-graph=0 -profile-file=%S/Inputs/ctxsplit.extbinary.afdo -S | FileCheck %s --check-prefix=PRELINK
;
; Check both the flattened and nonflattened parts of the ctxsplit profile will
; be read in non-thinlto mode.
; RUN: opt < %s -passes='default<O2>' -pgo-kind=pgo-sample-use-pipeline -use-profiled-call-graph=0 -profile-file=%S/Inputs/ctxsplit.extbinary.afdo -S | FileCheck %s --check-prefix=NOTHINLTO
; POSTLINK: define dso_local noundef i32 @goo() {{.*}} !prof ![[ENTRY1:[0-9]+]] {
; POSTLINK: define dso_local noundef i32 @foo() {{.*}} !prof ![[ENTRY2:[0-9]+]] {
; POSTLINK: ![[ENTRY1]] = !{!"function_entry_count", i64 1001}
; POSTLINK: ![[ENTRY2]] = !{!"function_entry_count", i64 -1}
; PRELINK: define dso_local noundef i32 @goo() {{.*}} !prof ![[ENTRY1:[0-9]+]] {
; PRELINK: define dso_local noundef i32 @foo() {{.*}} !prof ![[ENTRY2:[0-9]+]] {
; PRELINK: ![[ENTRY1]] = !{!"function_entry_count", i64 1001}
; PRELINK: ![[ENTRY2]] = !{!"function_entry_count", i64 3001}
; NOTHINLTO: define dso_local noundef i32 @goo() {{.*}} !prof ![[ENTRY1:[0-9]+]] {
; NOTHINLTO: define dso_local noundef i32 @foo() {{.*}} !prof ![[ENTRY2:[0-9]+]] {
; NOTHINLTO: ![[ENTRY1]] = !{!"function_entry_count", i64 1001}
; NOTHINLTO: ![[ENTRY2]] = !{!"function_entry_count", i64 3001}
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: norecurse nounwind readnone uwtable
define dso_local i32 @goo() #0 !dbg !10 {
entry:
ret i32 -1, !dbg !11
}
; Function Attrs: norecurse nounwind readnone uwtable
define dso_local i32 @foo() #0 !dbg !7 {
entry:
ret i32 -1, !dbg !9
}
attributes #0 = { "use-sample-profile" }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 345241)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "a.c", directory: "")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 8.0.0 (trunk 345241)"}
!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: true, unit: !0, retainedNodes: !2)
!8 = !DISubroutineType(types: !2)
!9 = !DILocation(line: 2, column: 3, scope: !7)
!10 = distinct !DISubprogram(name: "goo", scope: !1, file: !1, line: 8, type: !8, isLocal: false, isDefinition: true, scopeLine: 8, isOptimized: true, unit: !0, retainedNodes: !2)
!11 = !DILocation(line: 10, column: 3, scope: !10)