xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/implicit-null-checks.ll (revision 2f79f5438cd6f4fa0fdc32458911c2d163f917c0)
1d889e17eSMax Kazantsev; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
292e54b09SRoman Lebedev; RUN: opt -passes='simple-loop-unswitch<nontrivial>' -S < %s | FileCheck %s
392e54b09SRoman Lebedev; RUN: opt -passes='loop(simple-loop-unswitch<nontrivial>),verify<loops>' -S < %s | FileCheck %s
4d889e17eSMax Kazantsev
58aaeee5fSMax Kazantsevdeclare void @may_exit()
6d889e17eSMax Kazantsevdeclare void @throw_npe()
7d889e17eSMax Kazantsev
8d889e17eSMax Kazantsev; It is illegal to preserve make_implicit notion of the condition being
9d889e17eSMax Kazantsev; unswitched because we may exit loop before we reach the condition, so
10d889e17eSMax Kazantsev; there is no guarantee that following implicit branch always means getting
11d889e17eSMax Kazantsev; to throw_npe block.
12*2f79f543SNikita Popovdefine i32 @test_should_drop_make_implicit(ptr %p1, ptr %p2) {
13d889e17eSMax Kazantsev; CHECK-LABEL: @test_should_drop_make_implicit(
14d889e17eSMax Kazantsev; CHECK-NEXT:  entry:
15*2f79f543SNikita Popov; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null
166a6cc554SFlorian Hahn; CHECK-NEXT:    [[NULL_CHECK_FR:%.*]] = freeze i1 [[NULL_CHECK]]
176a6cc554SFlorian Hahn; CHECK-NEXT:    br i1 [[NULL_CHECK_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
18d889e17eSMax Kazantsev; CHECK:       entry.split.us:
19d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[LOOP_US:%.*]]
20d889e17eSMax Kazantsev; CHECK:       loop.us:
21d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]
22*2f79f543SNikita Popov; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 4
23d889e17eSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND_US:%.*]] = icmp eq i32 [[X_US]], 0
24d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND_US]], label [[SIDE_EXIT_SPLIT_US:%.*]], label [[NULL_CHECK_BLOCK_US:%.*]]
25d889e17eSMax Kazantsev; CHECK:       null_check_block.us:
26d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]
27d889e17eSMax Kazantsev; CHECK:       side_exit.split.us:
28d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[SIDE_EXIT:%.*]]
29d889e17eSMax Kazantsev; CHECK:       throw_npe.split.us:
30d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE:%.*]]
31d889e17eSMax Kazantsev; CHECK:       entry.split:
32d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[LOOP:%.*]]
33d889e17eSMax Kazantsev; CHECK:       loop:
34d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
35*2f79f543SNikita Popov; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 4
36d889e17eSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0
37d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND]], label [[SIDE_EXIT_SPLIT:%.*]], label [[NULL_CHECK_BLOCK:%.*]]
38d889e17eSMax Kazantsev; CHECK:       null_check_block:
39d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[BACKEDGE]]
40d889e17eSMax Kazantsev; CHECK:       backedge:
41d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
42d889e17eSMax Kazantsev; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000
43d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
44d889e17eSMax Kazantsev; CHECK:       side_exit.split:
45d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[SIDE_EXIT]]
46d889e17eSMax Kazantsev; CHECK:       side_exit:
47d889e17eSMax Kazantsev; CHECK-NEXT:    ret i32 0
48d889e17eSMax Kazantsev; CHECK:       throw_npe:
49d889e17eSMax Kazantsev; CHECK-NEXT:    call void @throw_npe()
50d889e17eSMax Kazantsev; CHECK-NEXT:    unreachable
51d889e17eSMax Kazantsev; CHECK:       exit:
52d889e17eSMax Kazantsev; CHECK-NEXT:    [[X_LCSSA2:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]
53d889e17eSMax Kazantsev; CHECK-NEXT:    ret i32 [[X_LCSSA2]]
54d889e17eSMax Kazantsev;
55d889e17eSMax Kazantseventry:
56*2f79f543SNikita Popov  %null_check = icmp eq ptr %p2, null
57d889e17eSMax Kazantsev  br label %loop
58d889e17eSMax Kazantsevloop:
59d889e17eSMax Kazantsev  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
60*2f79f543SNikita Popov  %x = load i32, ptr %p1
61d889e17eSMax Kazantsev  %side_exit_cond = icmp eq i32 %x, 0
62d889e17eSMax Kazantsev  br i1 %side_exit_cond, label %side_exit, label %null_check_block
63d889e17eSMax Kazantsev
64d889e17eSMax Kazantsevnull_check_block:
65d889e17eSMax Kazantsev  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0
66d889e17eSMax Kazantsev
67d889e17eSMax Kazantsevbackedge:
68d889e17eSMax Kazantsev  %iv.next = add i32 %iv,1
69d889e17eSMax Kazantsev  %loop_cond = icmp slt i32 %iv.next, 10000
70d889e17eSMax Kazantsev  br i1 %loop_cond, label %loop, label %exit
71d889e17eSMax Kazantsev
72d889e17eSMax Kazantsevside_exit:
73d889e17eSMax Kazantsev  ret i32 0
74d889e17eSMax Kazantsev
75d889e17eSMax Kazantsevthrow_npe:
76d889e17eSMax Kazantsev  call void @throw_npe()
77d889e17eSMax Kazantsev  unreachable
78d889e17eSMax Kazantsev
79d889e17eSMax Kazantsevexit:
80d889e17eSMax Kazantsev  ret i32 %x
81d889e17eSMax Kazantsev}
82d889e17eSMax Kazantsev
83d889e17eSMax Kazantsev; Here make.implicit notion may be preserved because we always get to throw_npe
84d889e17eSMax Kazantsev; after following true branch. This is a trivial unswitch.
85*2f79f543SNikita Popovdefine i32 @test_may_keep_make_implicit_trivial(ptr %p1, ptr %p2) {
86d889e17eSMax Kazantsev; CHECK-LABEL: @test_may_keep_make_implicit_trivial(
87d889e17eSMax Kazantsev; CHECK-NEXT:  entry:
88*2f79f543SNikita Popov; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null
89d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[THROW_NPE:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !0
90d889e17eSMax Kazantsev; CHECK:       entry.split:
91d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[LOOP:%.*]]
92d889e17eSMax Kazantsev; CHECK:       loop:
93d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
94*2f79f543SNikita Popov; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1:%.*]], align 4
95d889e17eSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0
96d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[SIDE_EXIT_BLOCK:%.*]]
97d889e17eSMax Kazantsev; CHECK:       side_exit_block:
98d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[SIDE_EXIT_COND]], label [[SIDE_EXIT:%.*]], label [[BACKEDGE]]
99d889e17eSMax Kazantsev; CHECK:       backedge:
100d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
101d889e17eSMax Kazantsev; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000
102d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
103d889e17eSMax Kazantsev; CHECK:       side_exit:
104d889e17eSMax Kazantsev; CHECK-NEXT:    ret i32 0
105d889e17eSMax Kazantsev; CHECK:       throw_npe:
106d889e17eSMax Kazantsev; CHECK-NEXT:    call void @throw_npe()
107d889e17eSMax Kazantsev; CHECK-NEXT:    unreachable
108d889e17eSMax Kazantsev; CHECK:       exit:
109d889e17eSMax Kazantsev; CHECK-NEXT:    [[X_LCSSA2:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]
110d889e17eSMax Kazantsev; CHECK-NEXT:    ret i32 [[X_LCSSA2]]
111d889e17eSMax Kazantsev;
112d889e17eSMax Kazantseventry:
113*2f79f543SNikita Popov  %null_check = icmp eq ptr %p2, null
114d889e17eSMax Kazantsev  br label %loop
115d889e17eSMax Kazantsevloop:
116d889e17eSMax Kazantsev  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
117*2f79f543SNikita Popov  %x = load i32, ptr %p1
118d889e17eSMax Kazantsev  %side_exit_cond = icmp eq i32 %x, 0
119d889e17eSMax Kazantsev  br i1 %null_check, label %throw_npe, label %side_exit_block, !make.implicit !0
120d889e17eSMax Kazantsev
121d889e17eSMax Kazantsevside_exit_block:
122d889e17eSMax Kazantsev  br i1 %side_exit_cond, label %side_exit, label %backedge
123d889e17eSMax Kazantsev
124d889e17eSMax Kazantsevbackedge:
125d889e17eSMax Kazantsev  %iv.next = add i32 %iv,1
126d889e17eSMax Kazantsev  %loop_cond = icmp slt i32 %iv.next, 10000
127d889e17eSMax Kazantsev  br i1 %loop_cond, label %loop, label %exit
128d889e17eSMax Kazantsev
129d889e17eSMax Kazantsevside_exit:
130d889e17eSMax Kazantsev  ret i32 0
131d889e17eSMax Kazantsev
132d889e17eSMax Kazantsevthrow_npe:
133d889e17eSMax Kazantsev  call void @throw_npe()
134d889e17eSMax Kazantsev  unreachable
135d889e17eSMax Kazantsev
136d889e17eSMax Kazantsevexit:
137d889e17eSMax Kazantsev  ret i32 %x
138d889e17eSMax Kazantsev}
139d889e17eSMax Kazantsev
140*2f79f543SNikita Popovdefine i32 @test_may_keep_make_implicit_non_trivial(ptr %p1, ptr %p2) {
141d889e17eSMax Kazantsev; CHECK-LABEL: @test_may_keep_make_implicit_non_trivial(
142d889e17eSMax Kazantsev; CHECK-NEXT:  entry:
143*2f79f543SNikita Popov; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null
1448aaeee5fSMax Kazantsev; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !0
145d889e17eSMax Kazantsev; CHECK:       entry.split.us:
146d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[LOOP_US:%.*]]
147d889e17eSMax Kazantsev; CHECK:       loop.us:
148d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]
149*2f79f543SNikita Popov; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 4
150d889e17eSMax Kazantsev; CHECK-NEXT:    [[INNER_BLOCK_COND_US:%.*]] = icmp eq i32 [[X_US]], 0
151d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[INNER_BLOCK_COND_US]], label [[INNER_BLOCK_US:%.*]], label [[NULL_CHECK_BLOCK_US:%.*]]
152d889e17eSMax Kazantsev; CHECK:       inner_block.us:
153d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[NULL_CHECK_BLOCK_US]]
154d889e17eSMax Kazantsev; CHECK:       null_check_block.us:
155d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]
156d889e17eSMax Kazantsev; CHECK:       throw_npe.split.us:
157d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE:%.*]]
158d889e17eSMax Kazantsev; CHECK:       entry.split:
159d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[LOOP:%.*]]
160d889e17eSMax Kazantsev; CHECK:       loop:
161d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
162*2f79f543SNikita Popov; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 4
163d889e17eSMax Kazantsev; CHECK-NEXT:    [[INNER_BLOCK_COND:%.*]] = icmp eq i32 [[X]], 0
164d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[INNER_BLOCK_COND]], label [[INNER_BLOCK:%.*]], label [[NULL_CHECK_BLOCK:%.*]]
165d889e17eSMax Kazantsev; CHECK:       inner_block:
166d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[NULL_CHECK_BLOCK]]
167d889e17eSMax Kazantsev; CHECK:       null_check_block:
168d889e17eSMax Kazantsev; CHECK-NEXT:    br label [[BACKEDGE]]
169d889e17eSMax Kazantsev; CHECK:       backedge:
170d889e17eSMax Kazantsev; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
171d889e17eSMax Kazantsev; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000
172d889e17eSMax Kazantsev; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
173d889e17eSMax Kazantsev; CHECK:       throw_npe:
174d889e17eSMax Kazantsev; CHECK-NEXT:    call void @throw_npe()
175d889e17eSMax Kazantsev; CHECK-NEXT:    unreachable
176d889e17eSMax Kazantsev; CHECK:       exit:
177d889e17eSMax Kazantsev; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]
178d889e17eSMax Kazantsev; CHECK-NEXT:    ret i32 [[X_LCSSA1]]
179d889e17eSMax Kazantsev;
180d889e17eSMax Kazantseventry:
181*2f79f543SNikita Popov  %null_check = icmp eq ptr %p2, null
182d889e17eSMax Kazantsev  br label %loop
183d889e17eSMax Kazantsevloop:
184d889e17eSMax Kazantsev  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
185*2f79f543SNikita Popov  %x = load i32, ptr %p1
186d889e17eSMax Kazantsev  %inner_block_cond = icmp eq i32 %x, 0
187d889e17eSMax Kazantsev  br i1 %inner_block_cond, label %inner_block, label %null_check_block
188d889e17eSMax Kazantsev
189d889e17eSMax Kazantsevinner_block:
190d889e17eSMax Kazantsev  br label %null_check_block
191d889e17eSMax Kazantsev
192d889e17eSMax Kazantsevnull_check_block:
193d889e17eSMax Kazantsev  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0
194d889e17eSMax Kazantsev
195d889e17eSMax Kazantsevbackedge:
196d889e17eSMax Kazantsev  %iv.next = add i32 %iv,1
197d889e17eSMax Kazantsev  %loop_cond = icmp slt i32 %iv.next, 10000
198d889e17eSMax Kazantsev  br i1 %loop_cond, label %loop, label %exit
199d889e17eSMax Kazantsev
200d889e17eSMax Kazantsevthrow_npe:
201d889e17eSMax Kazantsev  call void @throw_npe()
202d889e17eSMax Kazantsev  unreachable
203d889e17eSMax Kazantsev
204d889e17eSMax Kazantsevexit:
205d889e17eSMax Kazantsev  ret i32 %x
206d889e17eSMax Kazantsev}
207d889e17eSMax Kazantsev
2088aaeee5fSMax Kazantsev; Here make.implicit notion should be dropped because of exiting call.
209*2f79f543SNikita Popovdefine i32 @test_should_drop_make_implicit_exiting_call(ptr %p1, ptr %p2) {
2108aaeee5fSMax Kazantsev; CHECK-LABEL: @test_should_drop_make_implicit_exiting_call(
2118aaeee5fSMax Kazantsev; CHECK-NEXT:  entry:
212*2f79f543SNikita Popov; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null
2136a6cc554SFlorian Hahn; CHECK-NEXT:    [[NULL_CHECK_FR:%.*]] = freeze i1 [[NULL_CHECK]]
2146a6cc554SFlorian Hahn; CHECK-NEXT:    br i1 [[NULL_CHECK_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
2158aaeee5fSMax Kazantsev; CHECK:       entry.split.us:
2168aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[LOOP_US:%.*]]
2178aaeee5fSMax Kazantsev; CHECK:       loop.us:
2188aaeee5fSMax Kazantsev; CHECK-NEXT:    [[IV_US:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT_US]] ]
2198aaeee5fSMax Kazantsev; CHECK-NEXT:    call void @may_exit()
220*2f79f543SNikita Popov; CHECK-NEXT:    [[X_US:%.*]] = load i32, ptr [[P1:%.*]], align 4
2218aaeee5fSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND_US:%.*]] = icmp eq i32 [[X_US]], 0
2228aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE_SPLIT_US:%.*]]
2238aaeee5fSMax Kazantsev; CHECK:       throw_npe.split.us:
2248aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[THROW_NPE:%.*]]
2258aaeee5fSMax Kazantsev; CHECK:       entry.split:
2268aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[LOOP:%.*]]
2278aaeee5fSMax Kazantsev; CHECK:       loop:
2288aaeee5fSMax Kazantsev; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
2298aaeee5fSMax Kazantsev; CHECK-NEXT:    call void @may_exit()
230*2f79f543SNikita Popov; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1]], align 4
2318aaeee5fSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0
2328aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[BACKEDGE]]
2338aaeee5fSMax Kazantsev; CHECK:       backedge:
2348aaeee5fSMax Kazantsev; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
2358aaeee5fSMax Kazantsev; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000
2368aaeee5fSMax Kazantsev; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
2378aaeee5fSMax Kazantsev; CHECK:       throw_npe:
2388aaeee5fSMax Kazantsev; CHECK-NEXT:    call void @throw_npe()
2398aaeee5fSMax Kazantsev; CHECK-NEXT:    unreachable
2408aaeee5fSMax Kazantsev; CHECK:       exit:
2418aaeee5fSMax Kazantsev; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]
2428aaeee5fSMax Kazantsev; CHECK-NEXT:    ret i32 [[X_LCSSA1]]
2438aaeee5fSMax Kazantsev;
2448aaeee5fSMax Kazantseventry:
245*2f79f543SNikita Popov  %null_check = icmp eq ptr %p2, null
2468aaeee5fSMax Kazantsev  br label %loop
2478aaeee5fSMax Kazantsevloop:
2488aaeee5fSMax Kazantsev  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
2498aaeee5fSMax Kazantsev  call void @may_exit()
250*2f79f543SNikita Popov  %x = load i32, ptr %p1
2518aaeee5fSMax Kazantsev  %side_exit_cond = icmp eq i32 %x, 0
2528aaeee5fSMax Kazantsev  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0
2538aaeee5fSMax Kazantsev
2548aaeee5fSMax Kazantsevbackedge:
2558aaeee5fSMax Kazantsev  %iv.next = add i32 %iv,1
2568aaeee5fSMax Kazantsev  %loop_cond = icmp slt i32 %iv.next, 10000
2578aaeee5fSMax Kazantsev  br i1 %loop_cond, label %loop, label %exit
2588aaeee5fSMax Kazantsev
2598aaeee5fSMax Kazantsevthrow_npe:
2608aaeee5fSMax Kazantsev  call void @throw_npe()
2618aaeee5fSMax Kazantsev  unreachable
2628aaeee5fSMax Kazantsev
2638aaeee5fSMax Kazantsevexit:
2648aaeee5fSMax Kazantsev  ret i32 %x
2658aaeee5fSMax Kazantsev}
2668aaeee5fSMax Kazantsev
2678aaeee5fSMax Kazantsev; Here exiting call goes after the null check, so make.implicit may be preserved.
268*2f79f543SNikita Popovdefine i32 @test_may_keep_make_implicit_exiting_call(ptr %p1, ptr %p2) {
2698aaeee5fSMax Kazantsev; CHECK-LABEL: @test_may_keep_make_implicit_exiting_call(
2708aaeee5fSMax Kazantsev; CHECK-NEXT:  entry:
271*2f79f543SNikita Popov; CHECK-NEXT:    [[NULL_CHECK:%.*]] = icmp eq ptr [[P2:%.*]], null
2728aaeee5fSMax Kazantsev; CHECK-NEXT:    br i1 [[NULL_CHECK]], label [[THROW_NPE:%.*]], label [[ENTRY_SPLIT:%.*]], !make.implicit !0
2738aaeee5fSMax Kazantsev; CHECK:       entry.split:
2748aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[LOOP:%.*]]
2758aaeee5fSMax Kazantsev; CHECK:       loop:
2768aaeee5fSMax Kazantsev; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY_SPLIT]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
277*2f79f543SNikita Popov; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P1:%.*]], align 4
2788aaeee5fSMax Kazantsev; CHECK-NEXT:    [[SIDE_EXIT_COND:%.*]] = icmp eq i32 [[X]], 0
2798aaeee5fSMax Kazantsev; CHECK-NEXT:    br label [[BACKEDGE]]
2808aaeee5fSMax Kazantsev; CHECK:       backedge:
2818aaeee5fSMax Kazantsev; CHECK-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
2828aaeee5fSMax Kazantsev; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp slt i32 [[IV_NEXT]], 10000
2838aaeee5fSMax Kazantsev; CHECK-NEXT:    call void @may_exit()
2848aaeee5fSMax Kazantsev; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
2858aaeee5fSMax Kazantsev; CHECK:       throw_npe:
2868aaeee5fSMax Kazantsev; CHECK-NEXT:    call void @throw_npe()
2878aaeee5fSMax Kazantsev; CHECK-NEXT:    unreachable
2888aaeee5fSMax Kazantsev; CHECK:       exit:
2898aaeee5fSMax Kazantsev; CHECK-NEXT:    [[X_LCSSA1:%.*]] = phi i32 [ [[X]], [[BACKEDGE]] ]
2908aaeee5fSMax Kazantsev; CHECK-NEXT:    ret i32 [[X_LCSSA1]]
2918aaeee5fSMax Kazantsev;
2928aaeee5fSMax Kazantseventry:
293*2f79f543SNikita Popov  %null_check = icmp eq ptr %p2, null
2948aaeee5fSMax Kazantsev  br label %loop
2958aaeee5fSMax Kazantsevloop:
2968aaeee5fSMax Kazantsev  %iv = phi i32 [0, %entry], [%iv.next, %backedge]
297*2f79f543SNikita Popov  %x = load i32, ptr %p1
2988aaeee5fSMax Kazantsev  %side_exit_cond = icmp eq i32 %x, 0
2998aaeee5fSMax Kazantsev  br i1 %null_check, label %throw_npe, label %backedge, !make.implicit !0
3008aaeee5fSMax Kazantsev
3018aaeee5fSMax Kazantsevbackedge:
3028aaeee5fSMax Kazantsev  %iv.next = add i32 %iv,1
3038aaeee5fSMax Kazantsev  %loop_cond = icmp slt i32 %iv.next, 10000
3048aaeee5fSMax Kazantsev  call void @may_exit()
3058aaeee5fSMax Kazantsev  br i1 %loop_cond, label %loop, label %exit
3068aaeee5fSMax Kazantsev
3078aaeee5fSMax Kazantsevthrow_npe:
3088aaeee5fSMax Kazantsev  call void @throw_npe()
3098aaeee5fSMax Kazantsev  unreachable
3108aaeee5fSMax Kazantsev
3118aaeee5fSMax Kazantsevexit:
3128aaeee5fSMax Kazantsev  ret i32 %x
3138aaeee5fSMax Kazantsev}
3148aaeee5fSMax Kazantsev
315d889e17eSMax Kazantsev!0 = !{}
316