Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,10 @@ static bool foldMemChr(CallInst *Call, DomTreeUpdater *DTU,
BB->getTerminator()->eraseFromParent();
SwitchInst *SI = IRB.CreateSwitch(
IRB.CreateTrunc(Call->getArgOperand(1), ByteTy), BBNext, N);
// We can't know the precise weights here, as they would depend on the value
// distribution of Call->getArgOperand(1). So we just mark it as "unknown".
setExplicitlyUnknownBranchWeightsIfProfiled(*SI, *Call->getFunction(),
DEBUG_TYPE);
Type *IndexTy = DL.getIndexType(Call->getType());
SmallVector<DominatorTree::UpdateType, 8> Updates;

Expand Down
51 changes: 32 additions & 19 deletions llvm/test/Transforms/AggressiveInstCombine/memchr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

declare ptr @memchr(ptr, i32, i64)

define i1 @test_memchr_null(i32 %x) {
define i1 @test_memchr_null(i32 %x) !prof !0 {
; CHECK-LABEL: define i1 @test_memchr_null(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]])
; CHECK: !prof [[PROF_0:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
Expand Down Expand Up @@ -40,9 +41,10 @@ entry:
ret i1 %isnull
}

define ptr @test_memchr(i32 %x) {
define ptr @test_memchr(i32 %x) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i8
; CHECK-NEXT: switch i8 [[TMP0]], label %[[ENTRY_SPLIT:.*]] [
Expand Down Expand Up @@ -72,16 +74,17 @@ entry:
ret ptr %memchr
}

define ptr @test_memchr_smaller_n(i32 %x) {
define ptr @test_memchr_smaller_n(i32 %x) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_smaller_n(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]])
; CHECK: !prof [[PROF_0]] {
; 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: ]
; CHECK-NEXT: ], !prof [[PROF_1:![0-9]+]]
; CHECK: [[MEMCHR_CASE]]:
; CHECK-NEXT: br label %[[MEMCHR_SUCCESS:.*]]
; CHECK: [[MEMCHR_CASE1]]:
Expand All @@ -103,9 +106,10 @@ entry:

; negative tests

define ptr @test_memchr_larger_n(i32 %x) {
define ptr @test_memchr_larger_n(i32 %x) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_larger_n(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 6)
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -115,9 +119,10 @@ entry:
ret ptr %memchr
}

define ptr @test_memchr_non_constant(i32 %x, ptr %str) {
define ptr @test_memchr_non_constant(i32 %x, ptr %str) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_non_constant(
; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]], ptr [[STR:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr [[STR]], i32 [[X]], i64 5)
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -127,8 +132,9 @@ entry:
ret ptr %memchr
}

define ptr @test_memchr_constant_ch() {
; CHECK-LABEL: define ptr @test_memchr_constant_ch() {
define ptr @test_memchr_constant_ch() !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_constant_ch()
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 49, i64 5)
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -138,9 +144,10 @@ entry:
ret ptr %memchr
}

define ptr @test_memchr_dynamic_n(i32 %x, i32 %y) {
define ptr @test_memchr_dynamic_n(i32 %x, i32 %y) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_dynamic_n(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i32 [[Y]])
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -150,9 +157,10 @@ entry:
ret ptr %memchr
}

define ptr @test_memchr_long(i32 %x) {
define ptr @test_memchr_long(i32 %x) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_long(
; CHECK-SAME: i32 [[X:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str_long, i32 [[X]], i64 8)
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -163,9 +171,10 @@ entry:
}

; We want to check that the compiler still calls memchr if the length is non-constant:
define ptr @test_memchr_non_constant_length2(i32 %x, i64 %len) {
define ptr @test_memchr_non_constant_length2(i32 %x, i64 %len) !prof !0 {
; CHECK-LABEL: define ptr @test_memchr_non_constant_length2(
; CHECK-SAME: i32 [[X:%.*]], i64 [[LEN:%.*]]) {
; CHECK-SAME: i32 [[X:%.*]], i64 [[LEN:%.*]])
; CHECK: !prof [[PROF_0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr @str, i32 [[X]], i64 [[LEN]])
; CHECK-NEXT: ret ptr [[MEMCHR]]
Expand All @@ -174,3 +183,7 @@ entry:
%memchr = call ptr @memchr(ptr @str, i32 %x, i64 %len)
ret ptr %memchr
}

!0 = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF_0]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF_1]] = !{!"unknown", !"aggressive-instcombine"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: missing EOF line.