llvm-project/llvm/test/ThinLTO/X86/index-const-prop.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

50 lines
2.2 KiB
LLVM

; Check constant propagation in thinlto combined summary. This allows us to do 2 things:
; 1. Internalize global definition which is not used externally if all accesses to it are read-only
; 2. Make a local copy of internal definition if all accesses to it are readonly. This allows constant
; folding it during optimziation phase.
; -stats requires asserts
; REQUIRES: asserts
; RUN: opt -module-summary %s -o %t1.bc
; RUN: opt -module-summary %p/Inputs/index-const-prop.ll -o %t2.bc
; RUN: llvm-lto -thinlto-action=thinlink -o %t3.index.bc %t1.bc %t2.bc
; RUN: llvm-lto -thinlto-action=import -exported-symbol=main %t1.bc -thinlto-index=%t3.index.bc -o %t1.imported.bc -stats 2>&1 | FileCheck %s --check-prefix=STATS
; RUN: llvm-dis %t1.imported.bc -o - | FileCheck %s --check-prefix=IMPORT
; RUN: llvm-lto -thinlto-action=optimize %t1.imported.bc -o - | llvm-dis - -o - | FileCheck %s --check-prefix=OPTIMIZE
; STATS: 2 module-summary-index - Number of live global variables marked read only
; Check that we don't internalize gBar when it is exported
; RUN: llvm-lto -thinlto-action=import -exported-symbol main -exported-symbol gBar %t1.bc -thinlto-index=%t3.index.bc -o %t1.imported2.bc
; RUN: llvm-dis %t1.imported2.bc -o - | FileCheck %s --check-prefix=IMPORT2
; IMPORT: @gBar = internal local_unnamed_addr global i32 2, align 4, !dbg !0
; IMPORT-NEXT: @gFoo.llvm.0 = internal unnamed_addr global i32 1, align 4, !dbg !5
; IMPORT: !DICompileUnit({{.*}})
; OPTIMIZE: define noundef i32 @main
; OPTIMIZE-NEXT: ret i32 3
; IMPORT2: @gBar = available_externally local_unnamed_addr global i32 2, align 4, !dbg !0
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
@gBar = external global i32
; Should not be counted in the stats of live read only variables since it is
; dead and will be dropped anyway.
@gDead = internal unnamed_addr global i32 1, align 4
define i32 @main() local_unnamed_addr {
%call = tail call i32 @foo()
%call1 = tail call i32 @bar()
%add = add nsw i32 %call1, %call
ret i32 %add
}
declare i32 @foo(...) local_unnamed_addr
declare i32 @bar(...) local_unnamed_addr