| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -S -passes=mergefunc < %s | FileCheck %s |
| ; |
| |
| ; Verify that MergeFunctions correctly combines select-instruction |
| ; branch_weights when merging two structurally identical functions. |
| ; Since FunctionComparator only considers functions equal when their |
| ; control-flow graphs and instruction order match exactly, MergeFunctions |
| ; can safely walk both functions in parallel and merge any instruction-level |
| ; metadata it encounters. |
| ; |
| ; The functions sel_a and sel_b differ only in their entry counts and |
| ; select branch_weights. When merged, the pass first converts each |
| ; function's relative branch weights into absolute execution counts using |
| ; its entry count, and then adds the counts together to produce the |
| ; final merged weights. |
| ; |
| ; sel_a: entry 50, weights 10:90 -> true=5, false=45 |
| ; sel_b: entry 150, weights 30:70 -> true=45, false=105 |
| ; Merged: true=5+45=50, false=45+105=150 |
| |
| define internal i32 @sel_a(i32 %x) !prof !1 { |
| ; CHECK-LABEL: define internal i32 @sel_a( |
| ; CHECK-SAME: i32 [[X:%.*]]) !prof [[PROF0:![0-9]+]] { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 0 |
| ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 0, !prof [[PROF1:![0-9]+]] |
| ; CHECK-NEXT: ret i32 [[SEL]] |
| ; |
| entry: |
| %cmp = icmp slt i32 %x, 0 |
| %sel = select i1 %cmp, i32 1, i32 0, !prof !2 |
| ret i32 %sel |
| } |
| |
| define internal i32 @sel_b(i32 %x) !prof !3 { |
| entry: |
| %cmp = icmp slt i32 %x, 0 |
| %sel = select i1 %cmp, i32 1, i32 0, !prof !4 |
| ret i32 %sel |
| } |
| |
| !1 = !{!"function_entry_count", i64 50} |
| !2 = !{!"branch_weights", i32 10, i32 90} |
| !3 = !{!"function_entry_count", i64 150} |
| !4 = !{!"branch_weights", i32 30, i32 70} |
| ;. |
| ; CHECK: [[PROF0]] = !{!"function_entry_count", i64 200} |
| ; CHECK: [[PROF1]] = !{!"branch_weights", i32 50, i32 150} |
| ;. |