1a7dcf39fSMax Kazantsev; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2a7dcf39fSMax Kazantsev; RUN: opt -S -passes=guard-widening < %s | FileCheck %s 3a7dcf39fSMax Kazantsev 4a7dcf39fSMax Kazantsev; Function Attrs: nocallback nofree nosync willreturn 5a7dcf39fSMax Kazantsevdeclare void @llvm.experimental.guard(i1, ...) #0 6a7dcf39fSMax Kazantsev 7a7dcf39fSMax Kazantsev; Hot loop, frequently entered, should widen. 8a7dcf39fSMax Kazantsevdefine i32 @test_intrinsic_very_profitable(i32 %n, i1 %cond.1, i1 %cond.2) { 9a7dcf39fSMax Kazantsev; CHECK-LABEL: define i32 @test_intrinsic_very_profitable 10a7dcf39fSMax Kazantsev; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) { 11a7dcf39fSMax Kazantsev; CHECK-NEXT: entry: 12*0b5bb692SSerguei Katkov; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]] 13*0b5bb692SSerguei Katkov; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]] 14a7dcf39fSMax Kazantsev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] 15a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_PRECONDITION:%.*]] = icmp uge i32 [[N]], 100 16a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_PRECONDITION]], label [[LOOP:%.*]], label [[FAILED:%.*]], !prof [[PROF0:![0-9]+]] 17a7dcf39fSMax Kazantsev; CHECK: loop: 18a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 19a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 20a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100 21a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]], !prof [[PROF1:![0-9]+]] 22a7dcf39fSMax Kazantsev; CHECK: exit: 23a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 0 24a7dcf39fSMax Kazantsev; CHECK: failed: 25a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 -1 26a7dcf39fSMax Kazantsev; 27a7dcf39fSMax Kazantseventry: 28a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.1) [ "deopt"() ] 29a7dcf39fSMax Kazantsev %loop.precondition = icmp uge i32 %n, 100 30a7dcf39fSMax Kazantsev br i1 %loop.precondition, label %loop, label %failed, !prof !0 31a7dcf39fSMax Kazantsev 32a7dcf39fSMax Kazantsevloop: ; preds = %loop, %entry 33a7dcf39fSMax Kazantsev %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 34a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.2) [ "deopt"() ] 35a7dcf39fSMax Kazantsev %iv.next = add nuw nsw i32 %iv, 1 36a7dcf39fSMax Kazantsev %loop.cond = icmp ult i32 %iv.next, 100 37a7dcf39fSMax Kazantsev br i1 %loop.cond, label %loop, label %exit, !prof !1 38a7dcf39fSMax Kazantsev 39a7dcf39fSMax Kazantsevexit: ; preds = %loop 40a7dcf39fSMax Kazantsev ret i32 0 41a7dcf39fSMax Kazantsev 42a7dcf39fSMax Kazantsevfailed: ; preds = %entry 43a7dcf39fSMax Kazantsev ret i32 -1 44a7dcf39fSMax Kazantsev} 45a7dcf39fSMax Kazantsev 46a7dcf39fSMax Kazantsev; Even though the loop is rarely entered, it has so many iterations that the widening 47a7dcf39fSMax Kazantsev; is still profitable. 48a7dcf39fSMax Kazantsevdefine i32 @test_intrinsic_profitable(i32 %n, i1 %cond.1, i1 %cond.2) { 49a7dcf39fSMax Kazantsev; CHECK-LABEL: define i32 @test_intrinsic_profitable 50a7dcf39fSMax Kazantsev; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) { 51a7dcf39fSMax Kazantsev; CHECK-NEXT: entry: 52*0b5bb692SSerguei Katkov; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]] 53*0b5bb692SSerguei Katkov; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]] 54a7dcf39fSMax Kazantsev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] 55a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_PRECONDITION:%.*]] = icmp uge i32 [[N]], 100 56a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_PRECONDITION]], label [[LOOP:%.*]], label [[FAILED:%.*]], !prof [[PROF2:![0-9]+]] 57a7dcf39fSMax Kazantsev; CHECK: loop: 58a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 59a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 60a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100 61a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]], !prof [[PROF1]] 62a7dcf39fSMax Kazantsev; CHECK: exit: 63a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 0 64a7dcf39fSMax Kazantsev; CHECK: failed: 65a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 -1 66a7dcf39fSMax Kazantsev; 67a7dcf39fSMax Kazantseventry: 68a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.1) [ "deopt"() ] 69a7dcf39fSMax Kazantsev %loop.precondition = icmp uge i32 %n, 100 70a7dcf39fSMax Kazantsev br i1 %loop.precondition, label %loop, label %failed, !prof !2 71a7dcf39fSMax Kazantsev 72a7dcf39fSMax Kazantsevloop: ; preds = %loop, %entry 73a7dcf39fSMax Kazantsev %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 74a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.2) [ "deopt"() ] 75a7dcf39fSMax Kazantsev %iv.next = add nuw nsw i32 %iv, 1 76a7dcf39fSMax Kazantsev %loop.cond = icmp ult i32 %iv.next, 100 77a7dcf39fSMax Kazantsev br i1 %loop.cond, label %loop, label %exit, !prof !1 78a7dcf39fSMax Kazantsev 79a7dcf39fSMax Kazantsevexit: ; preds = %loop 80a7dcf39fSMax Kazantsev ret i32 0 81a7dcf39fSMax Kazantsev 82a7dcf39fSMax Kazantsevfailed: ; preds = %entry 83a7dcf39fSMax Kazantsev ret i32 -1 84a7dcf39fSMax Kazantsev} 85a7dcf39fSMax Kazantsev 86a7dcf39fSMax Kazantsev; Loop's hotness compensates rareness of its entrance. We still want to widen, because 87a7dcf39fSMax Kazantsev; it may open up some optimization opportunities. 88a7dcf39fSMax Kazantsevdefine i32 @test_intrinsic_neutral(i32 %n, i1 %cond.1, i1 %cond.2) { 89a7dcf39fSMax Kazantsev; CHECK-LABEL: define i32 @test_intrinsic_neutral 90a7dcf39fSMax Kazantsev; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) { 91a7dcf39fSMax Kazantsev; CHECK-NEXT: entry: 92*0b5bb692SSerguei Katkov; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]] 93*0b5bb692SSerguei Katkov; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]] 94a7dcf39fSMax Kazantsev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] 95a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_PRECONDITION:%.*]] = icmp uge i32 [[N]], 100 96a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_PRECONDITION]], label [[LOOP:%.*]], label [[FAILED:%.*]], !prof [[PROF3:![0-9]+]] 97a7dcf39fSMax Kazantsev; CHECK: loop: 98a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 99a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 100a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100 101a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]], !prof [[PROF1]] 102a7dcf39fSMax Kazantsev; CHECK: exit: 103a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 0 104a7dcf39fSMax Kazantsev; CHECK: failed: 105a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 -1 106a7dcf39fSMax Kazantsev; 107a7dcf39fSMax Kazantseventry: 108a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.1) [ "deopt"() ] 109a7dcf39fSMax Kazantsev %loop.precondition = icmp uge i32 %n, 100 110a7dcf39fSMax Kazantsev br i1 %loop.precondition, label %loop, label %failed, !prof !3 111a7dcf39fSMax Kazantsev 112a7dcf39fSMax Kazantsevloop: ; preds = %loop, %entry 113a7dcf39fSMax Kazantsev %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 114a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.2) [ "deopt"() ] 115a7dcf39fSMax Kazantsev %iv.next = add nuw nsw i32 %iv, 1 116a7dcf39fSMax Kazantsev %loop.cond = icmp ult i32 %iv.next, 100 117a7dcf39fSMax Kazantsev br i1 %loop.cond, label %loop, label %exit, !prof !1 118a7dcf39fSMax Kazantsev 119a7dcf39fSMax Kazantsevexit: ; preds = %loop 120a7dcf39fSMax Kazantsev ret i32 0 121a7dcf39fSMax Kazantsev 122a7dcf39fSMax Kazantsevfailed: ; preds = %entry 123a7dcf39fSMax Kazantsev ret i32 -1 124a7dcf39fSMax Kazantsev} 125a7dcf39fSMax Kazantsev 126a7dcf39fSMax Kazantsev; FIXME: This loop is so rarely entered, that we don't want to widen here. 127a7dcf39fSMax Kazantsevdefine i32 @test_intrinsic_very_unprofitable(i32 %n, i1 %cond.1, i1 %cond.2) { 128a7dcf39fSMax Kazantsev; CHECK-LABEL: define i32 @test_intrinsic_very_unprofitable 129a7dcf39fSMax Kazantsev; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) { 130a7dcf39fSMax Kazantsev; CHECK-NEXT: entry: 131*0b5bb692SSerguei Katkov; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]] 132*0b5bb692SSerguei Katkov; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]] 133a7dcf39fSMax Kazantsev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] 134a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_PRECONDITION:%.*]] = icmp uge i32 [[N]], 100 135a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_PRECONDITION]], label [[LOOP:%.*]], label [[FAILED:%.*]], !prof [[PROF4:![0-9]+]] 136a7dcf39fSMax Kazantsev; CHECK: loop: 137a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 138a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 139a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100 140a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]], !prof [[PROF1]] 141a7dcf39fSMax Kazantsev; CHECK: exit: 142a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 0 143a7dcf39fSMax Kazantsev; CHECK: failed: 144a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 -1 145a7dcf39fSMax Kazantsev; 146a7dcf39fSMax Kazantseventry: 147a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.1) [ "deopt"() ] 148a7dcf39fSMax Kazantsev %loop.precondition = icmp uge i32 %n, 100 149a7dcf39fSMax Kazantsev br i1 %loop.precondition, label %loop, label %failed, !prof !4 150a7dcf39fSMax Kazantsev 151a7dcf39fSMax Kazantsevloop: ; preds = %loop, %entry 152a7dcf39fSMax Kazantsev %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 153a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.2) [ "deopt"() ] 154a7dcf39fSMax Kazantsev %iv.next = add nuw nsw i32 %iv, 1 155a7dcf39fSMax Kazantsev %loop.cond = icmp ult i32 %iv.next, 100 156a7dcf39fSMax Kazantsev br i1 %loop.cond, label %loop, label %exit, !prof !1 157a7dcf39fSMax Kazantsev 158a7dcf39fSMax Kazantsevexit: ; preds = %loop 159a7dcf39fSMax Kazantsev ret i32 0 160a7dcf39fSMax Kazantsev 161a7dcf39fSMax Kazantsevfailed: ; preds = %entry 162a7dcf39fSMax Kazantsev ret i32 -1 163a7dcf39fSMax Kazantsev} 164a7dcf39fSMax Kazantsev 165a7dcf39fSMax Kazantsev; FIXME: This loop is so rarely entered, that we don't want to widen here. 166a7dcf39fSMax Kazantsevdefine i32 @test_intrinsic_unprofitable(i32 %n, i1 %cond.1, i1 %cond.2) { 167a7dcf39fSMax Kazantsev; CHECK-LABEL: define i32 @test_intrinsic_unprofitable 168a7dcf39fSMax Kazantsev; CHECK-SAME: (i32 [[N:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) { 169a7dcf39fSMax Kazantsev; CHECK-NEXT: entry: 170*0b5bb692SSerguei Katkov; CHECK-NEXT: [[COND_2_GW_FR:%.*]] = freeze i1 [[COND_2]] 171*0b5bb692SSerguei Katkov; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[COND_1]], [[COND_2_GW_FR]] 172a7dcf39fSMax Kazantsev; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] 173a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_PRECONDITION:%.*]] = icmp uge i32 [[N]], 100 174a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_PRECONDITION]], label [[LOOP:%.*]], label [[FAILED:%.*]], !prof [[PROF5:![0-9]+]] 175a7dcf39fSMax Kazantsev; CHECK: loop: 176a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] 177a7dcf39fSMax Kazantsev; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 178a7dcf39fSMax Kazantsev; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 100 179a7dcf39fSMax Kazantsev; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]], !prof [[PROF1]] 180a7dcf39fSMax Kazantsev; CHECK: exit: 181a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 0 182a7dcf39fSMax Kazantsev; CHECK: failed: 183a7dcf39fSMax Kazantsev; CHECK-NEXT: ret i32 -1 184a7dcf39fSMax Kazantsev; 185a7dcf39fSMax Kazantseventry: 186a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.1) [ "deopt"() ] 187a7dcf39fSMax Kazantsev %loop.precondition = icmp uge i32 %n, 100 188a7dcf39fSMax Kazantsev br i1 %loop.precondition, label %loop, label %failed, !prof !5 189a7dcf39fSMax Kazantsev 190a7dcf39fSMax Kazantsevloop: ; preds = %loop, %entry 191a7dcf39fSMax Kazantsev %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] 192a7dcf39fSMax Kazantsev call void (i1, ...) @llvm.experimental.guard(i1 %cond.2) [ "deopt"() ] 193a7dcf39fSMax Kazantsev %iv.next = add nuw nsw i32 %iv, 1 194a7dcf39fSMax Kazantsev %loop.cond = icmp ult i32 %iv.next, 100 195a7dcf39fSMax Kazantsev br i1 %loop.cond, label %loop, label %exit, !prof !1 196a7dcf39fSMax Kazantsev 197a7dcf39fSMax Kazantsevexit: ; preds = %loop 198a7dcf39fSMax Kazantsev ret i32 0 199a7dcf39fSMax Kazantsev 200a7dcf39fSMax Kazantsevfailed: ; preds = %entry 201a7dcf39fSMax Kazantsev ret i32 -1 202a7dcf39fSMax Kazantsev} 203a7dcf39fSMax Kazantsev 204a7dcf39fSMax Kazantsevattributes #0 = { nocallback nofree nosync willreturn } 205a7dcf39fSMax Kazantsev 206a7dcf39fSMax Kazantsev!0 = !{!"branch_weights", i32 1048576, i32 1} 207a7dcf39fSMax Kazantsev!1 = !{!"branch_weights", i32 99, i32 1} 208a7dcf39fSMax Kazantsev!2 = !{!"branch_weights", i32 1, i32 10} 209a7dcf39fSMax Kazantsev!3 = !{!"branch_weights", i32 1, i32 99} 210a7dcf39fSMax Kazantsev!4 = !{!"branch_weights", i32 1, i32 1048576} 211a7dcf39fSMax Kazantsev!5 = !{!"branch_weights", i32 1, i32 1000} 212