[llvm] [AggressiveInstCombine] Expand strchr/memchr with small constant strings (PR #98501)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 16 04:11:08 PDT 2024
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/98501
>From 43614175726ccd4c890b08ac8846dc5ba92f4c13 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 11 Jul 2024 23:32:49 +0800
Subject: [PATCH 1/7] [AggressiveInstCombine] Add pre-commit tests. NFC.
---
.../AggressiveInstCombine/strchr.ll | 119 ++++++++++++++++++
1 file changed, 119 insertions(+)
create mode 100644 llvm/test/Transforms/AggressiveInstCombine/strchr.ll
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
new file mode 100644
index 0000000000000..86aa267ac2f44
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
@@ -0,0 +1,119 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=aggressive-instcombine --strchr-inline-threshold=5 < %s | FileCheck %s
+
+ at str = constant [5 x i8] c"01\002\00", align 1
+ at str_long = constant [8 x i8] c"0123456\00", align 1
+
+declare ptr @memchr(ptr, i32, i64)
+declare ptr @strchr(ptr, i32)
+
+define ptr @test_strchr(i32 %x) {
+; CHECK-LABEL: define ptr @test_strchr(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 [[X]])
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @strchr(ptr @str, i32 %x)
+ ret ptr %memchr
+}
+
+define i1 @test_strchr_null(i32 %x) {
+; CHECK-LABEL: define i1 @test_strchr_null(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 [[X]])
+; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[MEMCHR]], null
+; CHECK-NEXT: ret i1 [[ISNULL]]
+;
+entry:
+ %memchr = call ptr @strchr(ptr @str, i32 %x)
+ %isnull = icmp eq ptr %memchr, null
+ ret i1 %isnull
+}
+
+define ptr @test_memchr(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 5)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_smaller_n(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr_smaller_n(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 4)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_larger_n(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr_larger_n(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 6)
+ ret ptr %memchr
+}
+
+; negative tests
+
+define ptr @test_strchr_non_constant(i32 %x, ptr %str) {
+; CHECK-LABEL: define ptr @test_strchr_non_constant(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr [[STR]], i32 [[X]])
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @strchr(ptr %str, i32 %x)
+ ret ptr %memchr
+}
+
+define ptr @test_strchr_constant_ch() {
+; CHECK-LABEL: define ptr @test_strchr_constant_ch() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 49)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @strchr(ptr @str, i32 49)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_dynamic_n(i32 %x, i32 %y) {
+; CHECK-LABEL: define ptr @test_memchr_dynamic_n(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i32 %y)
+ ret ptr %memchr
+}
+
+define ptr @test_strchr_long(i32 %x) {
+; CHECK-LABEL: define ptr @test_strchr_long(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str_long, i32 [[X]])
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @strchr(ptr @str_long, i32 %x)
+ ret ptr %memchr
+}
>From 88a959a7bb144c0258813a0318846d145b54012f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 11 Jul 2024 23:49:36 +0800
Subject: [PATCH 2/7] [AggressiveInstCombine] Expand strchr/memchr with small
constant strings
---
.../AggressiveInstCombine.cpp | 87 ++++++++++++++
.../AggressiveInstCombine/strchr.ll | 108 ++++++++++++++++--
2 files changed, 185 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 1e0b8d448b9d1..c907fef1379e5 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -54,6 +54,11 @@ static cl::opt<unsigned> StrNCmpInlineThreshold(
cl::desc("The maximum length of a constant string for a builtin string cmp "
"call eligible for inlining. The default value is 3."));
+static cl::opt<unsigned>
+ StrChrInlineThreshold("strchr-inline-threshold", cl::init(3), cl::Hidden,
+ cl::desc("The maximum length of a constant string to "
+ "inline a memchr/strchr call."));
+
/// Match a pattern for a bitwise funnel/rotate operation that partially guards
/// against undefined behavior by branching around the funnel-shift/rotation
/// when the shift amount is 0.
@@ -1103,6 +1108,81 @@ void StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
}
}
+/// Convert strchr/memchr with a small constant string into a switch
+static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
+ const DataLayout &DL) {
+ assert((Func == LibFunc_strchr || Func == LibFunc_memchr) &&
+ "Unexpected LibFunc");
+ if (isa<Constant>(Call->getArgOperand(1)))
+ return false;
+
+ StringRef Str;
+ Value *Base = Call->getArgOperand(0);
+ if (!getConstantStringInfo(Base, Str, /*TrimAtNul=*/Func == LibFunc_strchr))
+ return false;
+
+ uint64_t N = Str.size();
+ if (Func == LibFunc_memchr) {
+ if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2)))
+ N = std::min(N, ConstInt->getZExtValue());
+ else
+ return false;
+ }
+
+ if (N > StrChrInlineThreshold)
+ return false;
+
+ BasicBlock *BB = Call->getParent();
+ BasicBlock *BBNext = SplitBlock(BB, Call, DTU);
+ IRBuilder<> IRB(BB);
+ IntegerType *ByteTy = IRB.getInt8Ty();
+ BB->getTerminator()->eraseFromParent();
+ SwitchInst *SI = IRB.CreateSwitch(
+ IRB.CreateTrunc(Call->getArgOperand(1), ByteTy), BBNext, N);
+ Type *IndexTy = DL.getIndexType(Call->getType());
+
+ PHINode *PHI = PHINode::Create(Call->getType(), 2, "", BBNext->begin());
+ PHI->addIncoming(Constant::getNullValue(Call->getType()), BB);
+
+ SmallVector<DominatorTree::UpdateType, 8> Updates;
+
+ BasicBlock *BBSuccess =
+ BasicBlock::Create(Call->getContext(), "", BB->getParent(), BBSuccess);
+ IRB.SetInsertPoint(BBSuccess);
+ PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N);
+ Value *FirstOccursLocation = IRB.CreateInBoundsPtrAdd(Base, IndexPHI);
+ PHI->addIncoming(FirstOccursLocation, BBSuccess);
+ IRB.CreateBr(BBNext);
+ if (DTU)
+ Updates.push_back({DominatorTree::Insert, BBSuccess, BBNext});
+
+ SmallPtrSet<ConstantInt *, 4> Cases;
+ for (uint64_t I = 0; I < N; ++I) {
+ ConstantInt *CaseVal = ConstantInt::get(ByteTy, Str[I]);
+ if (!Cases.insert(CaseVal).second)
+ continue;
+
+ BasicBlock *BBCase =
+ BasicBlock::Create(Call->getContext(), "", BB->getParent(), BBNext);
+ SI->addCase(CaseVal, BBCase);
+ IRB.SetInsertPoint(BBCase);
+ IndexPHI->addIncoming(ConstantInt::get(IndexTy, I), BBCase);
+ IRB.CreateBr(BBSuccess);
+ if (DTU) {
+ Updates.push_back({DominatorTree::Insert, BB, BBCase});
+ Updates.push_back({DominatorTree::Insert, BBCase, BBSuccess});
+ }
+ }
+
+ Call->replaceAllUsesWith(PHI);
+ Call->eraseFromParent();
+
+ if (DTU)
+ DTU->applyUpdates(Updates);
+
+ return true;
+}
+
static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
TargetLibraryInfo &TLI, AssumptionCache &AC,
DominatorTree &DT, const DataLayout &DL,
@@ -1135,6 +1215,13 @@ static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
return true;
}
break;
+ case LibFunc_strchr:
+ case LibFunc_memchr:
+ if (foldStrChr(CI, LF, &DTU, DL)) {
+ MadeCFGChange = true;
+ return true;
+ }
+ break;
default:;
}
return false;
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
index 86aa267ac2f44..1692e5892c8ed 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
@@ -10,9 +10,23 @@ declare ptr @strchr(ptr, i32)
define ptr @test_strchr(i32 %x) {
; CHECK-LABEL: define ptr @test_strchr(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 [[X]])
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[BB1:.*]]
+; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB4:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br label %[[BB4]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6:%.*]], %[[BB4]] ]
; CHECK-NEXT: ret ptr [[MEMCHR]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ]
+; CHECK-NEXT: [[TMP6]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @strchr(ptr @str, i32 %x)
@@ -22,10 +36,24 @@ entry:
define i1 @test_strchr_null(i32 %x) {
; CHECK-LABEL: define i1 @test_strchr_null(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 [[X]])
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[BB1:.*]]
+; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB4:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br label %[[BB4]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6:%.*]], %[[BB4]] ]
; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[MEMCHR]], null
; CHECK-NEXT: ret i1 [[ISNULL]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ]
+; CHECK-NEXT: [[TMP6]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @strchr(ptr @str, i32 %x)
@@ -36,9 +64,29 @@ entry:
define ptr @test_memchr(i32 %x) {
; CHECK-LABEL: define ptr @test_memchr(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 5)
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[BB1:.*]]
+; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: i8 0, label %[[BB3:.*]]
+; CHECK-NEXT: i8 50, label %[[BB4:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB6:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
; CHECK-NEXT: ret ptr [[MEMCHR]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
+; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
@@ -48,9 +96,29 @@ entry:
define ptr @test_memchr_smaller_n(i32 %x) {
; CHECK-LABEL: define ptr @test_memchr_smaller_n(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 4)
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[BB1:.*]]
+; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: i8 0, label %[[BB3:.*]]
+; CHECK-NEXT: i8 50, label %[[BB4:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB6:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
; CHECK-NEXT: ret ptr [[MEMCHR]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
+; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
@@ -60,9 +128,29 @@ entry:
define ptr @test_memchr_larger_n(i32 %x) {
; CHECK-LABEL: define ptr @test_memchr_larger_n(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[BB1:.*]]
+; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: i8 0, label %[[BB3:.*]]
+; CHECK-NEXT: i8 50, label %[[BB4:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB6:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
; CHECK-NEXT: ret ptr [[MEMCHR]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
+; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 6)
>From 3ddb24ffc5d304901b8c4b4c01666ce0d59a7f3d Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 12 Jul 2024 21:17:53 +0800
Subject: [PATCH 3/7] [AggressiveInstCombine] Address review comments.
---
.../AggressiveInstCombine.cpp | 10 +++++--
.../AggressiveInstCombine/strchr.ll | 28 +++----------------
2 files changed, 11 insertions(+), 27 deletions(-)
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index c907fef1379e5..a4a705206c24a 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1123,9 +1123,13 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
uint64_t N = Str.size();
if (Func == LibFunc_memchr) {
- if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2)))
- N = std::min(N, ConstInt->getZExtValue());
- else
+ if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
+ uint64_t Val = ConstInt->getZExtValue();
+ /// Ignore the case that n is larger than the size of string.
+ if (Val > N)
+ return false;
+ N = Val;
+ } else
return false;
}
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
index 1692e5892c8ed..d6e94eef21c0a 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
@@ -125,40 +125,20 @@ entry:
ret ptr %memchr
}
+; negative tests
+
define ptr @test_memchr_larger_n(i32 %x) {
; CHECK-LABEL: define ptr @test_memchr_larger_n(
; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
-; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[BB1:.*]]
-; CHECK-NEXT: i8 49, label %[[BB2:.*]]
-; CHECK-NEXT: i8 0, label %[[BB3:.*]]
-; CHECK-NEXT: i8 50, label %[[BB4:.*]]
-; CHECK-NEXT: ]
-; CHECK: [[BB1]]:
-; CHECK-NEXT: br label %[[BB6:.*]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB3]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB4]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
; CHECK-NEXT: ret ptr [[MEMCHR]]
-; CHECK: [[BB6]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
-; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 6)
ret ptr %memchr
}
-; negative tests
-
define ptr @test_strchr_non_constant(i32 %x, ptr %str) {
; CHECK-LABEL: define ptr @test_strchr_non_constant(
; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]]) {
>From 31a7d82f0a331228e61858db19fd8e1643b6b2e9 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Mon, 15 Jul 2024 13:17:14 +0800
Subject: [PATCH 4/7] [AggressiveInstCombine] Address review comments.
---
.../AggressiveInstCombine.cpp | 10 +-
.../AggressiveInstCombine/strchr.ll | 118 +++++++++---------
2 files changed, 64 insertions(+), 64 deletions(-)
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index a4a705206c24a..71cfaa82ba948 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1125,7 +1125,7 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
if (Func == LibFunc_memchr) {
if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
uint64_t Val = ConstInt->getZExtValue();
- /// Ignore the case that n is larger than the size of string.
+ // Ignore the case that n is larger than the size of string.
if (Val > N)
return false;
N = Val;
@@ -1150,8 +1150,8 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
SmallVector<DominatorTree::UpdateType, 8> Updates;
- BasicBlock *BBSuccess =
- BasicBlock::Create(Call->getContext(), "", BB->getParent(), BBSuccess);
+ BasicBlock *BBSuccess = BasicBlock::Create(
+ Call->getContext(), "strchr.success", BB->getParent(), BBNext);
IRB.SetInsertPoint(BBSuccess);
PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N);
Value *FirstOccursLocation = IRB.CreateInBoundsPtrAdd(Base, IndexPHI);
@@ -1166,8 +1166,8 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
if (!Cases.insert(CaseVal).second)
continue;
- BasicBlock *BBCase =
- BasicBlock::Create(Call->getContext(), "", BB->getParent(), BBNext);
+ BasicBlock *BBCase = BasicBlock::Create(Call->getContext(), "strchr.case",
+ BB->getParent(), BBNext);
SI->addCase(CaseVal, BBCase);
IRB.SetInsertPoint(BBCase);
IndexPHI->addIncoming(ConstantInt::get(IndexTy, I), BBCase);
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
index d6e94eef21c0a..636c38ac4d506 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
@@ -13,20 +13,20 @@ define ptr @test_strchr(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[BB1:.*]]
-; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
; CHECK-NEXT: ]
-; CHECK: [[BB1]]:
-; CHECK-NEXT: br label %[[BB4:.*]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: br label %[[BB4]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6:%.*]], %[[BB4]] ]
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-; CHECK: [[BB4]]:
-; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ]
-; CHECK-NEXT: [[TMP6]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
+; CHECK: [[STRCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ]
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[STRCHR_CASE]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE1]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6]], %[[STRCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[TMP3]]
;
entry:
%memchr = call ptr @strchr(ptr @str, i32 %x)
@@ -39,21 +39,21 @@ define i1 @test_strchr_null(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[BB1:.*]]
-; CHECK-NEXT: i8 49, label %[[BB2:.*]]
+; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
; CHECK-NEXT: ]
-; CHECK: [[BB1]]:
-; CHECK-NEXT: br label %[[BB4:.*]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: br label %[[BB4]]
+; CHECK: [[STRCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP1]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[STRCHR_CASE]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE1]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6:%.*]], %[[BB4]] ]
+; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP2]], %[[STRCHR_SUCCESS]] ]
; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[MEMCHR]], null
; CHECK-NEXT: ret i1 [[ISNULL]]
-; CHECK: [[BB4]]:
-; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ]
-; CHECK-NEXT: [[TMP6]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
;
entry:
%memchr = call ptr @strchr(ptr @str, i32 %x)
@@ -67,26 +67,26 @@ define ptr @test_memchr(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[BB1:.*]]
-; CHECK-NEXT: i8 49, label %[[BB2:.*]]
-; CHECK-NEXT: i8 0, label %[[BB3:.*]]
-; CHECK-NEXT: i8 50, label %[[BB4:.*]]
+; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
+; CHECK-NEXT: i8 0, label %[[STRCHR_CASE2:.*]]
+; CHECK-NEXT: i8 50, label %[[STRCHR_CASE3:.*]]
; CHECK-NEXT: ]
-; CHECK: [[BB1]]:
-; CHECK-NEXT: br label %[[BB6:.*]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB3]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB4]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-; CHECK: [[BB6]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
-; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK: [[STRCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ], [ 2, %[[STRCHR_CASE2]] ], [ 3, %[[STRCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[STRCHR_CASE]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE1]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE2]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE3]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[STRCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[TMP3]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
@@ -99,26 +99,26 @@ define ptr @test_memchr_smaller_n(i32 %x) {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[BB1:.*]]
-; CHECK-NEXT: i8 49, label %[[BB2:.*]]
-; CHECK-NEXT: i8 0, label %[[BB3:.*]]
-; CHECK-NEXT: i8 50, label %[[BB4:.*]]
+; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
+; CHECK-NEXT: i8 0, label %[[STRCHR_CASE2:.*]]
+; CHECK-NEXT: i8 50, label %[[STRCHR_CASE3:.*]]
; CHECK-NEXT: ]
-; CHECK: [[BB1]]:
-; CHECK-NEXT: br label %[[BB6:.*]]
-; CHECK: [[BB2]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB3]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[BB4]]:
-; CHECK-NEXT: br label %[[BB6]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8:%.*]], %[[BB6]] ]
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-; CHECK: [[BB6]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[BB1]] ], [ 1, %[[BB2]] ], [ 2, %[[BB3]] ], [ 3, %[[BB4]] ]
-; CHECK-NEXT: [[TMP8]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK: [[STRCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ], [ 2, %[[STRCHR_CASE2]] ], [ 3, %[[STRCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[STRCHR_CASE]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE1]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE2]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[STRCHR_CASE3]]:
+; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[STRCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[TMP3]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
>From 42af6e6bde066abb1861009df146df1fe260fe1f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 16 Jul 2024 13:20:05 +0800
Subject: [PATCH 5/7] [AggressiveInstCombine] Address review comments. NFC.
---
.../AggressiveInstCombine.cpp | 46 ++---
.../AggressiveInstCombine/memchr.ll | 166 ++++++++++++++++
.../AggressiveInstCombine/strchr.ll | 187 ------------------
3 files changed, 186 insertions(+), 213 deletions(-)
create mode 100644 llvm/test/Transforms/AggressiveInstCombine/memchr.ll
delete mode 100644 llvm/test/Transforms/AggressiveInstCombine/strchr.ll
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index 71cfaa82ba948..ac50ff3ca7c6e 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -55,9 +55,9 @@ static cl::opt<unsigned> StrNCmpInlineThreshold(
"call eligible for inlining. The default value is 3."));
static cl::opt<unsigned>
- StrChrInlineThreshold("strchr-inline-threshold", cl::init(3), cl::Hidden,
+ MemChrInlineThreshold("memchr-inline-threshold", cl::init(3), cl::Hidden,
cl::desc("The maximum length of a constant string to "
- "inline a memchr/strchr call."));
+ "inline a memchr call."));
/// Match a pattern for a bitwise funnel/rotate operation that partially guards
/// against undefined behavior by branching around the funnel-shift/rotation
@@ -1108,32 +1108,28 @@ void StrNCmpInliner::inlineCompare(Value *LHS, StringRef RHS, uint64_t N,
}
}
-/// Convert strchr/memchr with a small constant string into a switch
-static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
+/// Convert memchr with a small constant string into a switch
+static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
const DataLayout &DL) {
- assert((Func == LibFunc_strchr || Func == LibFunc_memchr) &&
- "Unexpected LibFunc");
if (isa<Constant>(Call->getArgOperand(1)))
return false;
StringRef Str;
Value *Base = Call->getArgOperand(0);
- if (!getConstantStringInfo(Base, Str, /*TrimAtNul=*/Func == LibFunc_strchr))
+ if (!getConstantStringInfo(Base, Str, /*TrimAtNul=*/false))
return false;
uint64_t N = Str.size();
- if (Func == LibFunc_memchr) {
- if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
- uint64_t Val = ConstInt->getZExtValue();
- // Ignore the case that n is larger than the size of string.
- if (Val > N)
- return false;
- N = Val;
- } else
+ if (auto *ConstInt = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
+ uint64_t Val = ConstInt->getZExtValue();
+ // Ignore the case that n is larger than the size of string.
+ if (Val > N)
return false;
- }
+ N = Val;
+ } else
+ return false;
- if (N > StrChrInlineThreshold)
+ if (N > MemChrInlineThreshold)
return false;
BasicBlock *BB = Call->getParent();
@@ -1144,18 +1140,13 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
SwitchInst *SI = IRB.CreateSwitch(
IRB.CreateTrunc(Call->getArgOperand(1), ByteTy), BBNext, N);
Type *IndexTy = DL.getIndexType(Call->getType());
-
- PHINode *PHI = PHINode::Create(Call->getType(), 2, "", BBNext->begin());
- PHI->addIncoming(Constant::getNullValue(Call->getType()), BB);
-
SmallVector<DominatorTree::UpdateType, 8> Updates;
BasicBlock *BBSuccess = BasicBlock::Create(
- Call->getContext(), "strchr.success", BB->getParent(), BBNext);
+ Call->getContext(), "memchr.success", BB->getParent(), BBNext);
IRB.SetInsertPoint(BBSuccess);
PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N);
Value *FirstOccursLocation = IRB.CreateInBoundsPtrAdd(Base, IndexPHI);
- PHI->addIncoming(FirstOccursLocation, BBSuccess);
IRB.CreateBr(BBNext);
if (DTU)
Updates.push_back({DominatorTree::Insert, BBSuccess, BBNext});
@@ -1166,7 +1157,7 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
if (!Cases.insert(CaseVal).second)
continue;
- BasicBlock *BBCase = BasicBlock::Create(Call->getContext(), "strchr.case",
+ BasicBlock *BBCase = BasicBlock::Create(Call->getContext(), "memchr.case",
BB->getParent(), BBNext);
SI->addCase(CaseVal, BBCase);
IRB.SetInsertPoint(BBCase);
@@ -1178,6 +1169,10 @@ static bool foldStrChr(CallInst *Call, LibFunc Func, DomTreeUpdater *DTU,
}
}
+ PHINode *PHI = PHINode::Create(Call->getType(), 2, "", BBNext->begin());
+ PHI->addIncoming(Constant::getNullValue(Call->getType()), BB);
+ PHI->addIncoming(FirstOccursLocation, BBSuccess);
+
Call->replaceAllUsesWith(PHI);
Call->eraseFromParent();
@@ -1219,9 +1214,8 @@ static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
return true;
}
break;
- case LibFunc_strchr:
case LibFunc_memchr:
- if (foldStrChr(CI, LF, &DTU, DL)) {
+ if (foldMemChr(CI, &DTU, DL)) {
MadeCFGChange = true;
return true;
}
diff --git a/llvm/test/Transforms/AggressiveInstCombine/memchr.ll b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
new file mode 100644
index 0000000000000..d1fb7786e6946
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
@@ -0,0 +1,166 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=aggressive-instcombine --memchr-inline-threshold=5 < %s | FileCheck %s
+
+ at str = constant [5 x i8] c"01\002\00", align 1
+ at str_long = constant [8 x i8] c"0123456\00", align 1
+
+declare ptr @memchr(ptr, i32, i64)
+
+define i1 @test_memchr_null(i32 %x) {
+; CHECK-LABEL: define i1 @test_memchr_null(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[MEMCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[MEMCHR_CASE1:.*]]
+; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
+; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[MEMCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP1]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[MEMCHR_CASE]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE1]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE2]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE3]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP2]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[TMP3]], null
+; CHECK-NEXT: ret i1 [[ISNULL]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
+ %isnull = icmp eq ptr %memchr, null
+ ret i1 %isnull
+}
+
+define ptr @test_memchr(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[MEMCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[MEMCHR_CASE1:.*]]
+; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
+; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[MEMCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[MEMCHR_CASE]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE1]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE2]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE3]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[TMP3]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_smaller_n(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr_smaller_n(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
+; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
+; CHECK-NEXT: i8 48, label %[[MEMCHR_CASE:.*]]
+; CHECK-NEXT: i8 49, label %[[MEMCHR_CASE1:.*]]
+; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
+; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[MEMCHR_SUCCESS:.*]]:
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
+; CHECK: [[MEMCHR_CASE]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE1]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE2]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_CASE3]]:
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[ENTRY_SPLIT]]:
+; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[TMP3]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
+ ret ptr %memchr
+}
+
+; negative tests
+
+define ptr @test_memchr_larger_n(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr_larger_n(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 6)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_non_constant(i32 %x, ptr %str) {
+; CHECK-LABEL: define ptr @test_memchr_non_constant(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr [[STR]], i32 [[X]], i64 5)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr %str, i32 %x, i64 5)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_constant_ch() {
+; CHECK-LABEL: define ptr @test_memchr_constant_ch() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 49, i64 5)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 49, i64 5)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_dynamic_n(i32 %x, i32 %y) {
+; CHECK-LABEL: define ptr @test_memchr_dynamic_n(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i32 %y)
+ ret ptr %memchr
+}
+
+define ptr @test_memchr_long(i32 %x) {
+; CHECK-LABEL: define ptr @test_memchr_long(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str_long, i32 [[X]], i64 8)
+; CHECK-NEXT: ret ptr [[MEMCHR]]
+;
+entry:
+ %memchr = call ptr @memchr(ptr @str_long, i32 %x, i64 8)
+ ret ptr %memchr
+}
diff --git a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll b/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
deleted file mode 100644
index 636c38ac4d506..0000000000000
--- a/llvm/test/Transforms/AggressiveInstCombine/strchr.ll
+++ /dev/null
@@ -1,187 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -S -passes=aggressive-instcombine --strchr-inline-threshold=5 < %s | FileCheck %s
-
- at str = constant [5 x i8] c"01\002\00", align 1
- at str_long = constant [8 x i8] c"0123456\00", align 1
-
-declare ptr @memchr(ptr, i32, i64)
-declare ptr @strchr(ptr, i32)
-
-define ptr @test_strchr(i32 %x) {
-; CHECK-LABEL: define ptr @test_strchr(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
-; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
-; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
-; CHECK-NEXT: ]
-; CHECK: [[STRCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ]
-; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP5]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
-; CHECK: [[STRCHR_CASE]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE1]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP6]], %[[STRCHR_SUCCESS]] ]
-; CHECK-NEXT: ret ptr [[TMP3]]
-;
-entry:
- %memchr = call ptr @strchr(ptr @str, i32 %x)
- ret ptr %memchr
-}
-
-define i1 @test_strchr_null(i32 %x) {
-; CHECK-LABEL: define i1 @test_strchr_null(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
-; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
-; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
-; CHECK-NEXT: ]
-; CHECK: [[STRCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ]
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP1]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
-; CHECK: [[STRCHR_CASE]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE1]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[MEMCHR:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP2]], %[[STRCHR_SUCCESS]] ]
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[MEMCHR]], null
-; CHECK-NEXT: ret i1 [[ISNULL]]
-;
-entry:
- %memchr = call ptr @strchr(ptr @str, i32 %x)
- %isnull = icmp eq ptr %memchr, null
- ret i1 %isnull
-}
-
-define ptr @test_memchr(i32 %x) {
-; CHECK-LABEL: define ptr @test_memchr(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
-; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
-; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
-; CHECK-NEXT: i8 0, label %[[STRCHR_CASE2:.*]]
-; CHECK-NEXT: i8 50, label %[[STRCHR_CASE3:.*]]
-; CHECK-NEXT: ]
-; CHECK: [[STRCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ], [ 2, %[[STRCHR_CASE2]] ], [ 3, %[[STRCHR_CASE3]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
-; CHECK: [[STRCHR_CASE]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE1]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE2]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE3]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[STRCHR_SUCCESS]] ]
-; CHECK-NEXT: ret ptr [[TMP3]]
-;
-entry:
- %memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
- ret ptr %memchr
-}
-
-define ptr @test_memchr_smaller_n(i32 %x) {
-; CHECK-LABEL: define ptr @test_memchr_smaller_n(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
-; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
-; CHECK-NEXT: i8 48, label %[[STRCHR_CASE:.*]]
-; CHECK-NEXT: i8 49, label %[[STRCHR_CASE1:.*]]
-; CHECK-NEXT: i8 0, label %[[STRCHR_CASE2:.*]]
-; CHECK-NEXT: i8 50, label %[[STRCHR_CASE3:.*]]
-; CHECK-NEXT: ]
-; CHECK: [[STRCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[STRCHR_CASE]] ], [ 1, %[[STRCHR_CASE1]] ], [ 2, %[[STRCHR_CASE2]] ], [ 3, %[[STRCHR_CASE3]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
-; CHECK: [[STRCHR_CASE]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE1]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE2]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[STRCHR_CASE3]]:
-; CHECK-NEXT: br label %[[STRCHR_SUCCESS]]
-; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[STRCHR_SUCCESS]] ]
-; CHECK-NEXT: ret ptr [[TMP3]]
-;
-entry:
- %memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
- ret ptr %memchr
-}
-
-; negative tests
-
-define ptr @test_memchr_larger_n(i32 %x) {
-; CHECK-LABEL: define ptr @test_memchr_larger_n(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-;
-entry:
- %memchr = call ptr @memchr(ptr @str, i32 %x, i64 6)
- ret ptr %memchr
-}
-
-define ptr @test_strchr_non_constant(i32 %x, ptr %str) {
-; CHECK-LABEL: define ptr @test_strchr_non_constant(
-; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr [[STR]], i32 [[X]])
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-;
-entry:
- %memchr = call ptr @strchr(ptr %str, i32 %x)
- ret ptr %memchr
-}
-
-define ptr @test_strchr_constant_ch() {
-; CHECK-LABEL: define ptr @test_strchr_constant_ch() {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str, i32 49)
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-;
-entry:
- %memchr = call ptr @strchr(ptr @str, i32 49)
- ret ptr %memchr
-}
-
-define ptr @test_memchr_dynamic_n(i32 %x, i32 %y) {
-; CHECK-LABEL: define ptr @test_memchr_dynamic_n(
-; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-;
-entry:
- %memchr = call ptr @memchr(ptr @str, i32 %x, i32 %y)
- ret ptr %memchr
-}
-
-define ptr @test_strchr_long(i32 %x) {
-; CHECK-LABEL: define ptr @test_strchr_long(
-; CHECK-SAME: i32 [[X:%.*]]) {
-; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @strchr(ptr @str_long, i32 [[X]])
-; CHECK-NEXT: ret ptr [[MEMCHR]]
-;
-entry:
- %memchr = call ptr @strchr(ptr @str_long, i32 %x)
- ret ptr %memchr
-}
>From e2de353c8753e625baa7a5fa6f8fc9b4f27ecf95 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 16 Jul 2024 13:22:09 +0800
Subject: [PATCH 6/7] [AggressiveInstCombine] Fix test. NFC.
---
llvm/test/Transforms/AggressiveInstCombine/memchr.ll | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/llvm/test/Transforms/AggressiveInstCombine/memchr.ll b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
index d1fb7786e6946..8905a920397d9 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
@@ -81,10 +81,9 @@ define ptr @test_memchr_smaller_n(i32 %x) {
; CHECK-NEXT: i8 48, label %[[MEMCHR_CASE:.*]]
; CHECK-NEXT: i8 49, label %[[MEMCHR_CASE1:.*]]
; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
-; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
; CHECK-NEXT: ]
; CHECK: [[MEMCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ]
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[MEMCHR_CASE]]:
@@ -93,14 +92,12 @@ define ptr @test_memchr_smaller_n(i32 %x) {
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE2]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
-; CHECK: [[MEMCHR_CASE3]]:
-; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[ENTRY_SPLIT]]:
; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[MEMCHR_SUCCESS]] ]
; CHECK-NEXT: ret ptr [[TMP3]]
;
entry:
- %memchr = call ptr @memchr(ptr @str, i32 %x, i64 4)
+ %memchr = call ptr @memchr(ptr @str, i32 %x, i64 3)
ret ptr %memchr
}
>From 7e8fe2609e888ec9d32bbcbe2ca5140a2c95d2bd Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 16 Jul 2024 19:10:24 +0800
Subject: [PATCH 7/7] [AggressiveInstCombine] Address review comments.
---
.../AggressiveInstCombine.cpp | 7 ++--
.../AggressiveInstCombine/memchr.ll | 42 +++++++++----------
2 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index ac50ff3ca7c6e..d5a38ec17a2a8 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -1145,7 +1145,7 @@ static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
BasicBlock *BBSuccess = BasicBlock::Create(
Call->getContext(), "memchr.success", BB->getParent(), BBNext);
IRB.SetInsertPoint(BBSuccess);
- PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N);
+ PHINode *IndexPHI = IRB.CreatePHI(IndexTy, N, "memchr.idx");
Value *FirstOccursLocation = IRB.CreateInBoundsPtrAdd(Base, IndexPHI);
IRB.CreateBr(BBNext);
if (DTU)
@@ -1158,7 +1158,7 @@ static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
continue;
BasicBlock *BBCase = BasicBlock::Create(Call->getContext(), "memchr.case",
- BB->getParent(), BBNext);
+ BB->getParent(), BBSuccess);
SI->addCase(CaseVal, BBCase);
IRB.SetInsertPoint(BBCase);
IndexPHI->addIncoming(ConstantInt::get(IndexTy, I), BBCase);
@@ -1169,7 +1169,8 @@ static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
}
}
- PHINode *PHI = PHINode::Create(Call->getType(), 2, "", BBNext->begin());
+ PHINode *PHI =
+ PHINode::Create(Call->getType(), 2, Call->getName(), BBNext->begin());
PHI->addIncoming(Constant::getNullValue(Call->getType()), BB);
PHI->addIncoming(FirstOccursLocation, BBSuccess);
diff --git a/llvm/test/Transforms/AggressiveInstCombine/memchr.ll b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
index 8905a920397d9..2601b9f05a97f 100644
--- a/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
+++ b/llvm/test/Transforms/AggressiveInstCombine/memchr.ll
@@ -17,21 +17,21 @@ define i1 @test_memchr_null(i32 %x) {
; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
; CHECK-NEXT: ]
-; CHECK: [[MEMCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP1]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[MEMCHR_CASE]]:
-; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS:.*]]
; CHECK: [[MEMCHR_CASE1]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE2]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE3]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_SUCCESS]]:
+; CHECK-NEXT: [[MEMCHR_IDX:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[MEMCHR_IDX]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP2]], %[[MEMCHR_SUCCESS]] ]
-; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[TMP3]], null
+; CHECK-NEXT: [[MEMCHR4:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP1]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: [[ISNULL:%.*]] = icmp eq ptr [[MEMCHR4]], null
; CHECK-NEXT: ret i1 [[ISNULL]]
;
entry:
@@ -51,21 +51,21 @@ define ptr @test_memchr(i32 %x) {
; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
; CHECK-NEXT: i8 50, label %[[MEMCHR_CASE3:.*]]
; CHECK-NEXT: ]
-; CHECK: [[MEMCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[MEMCHR_CASE]]:
-; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS:.*]]
; CHECK: [[MEMCHR_CASE1]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE2]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE3]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_SUCCESS]]:
+; CHECK-NEXT: [[MEMCHR_IDX:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ], [ 3, %[[MEMCHR_CASE3]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[MEMCHR_IDX]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[MEMCHR_SUCCESS]] ]
-; CHECK-NEXT: ret ptr [[TMP3]]
+; CHECK-NEXT: [[MEMCHR4:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP1]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[MEMCHR4]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 5)
@@ -82,19 +82,19 @@ define ptr @test_memchr_smaller_n(i32 %x) {
; CHECK-NEXT: i8 49, label %[[MEMCHR_CASE1:.*]]
; CHECK-NEXT: i8 0, label %[[MEMCHR_CASE2:.*]]
; CHECK-NEXT: ]
-; CHECK: [[MEMCHR_SUCCESS:.*]]:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[TMP7]]
-; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[MEMCHR_CASE]]:
-; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK-NEXT: br label %[[MEMCHR_SUCCESS:.*]]
; CHECK: [[MEMCHR_CASE1]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
; CHECK: [[MEMCHR_CASE2]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS]]
+; CHECK: [[MEMCHR_SUCCESS]]:
+; CHECK-NEXT: [[MEMCHR_IDX:%.*]] = phi i64 [ 0, %[[MEMCHR_CASE]] ], [ 1, %[[MEMCHR_CASE1]] ], [ 2, %[[MEMCHR_CASE2]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr @str, i64 [[MEMCHR_IDX]]
+; CHECK-NEXT: br label %[[ENTRY_SPLIT]]
; CHECK: [[ENTRY_SPLIT]]:
-; CHECK-NEXT: [[TMP3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP8]], %[[MEMCHR_SUCCESS]] ]
-; CHECK-NEXT: ret ptr [[TMP3]]
+; CHECK-NEXT: [[MEMCHR3:%.*]] = phi ptr [ null, %[[ENTRY]] ], [ [[TMP1]], %[[MEMCHR_SUCCESS]] ]
+; CHECK-NEXT: ret ptr [[MEMCHR3]]
;
entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 3)
More information about the llvm-commits
mailing list