[llvm] [llvm][instcombine] Add Missed Optimization for Folding Min Max intrinsic into PHI instruction (PR #84619)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 9 01:47:42 PST 2024
https://github.com/PeterChou1 updated https://github.com/llvm/llvm-project/pull/84619
>From 93d329318edce86e5fcb81532c4a449984aa4e49 Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Sat, 9 Mar 2024 01:44:24 -0500
Subject: [PATCH 1/3] [llvm][instcombine] adds missed fold optimization for min
max intrinsics in phi instcombine pass
---
.../InstCombine/InstCombineInternal.h | 3 +
.../Transforms/InstCombine/InstCombinePHI.cpp | 90 +++++++++++++++++++
2 files changed, 93 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 57148d719d9b61..c9221dae533346 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -624,6 +624,9 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
Instruction *foldPHIArgLoadIntoPHI(PHINode &PN);
Instruction *foldPHIArgZextsIntoPHI(PHINode &PN);
Instruction *foldPHIArgIntToPtrToPHI(PHINode &PN);
+ Instruction *foldPHIWithMinMax(PHINode &PN);
+ Instruction *foldPHIWithMinMaxHelper(PHINode &PN, Instruction *I, Value *Z,
+ ICmpInst::Predicate Pred);
/// If an integer typed PHI has only one use which is an IntToPtr operation,
/// replace the PHI with an existing pointer typed PHI if it exists. Otherwise
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 46bca4b722a03a..7c5696ccd2efde 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -611,6 +611,93 @@ Instruction *InstCombinerImpl::foldPHIArgGEPIntoPHI(PHINode &PN) {
return NewGEP;
}
+/// helper function for foldPHIWithMinMax
+Instruction *
+InstCombinerImpl::foldPHIWithMinMaxHelper(PHINode &PN, Instruction *I, Value *Z,
+ ICmpInst::Predicate Pred) {
+
+ auto IsCondKnownTrue = [](Value *Val) -> std::optional<bool> {
+ if (!Val)
+ return std::nullopt;
+ if (match(Val, m_One()))
+ return true;
+ if (match(Val, m_Zero()))
+ return false;
+ return std::nullopt;
+ };
+
+ ICmpInst::Predicate SwappedPred =
+ ICmpInst::getNonStrictPredicate(ICmpInst::getSwappedPredicate(Pred));
+ for (unsigned OpNum = 0; OpNum != PN.getNumIncomingValues(); ++OpNum) {
+ if (auto *MinMax = dyn_cast<MinMaxIntrinsic>(PN.getIncomingValue(OpNum))) {
+ if (Pred != MinMax->getPredicate())
+ continue;
+
+ Value *X = MinMax->getLHS();
+ Value *Y = MinMax->getRHS();
+
+ SimplifyQuery Q = SQ.getWithInstruction(I);
+
+ auto CmpXZ = IsCondKnownTrue(simplifyICmpInst(SwappedPred, X, Z, Q));
+ auto CmpYZ = IsCondKnownTrue(simplifyICmpInst(SwappedPred, Y, Z, Q));
+
+ if (!CmpXZ.has_value() && !CmpYZ.has_value())
+ continue;
+ if (CmpXZ.has_value() && CmpYZ.has_value())
+ continue;
+
+ if (!CmpXZ.has_value()) {
+ std::swap(X, Y);
+ std::swap(CmpXZ, CmpYZ);
+ }
+
+ switch (Pred) {
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::ICMP_UGT:
+ // if X > Z
+ // %min = llvm.min ( X, Y )
+ // %phi = phi %min ... => %phi = phi X ..
+ // %cmp = icmp lt %phi, Z %cmp = icmp %phi, Z
+ // if X < Z
+ // %max = llvm.max ( X, Y )
+ // %phi = phi %max ... => %phi = phi X ..
+ // %cmp = icmp gt %phi, Z %cmp = icmp %phi, Z
+ if (CmpXZ.value()) {
+ if (MinMax->hasOneUse()) {
+ MinMax->eraseFromParent();
+ }
+ PN.setIncomingValue(OpNum, Y);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return nullptr;
+}
+
+/// Fold max min intrinsic into PHI instruction
+Instruction *InstCombinerImpl::foldPHIWithMinMax(PHINode &PN) {
+
+ if (!PN.hasOneUse())
+ return nullptr;
+
+ // The PHI instruction must only be used by a ICmp Instruction
+ if (ICmpInst *ICmp = dyn_cast<ICmpInst>(PN.getUniqueUndroppableUser())) {
+ Value *Op0 = ICmp->getOperand(0), *Op1 = ICmp->getOperand(1);
+ // case 1: icmp <op> %phi, %other
+ if (isa<PHINode>(Op0))
+ return foldPHIWithMinMaxHelper(PN, ICmp, Op1, ICmp->getPredicate());
+ // case 2: icmp <op> %intrinsic, %phi
+ else if (isa<PHINode>(Op1))
+ return foldPHIWithMinMaxHelper(PN, ICmp, Op0, ICmp->getPredicate());
+ }
+ return nullptr;
+}
+
/// Return true if we know that it is safe to sink the load out of the block
/// that defines it. This means that it must be obvious the value of the load is
/// not changed from the point of the load to the end of the block it is in.
@@ -1651,5 +1738,8 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
if (Value *Res = foldDependentIVs(PN, Builder))
return replaceInstUsesWith(PN, Res);
+ if (Instruction *Result = foldPHIWithMinMax(PN))
+ return Result;
+
return nullptr;
}
>From d2798eebe9ae1f2899ac863fe9626a9aa05f74bb Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Sat, 9 Mar 2024 04:35:01 -0500
Subject: [PATCH 2/3] [llvm][instcombine] added test for folding min/max
intrinsics into phi instructions
---
.../Transforms/InstCombine/InstCombinePHI.cpp | 13 +-
.../Transforms/InstCombine/fold-phi-minmax.ll | 314 ++++++++++++++++++
2 files changed, 321 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/Transforms/InstCombine/fold-phi-minmax.ll
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 7c5696ccd2efde..71f8cbeb9a9dbd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -646,6 +646,7 @@ InstCombinerImpl::foldPHIWithMinMaxHelper(PHINode &PN, Instruction *I, Value *Z,
if (CmpXZ.has_value() && CmpYZ.has_value())
continue;
+ // swap XZ with YZ so XZ always has value
if (!CmpXZ.has_value()) {
std::swap(X, Y);
std::swap(CmpXZ, CmpYZ);
@@ -656,13 +657,13 @@ InstCombinerImpl::foldPHIWithMinMaxHelper(PHINode &PN, Instruction *I, Value *Z,
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SGT:
case ICmpInst::ICMP_UGT:
- // if X > Z
+ // if X >= Z
// %min = llvm.min ( X, Y )
- // %phi = phi %min ... => %phi = phi X ..
+ // %phi = phi %min ... => %phi = phi Y ..
// %cmp = icmp lt %phi, Z %cmp = icmp %phi, Z
- // if X < Z
+ // if X <= Z
// %max = llvm.max ( X, Y )
- // %phi = phi %max ... => %phi = phi X ..
+ // %phi = phi %max ... => %phi = phi Y ..
// %cmp = icmp gt %phi, Z %cmp = icmp %phi, Z
if (CmpXZ.value()) {
if (MinMax->hasOneUse()) {
@@ -688,12 +689,12 @@ Instruction *InstCombinerImpl::foldPHIWithMinMax(PHINode &PN) {
// The PHI instruction must only be used by a ICmp Instruction
if (ICmpInst *ICmp = dyn_cast<ICmpInst>(PN.getUniqueUndroppableUser())) {
Value *Op0 = ICmp->getOperand(0), *Op1 = ICmp->getOperand(1);
- // case 1: icmp <op> %phi, %other
+ // case 1: icmp <op> %phi, %intrinsic
if (isa<PHINode>(Op0))
return foldPHIWithMinMaxHelper(PN, ICmp, Op1, ICmp->getPredicate());
// case 2: icmp <op> %intrinsic, %phi
else if (isa<PHINode>(Op1))
- return foldPHIWithMinMaxHelper(PN, ICmp, Op0, ICmp->getPredicate());
+ return foldPHIWithMinMaxHelper(PN, ICmp, Op0, ICmp->getSwappedPredicate());
}
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/fold-phi-minmax.ll b/llvm/test/Transforms/InstCombine/fold-phi-minmax.ll
new file mode 100644
index 00000000000000..55b464cdc58248
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-phi-minmax.ll
@@ -0,0 +1,314 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+
+; test phi combine less than (equal)
+define i1 @src0(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src0(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 6, i32 %a)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine less than (swapped) good
+define i1 @src1(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umax.i32(i32 6, i32 %a)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 6, %ind
+ ret i1 %cmp
+}
+
+; test phi combine less than (swapped) bad
+define i1 @src2(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 6)
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[MIN]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umax.i32(i32 6, i32 %a)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 6, %ind
+ ret i1 %cmp
+}
+
+
+; test phi combine less than (reversed)
+define i1 @src3(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 6)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine less than (over)
+define i1 @src4(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 7)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine less than (under)
+define i1 @src5(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src5(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 5)
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[MIN]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 5)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine greater than (equal)
+define i1 @src6(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src6(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umax.i32(i32 %a, i32 6)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine greater than (over)
+define i1 @src7(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src7(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 7)
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[MIN]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umax.i32(i32 %a, i32 7)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine greater than (under)
+define i1 @src8(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src8(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umax.i32(i32 %a, i32 5)
+ br label %loop
+
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 %ind, 6
+ ret i1 %cmp
+}
+
+; test phi combine greater than (swapped-equal) good
+define i1 @src9(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src9(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 6)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 6, %ind
+ ret i1 %cmp
+}
+
+; test phi combine greater than (swapped-over) good
+define i1 @src11(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src11(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[A:%.*]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 7)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 6, %ind
+ ret i1 %cmp
+}
+
+; test phi combine greater than (swapped-under) bad
+define i1 @src12(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src12(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 5)
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[MIN]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 5)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ugt i32 6, %ind
+ ret i1 %cmp
+}
+
+; test phi combine less than (swapped-equal) bad
+define i1 @src13(i32 %a, i32 %b, i1 %c) #0 {
+; CHECK-LABEL: @src13(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[LOOP:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[A:%.*]], i32 6)
+; CHECK-NEXT: br label [[LOOP]]
+; CHECK: loop:
+; CHECK-NEXT: [[IND:%.*]] = phi i32 [ [[MIN]], [[THEN]] ], [ [[B:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[IND]], 6
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+entry:
+ br i1 %c, label %then, label %loop
+then:
+ %min = call i32 @llvm.umin.i32(i32 %a, i32 6)
+ br label %loop
+loop:
+ %ind = phi i32 [ %min, %then ], [ %b, %entry ]
+ %cmp = icmp ult i32 6, %ind
+ ret i1 %cmp
+}
>From 6de82a748a290c6e879a4922fa7185c98ce829fa Mon Sep 17 00:00:00 2001
From: PeterChou1 <peter.chou at mail.utoronto.ca>
Date: Sat, 9 Mar 2024 04:47:01 -0500
Subject: [PATCH 3/3] [llvm][instcombine] format file for InstCombinePHI
---
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index 71f8cbeb9a9dbd..9cae84741722f6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -694,7 +694,8 @@ Instruction *InstCombinerImpl::foldPHIWithMinMax(PHINode &PN) {
return foldPHIWithMinMaxHelper(PN, ICmp, Op1, ICmp->getPredicate());
// case 2: icmp <op> %intrinsic, %phi
else if (isa<PHINode>(Op1))
- return foldPHIWithMinMaxHelper(PN, ICmp, Op0, ICmp->getSwappedPredicate());
+ return foldPHIWithMinMaxHelper(PN, ICmp, Op0,
+ ICmp->getSwappedPredicate());
}
return nullptr;
}
More information about the llvm-commits
mailing list