[ThinLTO] Add code comment. NFC
[llvm-complete.git] / test / Transforms / GuardWidening / basic-loop.ll
blob8129a789f33b03609cb568e3933494eb39e19b58
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -loop-guard-widening < %s        | FileCheck %s
3 ; RUN: opt -S -passes="loop(guard-widening)" < %s | FileCheck %s
5 declare void @llvm.experimental.guard(i1,...)
7 @G = external global i32
9 ; Show that we can widen into early checks within a loop, and in the process
10 ; expose optimization oppurtunities.
11 define void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
12 ; CHECK-LABEL: @widen_within_loop(
13 ; CHECK-NEXT:  entry:
14 ; CHECK-NEXT:    br label [[LOOP:%.*]]
15 ; CHECK:       loop:
16 ; CHECK-NEXT:    store i32 0, i32* @G
17 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
18 ; CHECK-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
19 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
20 ; CHECK-NEXT:    store i32 1, i32* @G
21 ; CHECK-NEXT:    store i32 2, i32* @G
22 ; CHECK-NEXT:    store i32 3, i32* @G
23 ; CHECK-NEXT:    br label [[LOOP]]
25 entry:
26   br label %loop
28 loop:
29   store i32 0, i32* @G
30   call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
31   store i32 1, i32* @G
32   call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
33   store i32 2, i32* @G
34   call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
35   store i32 3, i32* @G
36   br label %loop
39 define void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
40 ; CHECK-LABEL: @widen_into_preheader(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    store i32 0, i32* @G
43 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
44 ; CHECK-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
45 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
46 ; CHECK-NEXT:    br label [[LOOP:%.*]]
47 ; CHECK:       loop:
48 ; CHECK-NEXT:    store i32 1, i32* @G
49 ; CHECK-NEXT:    store i32 2, i32* @G
50 ; CHECK-NEXT:    store i32 3, i32* @G
51 ; CHECK-NEXT:    br label [[LOOP]]
53 entry:
54   store i32 0, i32* @G
55   call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
56   br label %loop
58 loop:
59   store i32 1, i32* @G
60   call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
61   store i32 2, i32* @G
62   call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
63   store i32 3, i32* @G
64   br label %loop
67 define void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
68 ; CHECK-LABEL: @dont_widen_over_common_exit(
69 ; CHECK-NEXT:  entry:
70 ; CHECK-NEXT:    br label [[LOOP:%.*]]
71 ; CHECK:       loop:
72 ; CHECK-NEXT:    store i32 0, i32* @G
73 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ]
74 ; CHECK-NEXT:    store i32 1, i32* @G
75 ; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
76 ; CHECK:       backedge:
77 ; CHECK-NEXT:    store i32 2, i32* @G
78 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ]
79 ; CHECK-NEXT:    store i32 3, i32* @G
80 ; CHECK-NEXT:    br label [[LOOP]]
81 ; CHECK:       exit:
82 ; CHECK-NEXT:    ret void
84 entry:
85   br label %loop
87 loop:
88   store i32 0, i32* @G
89   call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
90   store i32 1, i32* @G
91   br i1 %cond_1, label %backedge, label %exit
93 backedge:
94   store i32 2, i32* @G
95   call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
96   store i32 3, i32* @G
97   br label %loop
99 exit:
100   ret void
103 define void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
104 ; CHECK-LABEL: @widen_over_common_exit_to_ph(
105 ; CHECK-NEXT:  entry:
106 ; CHECK-NEXT:    store i32 0, i32* @G
107 ; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]]
108 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ]
109 ; CHECK-NEXT:    br label [[LOOP:%.*]]
110 ; CHECK:       loop:
111 ; CHECK-NEXT:    store i32 1, i32* @G
112 ; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
113 ; CHECK:       backedge:
114 ; CHECK-NEXT:    store i32 2, i32* @G
115 ; CHECK-NEXT:    store i32 3, i32* @G
116 ; CHECK-NEXT:    br label [[LOOP]]
117 ; CHECK:       exit:
118 ; CHECK-NEXT:    ret void
120 entry:
121   store i32 0, i32* @G
122   call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
123   br label %loop
125 loop:
126   store i32 1, i32* @G
127   br i1 %cond_1, label %backedge, label %exit
129 backedge:
130   store i32 2, i32* @G
131   call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
132   store i32 3, i32* @G
133   br label %loop
135 exit:
136   ret void