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, i1* %c_p) {
14; CHECK-LABEL: @iter(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
17; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
18; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
19; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
20; CHECK-NEXT:    [[CND:%.*]] = load i1, i1* [[C_P:%.*]], align 1
21; CHECK-NEXT:    br label [[LOOP:%.*]]
22; CHECK:       loop:
23; CHECK-NEXT:    br i1 [[CND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
24; CHECK:       leave.loopexit:
25; CHECK-NEXT:    br label [[LEAVE:%.*]]
26; CHECK:       leave:
27; CHECK-NEXT:    ret void
28;
29
30entry:
31  %cond_0 = icmp ult i32 %a, 10
32  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
33  br label %loop
34
35loop:                                             ; preds = %loop.preheader, %loop
36  %cond_1 = icmp ult i32 %b, 10
37  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
38  %cnd = load i1, i1* %c_p
39  br i1 %cnd, label %loop, label %leave.loopexit
40
41leave.loopexit:                                   ; preds = %loop
42  br label %leave
43
44leave:                                            ; preds = %leave.loopexit, %entry
45  ret void
46}
47
48define void @within_loop(i32 %a, i32 %b, i1* %c_p) {
49; CHECK-LABEL: @within_loop(
50; CHECK-NEXT:  entry:
51; CHECK-NEXT:    [[COND_0:%.*]] = icmp ult i32 [[A:%.*]], 10
52; CHECK-NEXT:    [[COND_1:%.*]] = icmp ult i32 [[B:%.*]], 10
53; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0]], [[COND_1]]
54; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]
55; CHECK-NEXT:    [[CND:%.*]] = load i1, i1* [[C_P:%.*]], align 1
56; CHECK-NEXT:    br label [[LOOP:%.*]]
57; CHECK:       loop:
58; CHECK-NEXT:    br i1 [[CND]], label [[LOOP]], label [[LEAVE_LOOPEXIT:%.*]]
59; CHECK:       leave.loopexit:
60; CHECK-NEXT:    br label [[LEAVE:%.*]]
61; CHECK:       leave:
62; CHECK-NEXT:    ret void
63;
64
65entry:
66  br label %loop
67
68loop:                                             ; preds = %loop.preheader, %loop
69  %cond_0 = icmp ult i32 %a, 10
70  call void (i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"() ]
71  %cond_1 = icmp ult i32 %b, 10
72  call void (i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"() ]
73  %cnd = load i1, i1* %c_p
74  br i1 %cnd, label %loop, label %leave.loopexit
75
76leave.loopexit:                                   ; preds = %loop
77  br label %leave
78
79leave:                                            ; preds = %leave.loopexit, %entry
80  ret void
81}
82
83