[llvm] [GVN] Excluding dead blocks before full redundancy eliminations (PR #88556)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 12 11:46:27 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Min-Yih Hsu (mshockwave)
<details>
<summary>Changes</summary>
Dead blocks will never contribute to non-local load value definitions; keeping it will trigger one of the assertions when we're building SSA form for candidate loads during full redundancy eliminations.
This fixes #<!-- -->88051
---
Full diff: https://github.com/llvm/llvm-project/pull/88556.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/GVN.cpp (+11)
- (added) llvm/test/Transforms/GVN/pr88051.ll (+91)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 67fb2a5da3bb71..d5e84bf02a13e1 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -1888,6 +1888,17 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
// load, then it is fully redundant and we can use PHI insertion to compute
// its value. Insert PHIs and remove the fully redundant value now.
if (UnavailableBlocks.empty()) {
+ // Excluding dead blocks, whose available values are undef. Note that we
+ // can't do this removal for partial redundancy.
+ auto AVEndIt = ValuesPerBlock.end();
+ auto AVBeginIt =
+ llvm::remove_if(ValuesPerBlock, [](const auto &AV) -> bool {
+ return AV.AV.isUndefValue();
+ });
+ ValuesPerBlock.erase(AVBeginIt, AVEndIt);
+ if (ValuesPerBlock.empty())
+ return Changed;
+
LLVM_DEBUG(dbgs() << "GVN REMOVING NONLOCAL LOAD: " << *Load << '\n');
// Perform PHI construction.
diff --git a/llvm/test/Transforms/GVN/pr88051.ll b/llvm/test/Transforms/GVN/pr88051.ll
new file mode 100644
index 00000000000000..c50545764097ac
--- /dev/null
+++ b/llvm/test/Transforms/GVN/pr88051.ll
@@ -0,0 +1,91 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S --passes='gvn' < %s | FileCheck %s
+
+ at g = external global i32
+ at e = external global [1 x i32]
+
+define signext i32 @main() nounwind {
+; CHECK-LABEL: define signext i32 @main(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+; CHECK: while.body:
+; CHECK-NEXT: [[DOTPRE15:%.*]] = phi i32 [ [[DOTPRE16:%.*]], [[FOR_END54:%.*]] ], [ undef, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[DOTPRE2:%.*]] = phi i32 [ [[DOTPRE3:%.*]], [[FOR_END54]] ], [ undef, [[ENTRY]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[TMP3:%.*]], [[FOR_END54]] ], [ undef, [[ENTRY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[TMP4:%.*]], [[FOR_END54]] ], [ undef, [[ENTRY]] ]
+; CHECK-NEXT: br label [[FOR_BODY3:%.*]]
+; CHECK: for.body3:
+; CHECK-NEXT: br i1 false, label [[IF_ELSE:%.*]], label [[FOR_COND6_PREHEADER:%.*]]
+; CHECK: for.cond6.preheader:
+; CHECK-NEXT: br label [[IF_END49:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr null, align 8
+; CHECK-NEXT: store volatile i32 0, ptr [[TMP2]], align 4
+; CHECK-NEXT: br i1 false, label [[IF_END:%.*]], label [[FOR_END54SPLITSPLIT:%.*]]
+; CHECK: if.end:
+; CHECK-NEXT: br i1 false, label [[IF_END_IF_END49_CRIT_EDGE:%.*]], label [[IF_END_FOR_END54_CRIT_EDGE:%.*]]
+; CHECK: if.end.if.end49_crit_edge:
+; CHECK-NEXT: br label [[IF_END49]]
+; CHECK: if.end.for.end54_crit_edge:
+; CHECK-NEXT: [[DOTPRE9:%.*]] = sext i32 [[TMP1]] to i64
+; CHECK-NEXT: br label [[FOR_END54]]
+; CHECK: if.end49:
+; CHECK-NEXT: br i1 true, label [[FOR_BODY3]], label [[IF_END49_FOR_END54SPLIT_CRIT_EDGE:%.*]]
+; CHECK: if.end49.for.end54split_crit_edge:
+; CHECK-NEXT: [[DOTPRE_PRE:%.*]] = load i32, ptr @g, align 4
+; CHECK-NEXT: [[DOTPRE8:%.*]] = sext i32 [[DOTPRE_PRE]] to i64
+; CHECK-NEXT: br label [[FOR_END54SPLIT:%.*]]
+; CHECK: for.end54splitsplit:
+; CHECK-NEXT: [[IDXPROM55_PHI_TRANS_INSERT_PHI_TRANS_INSERT:%.*]] = sext i32 [[DOTPRE2]] to i64
+; CHECK-NEXT: [[ARRAYIDX56_PHI_TRANS_INSERT_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds [1 x i32], ptr @e, i64 0, i64 [[IDXPROM55_PHI_TRANS_INSERT_PHI_TRANS_INSERT]]
+; CHECK-NEXT: [[DOTPRE1_PRE:%.*]] = load i32, ptr [[ARRAYIDX56_PHI_TRANS_INSERT_PHI_TRANS_INSERT]], align 4
+; CHECK-NEXT: br label [[FOR_END54SPLIT]]
+; CHECK: for.end54split:
+; CHECK-NEXT: [[IDXPROM55_PHI_TRANS_INSERT_PRE_PHI:%.*]] = phi i64 [ [[IDXPROM55_PHI_TRANS_INSERT_PHI_TRANS_INSERT]], [[FOR_END54SPLITSPLIT]] ], [ [[DOTPRE8]], [[IF_END49_FOR_END54SPLIT_CRIT_EDGE]] ]
+; CHECK-NEXT: [[DOTPRE1:%.*]] = phi i32 [ [[DOTPRE1_PRE]], [[FOR_END54SPLITSPLIT]] ], [ [[DOTPRE15]], [[IF_END49_FOR_END54SPLIT_CRIT_EDGE]] ]
+; CHECK-NEXT: [[DOTPRE:%.*]] = phi i32 [ [[DOTPRE2]], [[FOR_END54SPLITSPLIT]] ], [ [[DOTPRE_PRE]], [[IF_END49_FOR_END54SPLIT_CRIT_EDGE]] ]
+; CHECK-NEXT: [[ARRAYIDX56_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds [1 x i32], ptr @e, i64 0, i64 [[IDXPROM55_PHI_TRANS_INSERT_PRE_PHI]]
+; CHECK-NEXT: br label [[FOR_END54]]
+; CHECK: for.end54:
+; CHECK-NEXT: [[IDXPROM55_PRE_PHI:%.*]] = phi i64 [ [[IDXPROM55_PHI_TRANS_INSERT_PRE_PHI]], [[FOR_END54SPLIT]] ], [ [[DOTPRE9]], [[IF_END_FOR_END54_CRIT_EDGE]] ]
+; CHECK-NEXT: [[DOTPRE16]] = phi i32 [ [[DOTPRE1]], [[FOR_END54SPLIT]] ], [ [[DOTPRE15]], [[IF_END_FOR_END54_CRIT_EDGE]] ]
+; CHECK-NEXT: [[DOTPRE3]] = phi i32 [ [[DOTPRE]], [[FOR_END54SPLIT]] ], [ [[DOTPRE2]], [[IF_END_FOR_END54_CRIT_EDGE]] ]
+; CHECK-NEXT: [[TMP3]] = phi i32 [ [[DOTPRE1]], [[FOR_END54SPLIT]] ], [ [[TMP0]], [[IF_END_FOR_END54_CRIT_EDGE]] ]
+; CHECK-NEXT: [[TMP4]] = phi i32 [ [[DOTPRE]], [[FOR_END54SPLIT]] ], [ [[TMP1]], [[IF_END_FOR_END54_CRIT_EDGE]] ]
+; CHECK-NEXT: [[ARRAYIDX56:%.*]] = getelementptr inbounds [1 x i32], ptr @e, i64 0, i64 [[IDXPROM55_PRE_PHI]]
+; CHECK-NEXT: tail call void null(i32 noundef signext [[TMP3]])
+; CHECK-NEXT: br label [[WHILE_BODY]]
+;
+entry:
+ br label %while.body
+
+while.body: ; preds = %for.end54, %entry
+ br label %for.body3
+
+for.body3: ; preds = %if.end49, %while.body
+ br i1 false, label %if.else, label %for.cond6.preheader
+
+for.cond6.preheader: ; preds = %for.body3
+ br label %if.end49
+
+if.else: ; preds = %for.body3
+ %0 = load ptr, ptr null, align 8
+ store volatile i32 0, ptr %0, align 4
+ br i1 false, label %if.end, label %for.end54
+
+if.end: ; preds = %if.else
+ br i1 false, label %if.end49, label %for.end54
+
+if.end49: ; preds = %if.end, %for.cond6.preheader
+ br i1 true, label %for.body3, label %for.end54
+
+for.end54: ; preds = %if.end49, %if.end, %if.else
+ %1 = load i32, ptr @g, align 4
+ %idxprom55 = sext i32 %1 to i64
+ %arrayidx56 = getelementptr inbounds [1 x i32], ptr @e, i64 0, i64 %idxprom55
+ %2 = load i32, ptr %arrayidx56, align 4
+ tail call void null(i32 noundef signext %2)
+ br label %while.body
+}
+
``````````
</details>
https://github.com/llvm/llvm-project/pull/88556
More information about the llvm-commits
mailing list