[llvm] [NewGVN] Prevent cyclic reference when building phiofops (PR #69418)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 17 21:22:33 PDT 2023
https://github.com/XChy created https://github.com/llvm/llvm-project/pull/69418
Fixes #69211.
This patch adds self-reference check in `findPHIOfOpsLeader`.
>From 02dfc47d2e44d31d180d5e4d2995982dfb2f9220 Mon Sep 17 00:00:00 2001
From: XChy <xxs_chy at outlook.com>
Date: Wed, 18 Oct 2023 01:20:43 +0800
Subject: [PATCH] [NewGVN] Prevent cyclic reference when building phiofops
---
llvm/lib/Transforms/Scalar/NewGVN.cpp | 10 +++
.../Transforms/NewGVN/cyclic-phi-handling.ll | 74 +++++++++++++++++--
2 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 19ac9526b5f88b6..2bd5e2127aa340a 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -3812,6 +3812,16 @@ Value *NewGVN::findPHIOfOpsLeader(const Expression *E,
auto *MemberInst = dyn_cast<Instruction>(Member);
if (MemberInst == OrigInst)
continue;
+
+ // Prevent cyclic reference, such as:
+ // %a = add i64 %phi, 1
+ // %foundinst = add i64 %a, 1
+ // =>
+ // %phiofops = phi i64 [1, %BB1], [%foundinst, %BB2]
+ // %foundinst = add i64 %phiofops, 1
+ if (llvm::find(MemberInst->operands(), OrigInst) != MemberInst->op_end())
+ continue;
+
// Anything that isn't an instruction is always available.
if (!MemberInst)
return Member;
diff --git a/llvm/test/Transforms/NewGVN/cyclic-phi-handling.ll b/llvm/test/Transforms/NewGVN/cyclic-phi-handling.ll
index 4a2f0b972c9fe1a..5f8d90aa4a6aa21 100644
--- a/llvm/test/Transforms/NewGVN/cyclic-phi-handling.ll
+++ b/llvm/test/Transforms/NewGVN/cyclic-phi-handling.ll
@@ -5,15 +5,15 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
define void @foo(i32 %arg, i32 %arg1, ptr %arg2) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: bb:
-; CHECK-NEXT: br label %bb3
+; CHECK-NEXT: br label [[BB3:%.*]]
; CHECK: bb3:
-; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ %arg1, %bb ], [ [[TMP:%.*]]4, %bb7 ]
-; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ %arg, %bb ], [ [[TMP]], %bb7 ]
-; CHECK-NEXT: [[TMP5:%.*]] = call i32 %arg2(i32 [[TMP4]], i32 [[TMP]])
+; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ [[ARG1:%.*]], [[BB:%.*]] ], [ [[TMP4:%.*]], [[BB7:%.*]] ]
+; CHECK-NEXT: [[TMP4]] = phi i32 [ [[ARG:%.*]], [[BB]] ], [ [[TMP]], [[BB7]] ]
+; CHECK-NEXT: [[TMP5:%.*]] = call i32 [[ARG2:%.*]](i32 [[TMP4]], i32 [[TMP]])
; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i32 [[TMP5]], 0
-; CHECK-NEXT: br i1 [[TMP6]], label %bb7, label %bb8
+; CHECK-NEXT: br i1 [[TMP6]], label [[BB7]], label [[BB8:%.*]]
; CHECK: bb7:
-; CHECK-NEXT: br label %bb3
+; CHECK-NEXT: br label [[BB3]]
; CHECK: bb8:
; CHECK-NEXT: ret void
;
@@ -35,3 +35,65 @@ bb7: ; preds = %bb3
bb8: ; preds = %bb3
ret void
}
+
+; Don't let %b be the candidate when making %a phi of ops
+define i64 @phis_of_ops_cyclic() {
+; CHECK-LABEL: @phis_of_ops_cyclic(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_BODY:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[A:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[A]] = add i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[B:%.*]] = add i64 [[A]], 1
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i64 [[A]], 100
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY]], label [[END:%.*]]
+; CHECK: end:
+; CHECK-NEXT: ret i64 [[B]]
+;
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %a = add i64 %indvars.iv, 1
+ %b = add i64 %a, 1
+
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %tobool = icmp slt i64 %indvars.iv.next, 100
+ br i1 %tobool, label %for.body, label %end
+
+end:
+ ret i64 %b
+}
+
+define i64 @phis_of_ops_cyclic_multiple() {
+; CHECK-LABEL: @phis_of_ops_cyclic_multiple(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[FOR_BODY:%.*]]
+; CHECK: for.body:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[A:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[A]] = add i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[B:%.*]] = add i64 [[A]], 1
+; CHECK-NEXT: [[D:%.*]] = add i64 [[B]], 1
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i64 [[A]], 100
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY]], label [[END:%.*]]
+; CHECK: end:
+; CHECK-NEXT: ret i64 [[D]]
+;
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %a = add i64 %indvars.iv, 1
+ %b = add i64 %a, 1
+ %c = add i64 %a, 1
+ %d = add i64 %b, 1
+
+ %indvars.iv.next = add i64 %indvars.iv, 1
+ %tobool = icmp slt i64 %indvars.iv.next, 100
+ br i1 %tobool, label %for.body, label %end
+
+end:
+ ret i64 %d
+}
More information about the llvm-commits
mailing list