121 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt -passes=tailcallelim -S %s -o - | FileCheck %s --check-prefixes=CHECK,ENABLED3; RUN: opt -passes=tailcallelim -tre-disable-entrycount-recompute -S %s -o - | FileCheck %s --check-prefixes=CHECK,DISABLED4 5; Test that tail call elimination correctly adjusts function entry counts6; when eliminating tail recursive calls.7 8; Basic test: eliminate a tail call and adjust entry count9define i32 @test_basic_entry_count_adjustment(i32 %n) !prof !0 {10; CHECK-LABEL: @test_basic_entry_count_adjustment(11; CHECK-NEXT: entry:12; CHECK-NEXT: br label [[TAILRECURSE:%.*]]13; CHECK: tailrecurse:14; CHECK-NEXT: [[N_TR:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[IF_THEN:%.*]] ]15; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N_TR]], 016; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[IF_ELSE:%.*]], !prof [[PROF1:![0-9]+]]17; CHECK: if.then:18; CHECK-NEXT: [[SUB]] = sub i32 [[N_TR]], 119; CHECK-NEXT: br label [[TAILRECURSE]]20; CHECK: if.else:21; CHECK-NEXT: ret i32 022;23entry:24 %cmp = icmp sgt i32 %n, 025 br i1 %cmp, label %if.then, label %if.else, !prof !126 27if.then: ; preds = %entry28 %sub = sub i32 %n, 129 %call = tail call i32 @test_basic_entry_count_adjustment(i32 %sub)30 ret i32 %call31 32if.else: ; preds = %entry33 ret i32 034}35 36; Test multiple tail calls in different blocks with different frequencies37define i32 @test_multiple_blocks_entry_count(i32 %n, i32 %flag) !prof !2 {38; CHECK-LABEL: @test_multiple_blocks_entry_count(39; CHECK-NEXT: entry:40; CHECK-NEXT: br label [[TAILRECURSE:%.*]]41; CHECK: tailrecurse:42; CHECK-NEXT: [[N_TR:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[SUB1:%.*]], [[BLOCK1:%.*]] ], [ [[SUB2:%.*]], [[BLOCK2:%.*]] ]43; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N_TR]], 044; CHECK-NEXT: br i1 [[CMP]], label [[CHECK_FLAG:%.*]], label [[BASE_CASE:%.*]], !prof [[PROF3:![0-9]+]]45; CHECK: check.flag:46; CHECK-NEXT: [[CMP_FLAG:%.*]] = icmp eq i32 [[FLAG:%.*]], 147; CHECK-NEXT: br i1 [[CMP_FLAG]], label [[BLOCK1]], label [[BLOCK2]], !prof [[PROF4:![0-9]+]]48; CHECK: block1:49; CHECK-NEXT: [[SUB1]] = sub i32 [[N_TR]], 150; CHECK-NEXT: br label [[TAILRECURSE]]51; CHECK: block2:52; CHECK-NEXT: [[SUB2]] = sub i32 [[N_TR]], 253; CHECK-NEXT: br label [[TAILRECURSE]]54; CHECK: base.case:55; CHECK-NEXT: ret i32 156;57entry:58 %cmp = icmp sgt i32 %n, 059 br i1 %cmp, label %check.flag, label %base.case, !prof !360check.flag:61 %cmp.flag = icmp eq i32 %flag, 162 br i1 %cmp.flag, label %block1, label %block2, !prof !463block1: ; preds = %check.flag64 %sub1 = sub i32 %n, 165 %call1 = tail call i32 @test_multiple_blocks_entry_count(i32 %sub1, i32 %flag)66 ret i32 %call167block2: ; preds = %check.flag68 %sub2 = sub i32 %n, 269 %call2 = tail call i32 @test_multiple_blocks_entry_count(i32 %sub2, i32 %flag)70 ret i32 %call271base.case: ; preds = %entry72 ret i32 173}74 75define i32 @test_no_entry_count(i32 %n) {76; CHECK-LABEL: @test_no_entry_count(77; CHECK-NEXT: entry:78; CHECK-NEXT: br label [[TAILRECURSE:%.*]]79; CHECK: tailrecurse:80; CHECK-NEXT: [[N_TR:%.*]] = phi i32 [ [[N:%.*]], [[ENTRY:%.*]] ], [ [[SUB:%.*]], [[IF_THEN:%.*]] ]81; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N_TR]], 082; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[IF_ELSE:%.*]]83; CHECK: if.then:84; CHECK-NEXT: [[SUB]] = sub i32 [[N_TR]], 185; CHECK-NEXT: br label [[TAILRECURSE]]86; CHECK: if.else:87; CHECK-NEXT: ret i32 088;89entry:90 %cmp = icmp sgt i32 %n, 091 br i1 %cmp, label %if.then, label %if.else92 93if.then: ; preds = %entry94 %sub = sub i32 %n, 195 %call = tail call i32 @test_no_entry_count(i32 %sub)96 ret i32 %call97 98if.else: ; preds = %entry99 ret i32 0100}101 102; Function entry count metadata103!0 = !{!"function_entry_count", i64 1000}104!1 = !{!"branch_weights", i32 800, i32 200}105!2 = !{!"function_entry_count", i64 2000}106!3 = !{!"branch_weights", i32 3, i32 1}107!4 = !{!"branch_weights", i32 100, i32 900}108;.109; ENABLED: [[META0:![0-9]+]] = !{!"function_entry_count", i64 200}110; ENABLED: [[PROF1]] = !{!"branch_weights", i32 800, i32 200}111; ENABLED: [[META2:![0-9]+]] = !{!"function_entry_count", i64 500}112; ENABLED: [[PROF3]] = !{!"branch_weights", i32 3, i32 1}113; ENABLED: [[PROF4]] = !{!"branch_weights", i32 100, i32 900}114;.115; DISABLED: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}116; DISABLED: [[PROF1]] = !{!"branch_weights", i32 800, i32 200}117; DISABLED: [[META2:![0-9]+]] = !{!"function_entry_count", i64 2000}118; DISABLED: [[PROF3]] = !{!"branch_weights", i32 3, i32 1}119; DISABLED: [[PROF4]] = !{!"branch_weights", i32 100, i32 900}120;.121