|
|
@@ -0,0 +1,261 @@ |
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 |
|
|
; RUN: opt < %s -passes=pgo-icall-prom -S | FileCheck %s --check-prefix=ICALL-FUNC |
|
|
; RUN: opt < %s -passes=pgo-icall-prom -enable-vtable-cmp -vtable-prom-max-num-additional-op-for-one-function=4 -S | FileCheck %s --check-prefixes=ICALL-VTABLE |
|
|
|
|
|
; One target function, one offset, allow at most three vtables |
|
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" |
|
|
target triple = "x86_64-unknown-linux-gnu" |
|
|
|
|
|
@_ZTV4Base = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @_ZN4Base5func1Ei, ptr @_ZN4Base5func2Ev] }, !type !0 |
|
|
@_ZTV8Derived1 = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @_ZN8Derived15func1Ei, ptr @_ZN4Base5func2Ev] }, !type !0, !type !1 |
|
|
@_ZTV8Derived2 = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @_ZN8Derived25func1Ei, ptr @_ZN4Base5func2Ev] }, !type !0, !type !2 |
|
|
@_ZTV8Derived3 = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @_ZN8Derived35func1Ei, ptr @_ZN4Base5func2Ev] }, !type !0, !type !3 |
|
|
|
|
|
define i32 @test_one_function_one_offset_one_vtable(ptr %d) { |
|
|
; ICALL-FUNC-LABEL: define i32 @test_one_function_one_offset_one_vtable( |
|
|
; ICALL-FUNC-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-FUNC-NEXT: entry: |
|
|
; ICALL-FUNC-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF4:![0-9]+]] |
|
|
; ICALL-FUNC-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-FUNC-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) |
|
|
; ICALL-FUNC-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-FUNC-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-FUNC-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], @_ZN4Base5func2Ev |
|
|
; ICALL-FUNC-NEXT: br i1 [[TMP2]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]], !prof [[PROF5:![0-9]+]] |
|
|
; ICALL-FUNC: if.true.direct_targ: |
|
|
; ICALL-FUNC-NEXT: [[TMP3:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP:%.*]] |
|
|
; ICALL-FUNC: if.false.orig_indirect: |
|
|
; ICALL-FUNC-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]](ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP]] |
|
|
; ICALL-FUNC: if.end.icp: |
|
|
; ICALL-FUNC-NEXT: [[TMP4:%.*]] = phi i32 [ [[CALL]], [[IF_FALSE_ORIG_INDIRECT]] ], [ [[TMP3]], [[IF_TRUE_DIRECT_TARG]] ] |
|
|
; ICALL-FUNC-NEXT: ret i32 [[TMP4]] |
|
|
; |
|
|
; ICALL-VTABLE-LABEL: define i32 @test_one_function_one_offset_one_vtable( |
|
|
; ICALL-VTABLE-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-VTABLE-NEXT: entry: |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF4:![0-9]+]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
|
|
; ICALL-VTABLE-NEXT: [[OFFSETVAR1:%.*]] = sub nuw i64 [[TMP0]], 16 |
|
|
; ICALL-VTABLE-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-VTABLE-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) |
|
|
; ICALL-VTABLE-NEXT: [[TMP2:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV8Derived2 to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]], !prof [[PROF5:![0-9]+]] |
|
|
; ICALL-VTABLE: 3: |
|
|
; ICALL-VTABLE-NEXT: [[TMP4:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP7:%.*]] |
|
|
; ICALL-VTABLE: 5: |
|
|
; ICALL-VTABLE-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-VTABLE-NEXT: [[TMP6:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-VTABLE-NEXT: [[CALL:%.*]] = tail call i32 [[TMP6]](ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP7]] |
|
|
; ICALL-VTABLE: 7: |
|
|
; ICALL-VTABLE-NEXT: [[TMP8:%.*]] = phi i32 [ [[CALL]], [[TMP5]] ], [ [[TMP4]], [[TMP3]] ] |
|
|
; ICALL-VTABLE-NEXT: ret i32 [[TMP8]] |
|
|
; |
|
|
entry: |
|
|
%vtable = load ptr, ptr %d, !prof !7 |
|
|
%0 = tail call i1 @llvm.type.test(ptr %vtable, metadata !"_ZTS4Base") |
|
|
tail call void @llvm.assume(i1 %0) |
|
|
%vfn = getelementptr inbounds ptr, ptr %vtable, i64 1 |
|
|
%1 = load ptr, ptr %vfn |
|
|
%call = tail call i32 %1(ptr %d), !prof !5 |
|
|
ret i32 %call |
|
|
} |
|
|
|
|
|
define i32 @test_one_function_one_offset_two_vtables(ptr %d) { |
|
|
; ICALL-FUNC-LABEL: define i32 @test_one_function_one_offset_two_vtables( |
|
|
; ICALL-FUNC-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-FUNC-NEXT: entry: |
|
|
; ICALL-FUNC-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF6:![0-9]+]] |
|
|
; ICALL-FUNC-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-FUNC-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) |
|
|
; ICALL-FUNC-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-FUNC-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-FUNC-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], @_ZN4Base5func2Ev |
|
|
; ICALL-FUNC-NEXT: br i1 [[TMP2]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]], !prof [[PROF5]] |
|
|
; ICALL-FUNC: if.true.direct_targ: |
|
|
; ICALL-FUNC-NEXT: [[TMP3:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP:%.*]] |
|
|
; ICALL-FUNC: if.false.orig_indirect: |
|
|
; ICALL-FUNC-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]](ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP]] |
|
|
; ICALL-FUNC: if.end.icp: |
|
|
; ICALL-FUNC-NEXT: [[TMP4:%.*]] = phi i32 [ [[CALL]], [[IF_FALSE_ORIG_INDIRECT]] ], [ [[TMP3]], [[IF_TRUE_DIRECT_TARG]] ] |
|
|
; ICALL-FUNC-NEXT: ret i32 [[TMP4]] |
|
|
; |
|
|
; ICALL-VTABLE-LABEL: define i32 @test_one_function_one_offset_two_vtables( |
|
|
; ICALL-VTABLE-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-VTABLE-NEXT: entry: |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF6:![0-9]+]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
|
|
; ICALL-VTABLE-NEXT: [[OFFSETVAR1:%.*]] = sub nuw i64 [[TMP0]], 16 |
|
|
; ICALL-VTABLE-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-VTABLE-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) |
|
|
; ICALL-VTABLE-NEXT: [[TMP2:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV8Derived1 to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP3:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV8Derived2 to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE_CMP_OR:%.*]] = or i1 [[TMP2]], [[TMP3]] |
|
|
; ICALL-VTABLE-NEXT: br i1 [[VTABLE_CMP_OR]], label [[TMP4:%.*]], label [[TMP6:%.*]], !prof [[PROF5]] |
|
|
; ICALL-VTABLE: 4: |
|
|
; ICALL-VTABLE-NEXT: [[TMP5:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP8:%.*]] |
|
|
; ICALL-VTABLE: 6: |
|
|
; ICALL-VTABLE-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-VTABLE-NEXT: [[TMP7:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-VTABLE-NEXT: [[CALL:%.*]] = tail call i32 [[TMP7]](ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP8]] |
|
|
; ICALL-VTABLE: 8: |
|
|
; ICALL-VTABLE-NEXT: [[TMP9:%.*]] = phi i32 [ [[CALL]], [[TMP6]] ], [ [[TMP5]], [[TMP4]] ] |
|
|
; ICALL-VTABLE-NEXT: ret i32 [[TMP9]] |
|
|
; |
|
|
entry: |
|
|
%vtable = load ptr, ptr %d, !prof !6 |
|
|
%0 = tail call i1 @llvm.type.test(ptr %vtable, metadata !"_ZTS4Base") |
|
|
tail call void @llvm.assume(i1 %0) |
|
|
%vfn = getelementptr inbounds ptr, ptr %vtable, i64 1 |
|
|
%1 = load ptr, ptr %vfn |
|
|
%call = tail call i32 %1(ptr %d), !prof !5 |
|
|
ret i32 %call |
|
|
} |
|
|
|
|
|
define i32 @test_one_function_one_offset_three_vtables(ptr %d) { |
|
|
; ICALL-FUNC-LABEL: define i32 @test_one_function_one_offset_three_vtables( |
|
|
; ICALL-FUNC-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-FUNC-NEXT: entry: |
|
|
; ICALL-FUNC-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF7:![0-9]+]] |
|
|
; ICALL-FUNC-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-FUNC-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) |
|
|
; ICALL-FUNC-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-FUNC-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-FUNC-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], @_ZN4Base5func2Ev |
|
|
; ICALL-FUNC-NEXT: br i1 [[TMP2]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]], !prof [[PROF5]] |
|
|
; ICALL-FUNC: if.true.direct_targ: |
|
|
; ICALL-FUNC-NEXT: [[TMP3:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP:%.*]] |
|
|
; ICALL-FUNC: if.false.orig_indirect: |
|
|
; ICALL-FUNC-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]](ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP]] |
|
|
; ICALL-FUNC: if.end.icp: |
|
|
; ICALL-FUNC-NEXT: [[TMP4:%.*]] = phi i32 [ [[CALL]], [[IF_FALSE_ORIG_INDIRECT]] ], [ [[TMP3]], [[IF_TRUE_DIRECT_TARG]] ] |
|
|
; ICALL-FUNC-NEXT: ret i32 [[TMP4]] |
|
|
; |
|
|
; ICALL-VTABLE-LABEL: define i32 @test_one_function_one_offset_three_vtables( |
|
|
; ICALL-VTABLE-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-VTABLE-NEXT: entry: |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF7:![0-9]+]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[VTABLE]] to i64 |
|
|
; ICALL-VTABLE-NEXT: [[OFFSETVAR1:%.*]] = sub nuw i64 [[TMP0]], 16 |
|
|
; ICALL-VTABLE-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-VTABLE-NEXT: tail call void @llvm.assume(i1 [[TMP1]]) |
|
|
; ICALL-VTABLE-NEXT: [[TMP2:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV8Derived1 to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP3:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV8Derived2 to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP4:%.*]] = icmp eq i64 ptrtoint (ptr @_ZTV4Base to i64), [[OFFSETVAR1]] |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE_CMP_OR:%.*]] = or i1 [[TMP2]], [[TMP3]] |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE_CMP_OR1:%.*]] = or i1 [[VTABLE_CMP_OR]], [[TMP4]] |
|
|
; ICALL-VTABLE-NEXT: br i1 [[VTABLE_CMP_OR1]], label [[TMP5:%.*]], label [[TMP7:%.*]], !prof [[PROF8:![0-9]+]] |
|
|
; ICALL-VTABLE: 5: |
|
|
; ICALL-VTABLE-NEXT: [[TMP6:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP9:%.*]] |
|
|
; ICALL-VTABLE: 7: |
|
|
; ICALL-VTABLE-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-VTABLE-NEXT: [[TMP8:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-VTABLE-NEXT: [[CALL:%.*]] = tail call i32 [[TMP8]](ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[TMP9]] |
|
|
; ICALL-VTABLE: 9: |
|
|
; ICALL-VTABLE-NEXT: [[TMP10:%.*]] = phi i32 [ [[CALL]], [[TMP7]] ], [ [[TMP6]], [[TMP5]] ] |
|
|
; ICALL-VTABLE-NEXT: ret i32 [[TMP10]] |
|
|
; |
|
|
entry: |
|
|
%vtable = load ptr, ptr %d, !prof !4 |
|
|
%0 = tail call i1 @llvm.type.test(ptr %vtable, metadata !"_ZTS4Base") |
|
|
tail call void @llvm.assume(i1 %0) |
|
|
%vfn = getelementptr inbounds ptr, ptr %vtable, i64 1 |
|
|
%1 = load ptr, ptr %vfn |
|
|
%call = tail call i32 %1(ptr %d), !prof !5 |
|
|
ret i32 %call |
|
|
} |
|
|
|
|
|
define i32 @test_one_function_one_offset_four_vtables(ptr %d) { |
|
|
; ICALL-FUNC-LABEL: define i32 @test_one_function_one_offset_four_vtables( |
|
|
; ICALL-FUNC-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-FUNC-NEXT: entry: |
|
|
; ICALL-FUNC-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF8:![0-9]+]] |
|
|
; ICALL-FUNC-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-FUNC-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) |
|
|
; ICALL-FUNC-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-FUNC-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-FUNC-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], @_ZN4Base5func2Ev |
|
|
; ICALL-FUNC-NEXT: br i1 [[TMP2]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]], !prof [[PROF5]] |
|
|
; ICALL-FUNC: if.true.direct_targ: |
|
|
; ICALL-FUNC-NEXT: [[TMP3:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP:%.*]] |
|
|
; ICALL-FUNC: if.false.orig_indirect: |
|
|
; ICALL-FUNC-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]](ptr [[D]]) |
|
|
; ICALL-FUNC-NEXT: br label [[IF_END_ICP]] |
|
|
; ICALL-FUNC: if.end.icp: |
|
|
; ICALL-FUNC-NEXT: [[TMP4:%.*]] = phi i32 [ [[CALL]], [[IF_FALSE_ORIG_INDIRECT]] ], [ [[TMP3]], [[IF_TRUE_DIRECT_TARG]] ] |
|
|
; ICALL-FUNC-NEXT: ret i32 [[TMP4]] |
|
|
; |
|
|
; ICALL-VTABLE-LABEL: define i32 @test_one_function_one_offset_four_vtables( |
|
|
; ICALL-VTABLE-SAME: ptr [[D:%.*]]) { |
|
|
; ICALL-VTABLE-NEXT: entry: |
|
|
; ICALL-VTABLE-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[D]], align 8, !prof [[PROF9:![0-9]+]] |
|
|
; ICALL-VTABLE-NEXT: [[TMP0:%.*]] = tail call i1 @llvm.type.test(ptr [[VTABLE]], metadata !"_ZTS4Base") |
|
|
; ICALL-VTABLE-NEXT: tail call void @llvm.assume(i1 [[TMP0]]) |
|
|
; ICALL-VTABLE-NEXT: [[VFN:%.*]] = getelementptr inbounds ptr, ptr [[VTABLE]], i64 1 |
|
|
; ICALL-VTABLE-NEXT: [[TMP1:%.*]] = load ptr, ptr [[VFN]], align 8 |
|
|
; ICALL-VTABLE-NEXT: [[TMP2:%.*]] = icmp eq ptr [[TMP1]], @_ZN4Base5func2Ev |
|
|
; ICALL-VTABLE-NEXT: br i1 [[TMP2]], label [[IF_TRUE_DIRECT_TARG:%.*]], label [[IF_FALSE_ORIG_INDIRECT:%.*]], !prof [[PROF5]] |
|
|
; ICALL-VTABLE: if.true.direct_targ: |
|
|
; ICALL-VTABLE-NEXT: [[TMP3:%.*]] = tail call i32 @_ZN4Base5func2Ev(ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[IF_END_ICP:%.*]] |
|
|
; ICALL-VTABLE: if.false.orig_indirect: |
|
|
; ICALL-VTABLE-NEXT: [[CALL:%.*]] = tail call i32 [[TMP1]](ptr [[D]]) |
|
|
; ICALL-VTABLE-NEXT: br label [[IF_END_ICP]] |
|
|
; ICALL-VTABLE: if.end.icp: |
|
|
; ICALL-VTABLE-NEXT: [[TMP4:%.*]] = phi i32 [ [[CALL]], [[IF_FALSE_ORIG_INDIRECT]] ], [ [[TMP3]], [[IF_TRUE_DIRECT_TARG]] ] |
|
|
; ICALL-VTABLE-NEXT: ret i32 [[TMP4]] |
|
|
; |
|
|
entry: |
|
|
%vtable = load ptr, ptr %d, !prof !8 |
|
|
%0 = tail call i1 @llvm.type.test(ptr %vtable, metadata !"_ZTS4Base") |
|
|
tail call void @llvm.assume(i1 %0) |
|
|
%vfn = getelementptr inbounds ptr, ptr %vtable, i64 1 |
|
|
%1 = load ptr, ptr %vfn |
|
|
%call = tail call i32 %1(ptr %d), !prof !5 |
|
|
ret i32 %call |
|
|
} |
|
|
|
|
|
declare i1 @llvm.type.test(ptr, metadata) |
|
|
declare void @llvm.assume(i1 noundef) |
|
|
declare i32 @_ZN4Base5func1Ei(ptr, i32) |
|
|
declare i32 @_ZN8Derived15func1Ei(ptr, i32) |
|
|
declare i32 @_ZN8Derived25func1Ei(ptr, i32) |
|
|
declare i32 @_ZN8Derived35func1Ei(ptr, i32) |
|
|
|
|
|
define i32 @_ZN4Base5func2Ev(ptr %this) { |
|
|
; ICALL-FUNC-LABEL: define i32 @_ZN4Base5func2Ev( |
|
|
; ICALL-FUNC-SAME: ptr [[THIS:%.*]]) { |
|
|
; ICALL-FUNC-NEXT: entry: |
|
|
; ICALL-FUNC-NEXT: ret i32 0 |
|
|
; |
|
|
; ICALL-VTABLE-LABEL: define i32 @_ZN4Base5func2Ev( |
|
|
; ICALL-VTABLE-SAME: ptr [[THIS:%.*]]) { |
|
|
; ICALL-VTABLE-NEXT: entry: |
|
|
; ICALL-VTABLE-NEXT: ret i32 0 |
|
|
; |
|
|
entry: |
|
|
ret i32 0 |
|
|
} |
|
|
|
|
|
!0 = !{i64 16, !"_ZTS4Base"} |
|
|
!1 = !{i64 16, !"_ZTS8Derived1"} |
|
|
!2 = !{i64 16, !"_ZTS8Derived2"} |
|
|
!3 = !{i64 16, !"_ZTS8Derived3"} |
|
|
!4 = !{!"VP", i32 2, i64 1600, i64 -9064381665493407289, i64 600, i64 5035968517245772950, i64 550, i64 1960855528937986108, i64 500} |
|
|
!5 = !{!"VP", i32 0, i64 1600, i64 -3104805163612457913, i64 1600} |
|
|
!6 = !{!"VP", i32 2, i64 1600, i64 -9064381665493407289, i64 1000, i64 5035968517245772950, i64 600} |
|
|
!7 = !{!"VP", i32 2, i64 1600, i64 5035968517245772950, i64 1600} |
|
|
!8 = !{!"VP", i32 2, i64 1600, i64 -9064381665493407289, i64 550, i64 5035968517245772950, i64 450, i64 1960855528937986108, i64 310, i64 -3121110164882083017, i64 290} |