[lld] [clang] [llvm] [FuncAttrs] Deduce `noundef` attributes for return values (PR #76553)
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)
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)
@@ -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)
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)
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