xref: /llvm-project/llvm/test/Transforms/GuardWidening/loop-schedule.ll (revision 0b5bb6923f09ebc257ebed4ace1d8b6b113b2bf5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes='licm,guard-widening,licm' -verify-memoryssa -debug-pass-manager < %s 2>&1 | FileCheck %s
3
4; Main point of this test is to check the scheduling -- there should be
5; no analysis passes needed between LICM and LoopGuardWidening
6
7; CHECK: LICMPass
8; CHECK-NEXT: GuardWideningPass
9; CHECK-NEXT: LICMPass
10
11declare void @llvm.experimental.guard(i1,...)
12
13define void @iter(i32 %a, i32 %b, ptr %c_p) {
14; CHECK-LABEL: @iter(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
17; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
18; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
19; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
20; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
21; CHECK-NEXT:    [[CND:%.*]] = load i1, ptr [[C_P:%.*]], align 1
22; CHECK-NEXT:    br label [[LOOP:%.*]]
23; CHECK:       loop:
24; CHECK-NEXT:    br i1 [[CND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
25; CHECK:       leave.loopexit:
26; CHECK-NEXT:    br label [[LEAVE:%.*]]
27; CHECK:       leave:
28; CHECK-NEXT:    ret void
29;
30
31entry:
32  %cond_0 = icmp ult i32 %a, 10
33  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
34  br label %loop
35
36loop:                                             ; preds = %loop.preheader, %loop
37  %cond_1 = icmp ult i32 %b, 10
38  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
39  %cnd = load i1, ptr %c_p
40  br i1 %cnd, label %loop, label %leave.loopexit
41
42leave.loopexit:                                   ; preds = %loop
43  br label %leave
44
45leave:                                            ; preds = %leave.loopexit, %entry
46  ret void
47}
48
49define void @within_loop(i32 %a, i32 %b, ptr %c_p) {
50; CHECK-LABEL: @within_loop(
51; CHECK-NEXT:  entry:
52; CHECK-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B:%.*]]
53; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
54; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B_GW_FR]], 10
55; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
56; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
57; CHECK-NEXT:    [[CND:%.*]] = load i1, ptr [[C_P:%.*]], align 1
58; CHECK-NEXT:    br label [[LOOP:%.*]]
59; CHECK:       loop:
60; CHECK-NEXT:    br i1 [[CND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
61; CHECK:       leave.loopexit:
62; CHECK-NEXT:    br label [[LEAVE:%.*]]
63; CHECK:       leave:
64; CHECK-NEXT:    ret void
65;
66
67entry:
68  br label %loop
69
70loop:                                             ; preds = %loop.preheader, %loop
71  %cond_0 = icmp ult i32 %a, 10
72  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
73  %cond_1 = icmp ult i32 %b, 10
74  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
75  %cnd = load i1, ptr %c_p
76  br i1 %cnd, label %loop, label %leave.loopexit
77
78leave.loopexit:                                   ; preds = %loop
79  br label %leave
80
81leave:                                            ; preds = %leave.loopexit, %entry
82  ret void
83}
84
85