Skip to content
Merged
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
97 changes: 77 additions & 20 deletions llvm/test/Transforms/FunctionSpecialization/profile-counts.ll
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 6
; RUN: opt -passes="ipsccp<func-spec>" -force-specialization -S < %s | FileCheck %s
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"

@A = external dso_local constant i32, align 4
@B = external dso_local constant i32, align 4

; CHECK: define dso_local i32 @bar(i32 %x, i32 %y, ptr %z) !prof ![[BAR_PROF:[0-9]]] {
;.
; CHECK: @A = external dso_local constant i32, align 4
; CHECK: @B = external dso_local constant i32, align 4
;.
define dso_local i32 @bar(i32 %x, i32 %y, ptr %z) !prof !0 {
; CHECK-LABEL: define dso_local i32 @bar(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], ptr [[Z:%.*]]) !prof [[PROF0:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]], !prof [[PROF1:![0-9]+]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo.specialized.1(i32 [[X]], ptr @A)
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @foo.specialized.2(i32 [[Y]], ptr @B)
; CHECK-NEXT: [[CALL2:%.*]] = call i32 @foo.specialized.2(i32 [[Y]], ptr @B)
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[CALL]], [[CALL1]]
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[ADD]], [[CALL2]]
; CHECK-NEXT: br label %[[RETURN:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: [[CALL3:%.*]] = call i32 @foo.specialized.2(i32 [[Y]], ptr @B)
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD1]], %[[IF_THEN]] ], [ [[CALL3]], %[[IF_ELSE]] ]
; CHECK-NEXT: [[CALL4:%.*]] = call i32 @foo(i32 [[X]], ptr [[Z]])
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[RETVAL_0]], [[CALL4]]
; CHECK-NEXT: ret i32 [[ADD2]]
;
entry:
%tobool = icmp ne i32 %x, 0
; CHECK: br i1 %tobool, label %if.then, label %if.else, !prof ![[BRANCH_PROF:[0-9]]]
br i1 %tobool, label %if.then, label %if.else, !prof !1

; CHECK: if.then:
; CHECK: call i32 @foo.specialized.1(i32 %x, ptr @A)
; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B)
; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B)
if.then:
%call = call i32 @foo(i32 %x, ptr @A)
%call1 = call i32 @foo(i32 %y, ptr @B)
Expand All @@ -23,36 +43,73 @@ if.then:
%add1 = add i32 %add, %call2
br label %return

; CHECK: if.else:
; CHECK: call i32 @foo.specialized.2(i32 %y, ptr @B)
if.else:
%call3 = call i32 @foo(i32 %y, ptr @B)
br label %return

; CHECK: return:
; CHECK: call i32 @foo(i32 %x, ptr %z)
return:
%retval.0 = phi i32 [ %add1, %if.then ], [ %call3, %if.else ]
%call4 = call i32 @foo(i32 %x, ptr %z);
%add2 = add i32 %retval.0, %call4
ret i32 %add2
}

; CHECK: define internal i32 @foo(i32 %x, ptr %b) !prof ![[FOO_UNSPEC_PROF:[0-9]]]
; CHECK: define internal i32 @foo.specialized.1(i32 %x, ptr %b) !prof ![[FOO_SPEC_1_PROF:[0-9]]]
; CHECK: define internal i32 @foo.specialized.2(i32 %x, ptr %b) !prof ![[FOO_SPEC_2_PROF:[0-9]]]
define internal i32 @foo(i32 %x, ptr %b) !prof !2 {
define dso_local i32 @baz(i32 %x, i32 %y) !prof !2 {
; CHECK-LABEL: define dso_local i32 @baz(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) !prof [[PROF2:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
; CHECK: [[IF_THEN]]:
; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo.specialized.1(i32 [[X]], ptr @A)
; CHECK-NEXT: br label %[[RETURN:.*]]
; CHECK: [[IF_ELSE]]:
; CHECK-NEXT: [[CALL1:%.*]] = call i32 @foo.specialized.2(i32 [[Y]], ptr @B)
; CHECK-NEXT: br label %[[RETURN]]
; CHECK: [[RETURN]]:
; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL]], %[[IF_THEN]] ], [ [[CALL1]], %[[IF_ELSE]] ]
; CHECK-NEXT: ret i32 [[RETVAL_0]]
;
entry:
%tobool = icmp ne i32 %x, 0
br i1 %tobool, label %if.then, label %if.else

if.then:
%call = call i32 @foo(i32 %x, ptr @A)
br label %return

if.else:
%call1 = call i32 @foo(i32 %y, ptr @B)
br label %return

return:
%retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]
ret i32 %retval.0
}

define internal i32 @foo(i32 %x, ptr %b) !prof !3 {
; CHECK-LABEL: define internal i32 @foo(
; CHECK-SAME: i32 [[X:%.*]], ptr [[B:%.*]]) !prof [[PROF3:![0-9]+]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[B]], align 4
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X]], [[TMP0]]
; CHECK-NEXT: ret i32 [[ADD]]
;
entry:
%0 = load i32, ptr %b, align 4
%add = add nsw i32 %x, %0
ret i32 %add
}

; CHECK: ![[BAR_PROF]] = !{!"function_entry_count", i64 1000}
; CHECK: ![[BRANCH_PROF]] = !{!"branch_weights", i32 1, i32 3}
; CHECK: ![[FOO_UNSPEC_PROF]] = !{!"function_entry_count", i64 500}
; CHECK: ![[FOO_SPEC_1_PROF]] = !{!"function_entry_count", i64 250}
; CHECK: ![[FOO_SPEC_2_PROF]] = !{!"function_entry_count", i64 1250}
!0 = !{!"function_entry_count", i64 1000}
!1 = !{!"branch_weights", i32 1, i32 3}
!2 = !{!"function_entry_count", i64 2000}
!2 = !{!"function_entry_count", i64 0}
!3 = !{!"function_entry_count", i64 2000}
;.
; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 3}
; CHECK: [[PROF2]] = !{!"function_entry_count", i64 0}
; CHECK: [[PROF3]] = !{!"function_entry_count", i64 500}
; CHECK: [[META4:![0-9]+]] = !{!"function_entry_count", i64 250}
; CHECK: [[META5:![0-9]+]] = !{!"function_entry_count", i64 1250}
;.