1137995d8SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
28cf5b69fSNikita Popov; RUN: opt -S -passes="loop-mssa(guard-widening)" -verify-memoryssa < %s | FileCheck %s
3137995d8SPhilip Reames
4137995d8SPhilip Reamesdeclare void @llvm.experimental.guard(i1,...)
5137995d8SPhilip Reames
6137995d8SPhilip Reames@G = external global i32
7137995d8SPhilip Reames
8137995d8SPhilip Reames; Show that we can widen into early checks within a loop, and in the process
9137995d8SPhilip Reames; expose optimization oppurtunities.
10137995d8SPhilip Reamesdefine void @widen_within_loop(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
11137995d8SPhilip Reames; CHECK-LABEL: @widen_within_loop(
12137995d8SPhilip Reames; CHECK-NEXT:  entry:
13137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
14137995d8SPhilip Reames; CHECK:       loop:
15*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 0, i32* @G, align 4
16137995d8SPhilip Reames; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
17137995d8SPhilip Reames; CHECK-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
18137995d8SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
19*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 1, i32* @G, align 4
20*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 2, i32* @G, align 4
21*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 3, i32* @G, align 4
22137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
23137995d8SPhilip Reames;
24137995d8SPhilip Reamesentry:
25137995d8SPhilip Reames  br label %loop
26137995d8SPhilip Reames
27137995d8SPhilip Reamesloop:
28137995d8SPhilip Reames  store i32 0, i32* @G
29137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
30137995d8SPhilip Reames  store i32 1, i32* @G
31137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
32137995d8SPhilip Reames  store i32 2, i32* @G
33137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
34137995d8SPhilip Reames  store i32 3, i32* @G
35137995d8SPhilip Reames  br label %loop
36137995d8SPhilip Reames}
37137995d8SPhilip Reames
38137995d8SPhilip Reamesdefine void @widen_into_preheader(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
39137995d8SPhilip Reames; CHECK-LABEL: @widen_into_preheader(
40137995d8SPhilip Reames; CHECK-NEXT:  entry:
41*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 0, i32* @G, align 4
42137995d8SPhilip Reames; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_1:%.*]]
43137995d8SPhilip Reames; CHECK-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[COND_2:%.*]]
44137995d8SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK1]]) [ "deopt"(i32 0) ]
45137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
46137995d8SPhilip Reames; CHECK:       loop:
47*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 1, i32* @G, align 4
48*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 2, i32* @G, align 4
49*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 3, i32* @G, align 4
50137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
51137995d8SPhilip Reames;
52137995d8SPhilip Reamesentry:
53137995d8SPhilip Reames  store i32 0, i32* @G
54137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
55137995d8SPhilip Reames  br label %loop
56137995d8SPhilip Reames
57137995d8SPhilip Reamesloop:
58137995d8SPhilip Reames  store i32 1, i32* @G
59137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_1) [ "deopt"(i32 1) ]
60137995d8SPhilip Reames  store i32 2, i32* @G
61137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
62137995d8SPhilip Reames  store i32 3, i32* @G
63137995d8SPhilip Reames  br label %loop
64137995d8SPhilip Reames}
65137995d8SPhilip Reames
66137995d8SPhilip Reamesdefine void @dont_widen_over_common_exit(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
67137995d8SPhilip Reames; CHECK-LABEL: @dont_widen_over_common_exit(
68137995d8SPhilip Reames; CHECK-NEXT:  entry:
69137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
70137995d8SPhilip Reames; CHECK:       loop:
71*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 0, i32* @G, align 4
72137995d8SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_0:%.*]]) [ "deopt"(i32 0) ]
73*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 1, i32* @G, align 4
74137995d8SPhilip Reames; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
75137995d8SPhilip Reames; CHECK:       backedge:
76*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 2, i32* @G, align 4
77137995d8SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[COND_2:%.*]]) [ "deopt"(i32 2) ]
78*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 3, i32* @G, align 4
79137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
80137995d8SPhilip Reames; CHECK:       exit:
81137995d8SPhilip Reames; CHECK-NEXT:    ret void
82137995d8SPhilip Reames;
83137995d8SPhilip Reamesentry:
84137995d8SPhilip Reames  br label %loop
85137995d8SPhilip Reames
86137995d8SPhilip Reamesloop:
87137995d8SPhilip Reames  store i32 0, i32* @G
88137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
89137995d8SPhilip Reames  store i32 1, i32* @G
90137995d8SPhilip Reames  br i1 %cond_1, label %backedge, label %exit
91137995d8SPhilip Reames
92137995d8SPhilip Reamesbackedge:
93137995d8SPhilip Reames  store i32 2, i32* @G
94137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
95137995d8SPhilip Reames  store i32 3, i32* @G
96137995d8SPhilip Reames  br label %loop
97137995d8SPhilip Reames
98137995d8SPhilip Reamesexit:
99137995d8SPhilip Reames  ret void
100137995d8SPhilip Reames}
101137995d8SPhilip Reames
102137995d8SPhilip Reamesdefine void @widen_over_common_exit_to_ph(i1 %cond_0, i1 %cond_1, i1 %cond_2) {
103137995d8SPhilip Reames; CHECK-LABEL: @widen_over_common_exit_to_ph(
104137995d8SPhilip Reames; CHECK-NEXT:  entry:
105*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 0, i32* @G, align 4
106137995d8SPhilip Reames; CHECK-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[COND_0:%.*]], [[COND_2:%.*]]
107137995d8SPhilip Reames; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"(i32 0) ]
108137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
109137995d8SPhilip Reames; CHECK:       loop:
110*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 1, i32* @G, align 4
111137995d8SPhilip Reames; CHECK-NEXT:    br i1 [[COND_1:%.*]], label [[BACKEDGE:%.*]], label [[EXIT:%.*]]
112137995d8SPhilip Reames; CHECK:       backedge:
113*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 2, i32* @G, align 4
114*9ffe1b0aSSerguei Katkov; CHECK-NEXT:    store i32 3, i32* @G, align 4
115137995d8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
116137995d8SPhilip Reames; CHECK:       exit:
117137995d8SPhilip Reames; CHECK-NEXT:    ret void
118137995d8SPhilip Reames;
119137995d8SPhilip Reamesentry:
120137995d8SPhilip Reames  store i32 0, i32* @G
121137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_0) [ "deopt"(i32 0) ]
122137995d8SPhilip Reames  br label %loop
123137995d8SPhilip Reames
124137995d8SPhilip Reamesloop:
125137995d8SPhilip Reames  store i32 1, i32* @G
126137995d8SPhilip Reames  br i1 %cond_1, label %backedge, label %exit
127137995d8SPhilip Reames
128137995d8SPhilip Reamesbackedge:
129137995d8SPhilip Reames  store i32 2, i32* @G
130137995d8SPhilip Reames  call void(i1, ...) @llvm.experimental.guard(i1 %cond_2) [ "deopt"(i32 2) ]
131137995d8SPhilip Reames  store i32 3, i32* @G
132137995d8SPhilip Reames  br label %loop
133137995d8SPhilip Reames
134137995d8SPhilip Reamesexit:
135137995d8SPhilip Reames  ret void
136137995d8SPhilip Reames}
137137995d8SPhilip Reames
138