[lld] [clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2024-01-01 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

> Can you please fix or revert 
> https://lab.llvm.org/buildbot/#/builders/74/builds/24592 ?

Should be fixed by 
https://github.com/llvm/llvm-project/commit/7e405eb722e40c79b7726201d0f76b5dab34ba0f.
https://lab.llvm.org/buildbot/#/builders/74/builds/24613

https://github.com/llvm/llvm-project/pull/76553
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[lld] [clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-31 Thread Yingwei Zheng via cfe-commits

dtcxzyw wrote:

> Failed Tests (3):
  LLVM :: CodeGen/BPF/loop-exit-cond.ll
  LLVM :: CodeGen/NVPTX/nvvm-reflect-opaque.ll
  LLVM :: CodeGen/NVPTX/nvvm-reflect.ll

https://github.com/llvm/llvm-project/pull/76553
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-29 Thread Nikita Popov via cfe-commits


@@ -1279,6 +1280,43 @@ static void addNonNullAttrs(const SCCNodeSet ,
   }
 }
 
+/// Deduce noundef attributes for the SCC.
+static void addNoUndefAttrs(const SCCNodeSet ,
+SmallSet ) {
+  // Check each function in turn, determining which functions return noundef
+  // values.
+  for (Function *F : SCCNodes) {
+// Already noundef.
+if (F->getAttributes().hasRetAttr(Attribute::NoUndef))
+  continue;
+
+// We can infer and propagate function attributes only when we know that 
the
+// definition we'll get at link time is *exactly* the definition we see 
now.
+// For more details, see GlobalValue::mayBeDerefined.
+if (!F->hasExactDefinition())
+  return;
+
+if (F->getReturnType()->isVoidTy())
+  continue;
+
+bool HasAnyUndefs = false;
+for (BasicBlock  : *F)
+  if (auto *Ret = dyn_cast(BB.getTerminator())) {
+// TODO: performs context-sensitive analysis?

nikic wrote:

```suggestion
// TODO: perform context-sensitive analysis?
```

https://github.com/llvm/llvm-project/pull/76553
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-28 Thread via cfe-commits

llvmbot wrote:



@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-clang

Author: Yingwei Zheng (dtcxzyw)


Changes

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=7f69c8b3a6c02ea32fefb16c2016dfa1ba994858to=1dafc281ff8c04bb0a968fb3d898f08876dc59e0stat=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.00%|+0.03%|+0.02%|+0.01%|

The motivation of this patch is to reduce the number of `freeze` insts and 
enable more optimizations.
Example:
```
diff --git a/bench/flac/optimized/replaygain.c.ll 
b/bench/flac/optimized/replaygain.c.ll
index fa826475..413bd717 100644
--- a/bench/flac/optimized/replaygain.c.ll
+++ b/bench/flac/optimized/replaygain.c.ll
@@ -63,7 +63,7 @@ entry:
 declare i32 @InitGainAnalysis(i64 noundef) local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define dso_local i32 @grabbag__replaygain_analyze(ptr nocapture 
noundef readonly %input, i32 noundef %is_stereo, i32 noundef %bps, i32 noundef 
%samples) local_unnamed_addr #0 {
+define dso_local noundef i32 @grabbag__replaygain_analyze(ptr 
nocapture noundef readonly %input, i32 noundef %is_stereo, i32 noundef %bps, 
i32 noundef %samples) local_unnamed_addr #0 {
 entry:
   %cmp = icmp eq i32 %bps, 16
   br i1 %cmp, label %if.then, label %if.else71
@@ -337,7 +337,7 @@ entry:
 declare float @GetTitleGain() local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define dso_local ptr @grabbag__replaygain_analyze_file(ptr noundef 
%filename, ptr nocapture noundef writeonly %title_gain, ptr nocapture noundef 
writeonly %title_peak) local_unnamed_addr #0 {
+define dso_local noundef ptr @grabbag__replaygain_analyze_file(ptr 
noundef %filename, ptr nocapture noundef writeonly %title_gain, ptr nocapture 
noundef writeonly %title_peak) local_unnamed_addr #0 {
 entry:
   %instance = alloca %struct.DecoderInstance, align 4
   %call = tail call ptr @FLAC__stream_decoder_new() #15
@@ -392,7 +392,7 @@ declare i32 @FLAC__stream_decoder_set_metadata_respond(ptr noundef, i32 noundef)
 declare i32 @FLAC__stream_decoder_init_file(ptr noundef, ptr noundef, 
ptr noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define internal i32 @write_callback_(ptr nocapture readnone %decoder, 
ptr nocapture noundef readonly %frame, ptr nocapture noundef readonly %buffer, 
ptr nocapture noundef %client_data) #0 {
+define internal noundef i32 @write_callback_(ptr nocapture readnone 
%decoder, ptr nocapture noundef readonly %frame, ptr nocapture noundef readonly 
%buffer, ptr nocapture noundef %client_data) #0 {
 entry:
   %bits_per_sample1 = getelementptr inbounds %struct.FLAC__FrameHeader, ptr 
%frame, i64 0, i32 4
   %0 = load i32, ptr %bits_per_sample1, align 8
@@ -429,23 +429,16 @@ land.lhs.true14:  ; preds 
= %land.lhs.true11
   %cmp16 = icmp eq i32 %2, %8
   br i1 %cmp16, label %if.end, label %if.end.thread
 
-if.end.thread:; preds = %land.lhs.true, 
%land.lhs.true14, %land.lhs.true11, %land.lhs.true8, %entry
-  store i32 1, ptr %error, align 4
-  br label %9
-
 if.end:   ; preds = %land.lhs.true14
   %conv = zext i1 %cmp to i32
   %call = tail call i32 @grabbag__replaygain_analyze(ptr noundef 
%buffer, i32 noundef %conv, i32 noundef %0, i32 noundef %3), !range !14
-  %call.fr = freeze i32 %call
-  %lnot.ext = xor i32 %call.fr, 1
-  store i32 %lnot.ext, ptr %error, align 4
-  %tobool22.not = icmp ne i32 %lnot.ext, 0
-  %spec.select = zext i1 %tobool22.not to i32
-  br label %9
-
-9:; preds = %if.end, 
%if.end.thread
-  %10 = phi i32 [ 1, %if.end.thread ], [ %spec.select, %if.end ]
-  ret i32 %10
+  %lnot.ext = xor i32 %call, 1
+  br label %if.end.thread
+
+if.end.thread:; preds = %entry, 
%land.lhs.true8, %land.lhs.true11, %land.lhs.true14, %land.lhs.true, %if.end
+  %storemerge = phi i32 [ %lnot.ext, %if.end ], [ 1, %land.lhs.true ], [ 1, 
%land.lhs.true14 ], [ 1, %land.lhs.true11 ], [ 1, %land.lhs.true8 ], [ 1, 
%entry ]
+  store i32 %storemerge, ptr %error, align 4
+  ret i32 %storemerge
 }
 
 ; Function Attrs: nounwind sspstrong uwtable

```

---

Patch is 55.83 KiB, truncated to 20.00 KiB below, full version: 

[clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)

2023-12-28 Thread Yingwei Zheng via cfe-commits

https://github.com/dtcxzyw created 
https://github.com/llvm/llvm-project/pull/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=7f69c8b3a6c02ea32fefb16c2016dfa1ba994858=1dafc281ff8c04bb0a968fb3d898f08876dc59e0=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.00%|+0.03%|+0.02%|+0.01%|

The motivation of this patch is to reduce the number of `freeze` insts and 
enable more optimizations.
Example:
```
diff --git a/bench/flac/optimized/replaygain.c.ll 
b/bench/flac/optimized/replaygain.c.ll
index fa826475..413bd717 100644
--- a/bench/flac/optimized/replaygain.c.ll
+++ b/bench/flac/optimized/replaygain.c.ll
@@ -63,7 +63,7 @@ entry:
 declare i32 @InitGainAnalysis(i64 noundef) local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define dso_local i32 @grabbag__replaygain_analyze(ptr nocapture noundef 
readonly %input, i32 noundef %is_stereo, i32 noundef %bps, i32 noundef 
%samples) local_unnamed_addr #0 {
+define dso_local noundef i32 @grabbag__replaygain_analyze(ptr nocapture 
noundef readonly %input, i32 noundef %is_stereo, i32 noundef %bps, i32 noundef 
%samples) local_unnamed_addr #0 {
 entry:
   %cmp = icmp eq i32 %bps, 16
   br i1 %cmp, label %if.then, label %if.else71
@@ -337,7 +337,7 @@ entry:
 declare float @GetTitleGain() local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define dso_local ptr @grabbag__replaygain_analyze_file(ptr noundef %filename, 
ptr nocapture noundef writeonly %title_gain, ptr nocapture noundef writeonly 
%title_peak) local_unnamed_addr #0 {
+define dso_local noundef ptr @grabbag__replaygain_analyze_file(ptr noundef 
%filename, ptr nocapture noundef writeonly %title_gain, ptr nocapture noundef 
writeonly %title_peak) local_unnamed_addr #0 {
 entry:
   %instance = alloca %struct.DecoderInstance, align 4
   %call = tail call ptr @FLAC__stream_decoder_new() #15
@@ -392,7 +392,7 @@ declare i32 @FLAC__stream_decoder_set_metadata_respond(ptr 
noundef, i32 noundef)
 declare i32 @FLAC__stream_decoder_init_file(ptr noundef, ptr noundef, ptr 
noundef, ptr noundef, ptr noundef, ptr noundef) local_unnamed_addr #1
 
 ; Function Attrs: nounwind sspstrong uwtable
-define internal i32 @write_callback_(ptr nocapture readnone %decoder, ptr 
nocapture noundef readonly %frame, ptr nocapture noundef readonly %buffer, ptr 
nocapture noundef %client_data) #0 {
+define internal noundef i32 @write_callback_(ptr nocapture readnone %decoder, 
ptr nocapture noundef readonly %frame, ptr nocapture noundef readonly %buffer, 
ptr nocapture noundef %client_data) #0 {
 entry:
   %bits_per_sample1 = getelementptr inbounds %struct.FLAC__FrameHeader, ptr 
%frame, i64 0, i32 4
   %0 = load i32, ptr %bits_per_sample1, align 8
@@ -429,23 +429,16 @@ land.lhs.true14:  ; preds 
= %land.lhs.true11
   %cmp16 = icmp eq i32 %2, %8
   br i1 %cmp16, label %if.end, label %if.end.thread
 
-if.end.thread:; preds = %land.lhs.true, 
%land.lhs.true14, %land.lhs.true11, %land.lhs.true8, %entry
-  store i32 1, ptr %error, align 4
-  br label %9
-
 if.end:   ; preds = %land.lhs.true14
   %conv = zext i1 %cmp to i32
   %call = tail call i32 @grabbag__replaygain_analyze(ptr noundef %buffer, i32 
noundef %conv, i32 noundef %0, i32 noundef %3), !range !14
-  %call.fr = freeze i32 %call
-  %lnot.ext = xor i32 %call.fr, 1
-  store i32 %lnot.ext, ptr %error, align 4
-  %tobool22.not = icmp ne i32 %lnot.ext, 0
-  %spec.select = zext i1 %tobool22.not to i32
-  br label %9
-
-9:; preds = %if.end, 
%if.end.thread
-  %10 = phi i32 [ 1, %if.end.thread ], [ %spec.select, %if.end ]
-  ret i32 %10
+  %lnot.ext = xor i32 %call, 1
+  br label %if.end.thread
+
+if.end.thread:; preds = %entry, 
%land.lhs.true8, %land.lhs.true11, %land.lhs.true14, %land.lhs.true, %if.end
+  %storemerge = phi i32 [ %lnot.ext, %if.end ], [ 1, %land.lhs.true ], [ 1, 
%land.lhs.true14 ], [ 1, %land.lhs.true11 ], [ 1, %land.lhs.true8 ], [ 1, 
%entry ]
+  store i32 %storemerge, ptr %error, align 4
+  ret i32 %storemerge
 }
 
 ; Function Attrs: nounwind sspstrong uwtable

```

>From 30dcc33c4ea3ab50397a7adbe85fe977d4a400bd Mon Sep 17 00:00:00 2001
From: Yingwei Zheng 
Date: Fri, 29 Dec 2023 14:27:22