1; RUN: opt -licm -basic-aa < %s -S | FileCheck %s
2; RUN: opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
3
4define void @f_0(i1 %p) nounwind ssp {
5; CHECK-LABEL: @f_0(
6entry:
7  br label %for.body
8
9for.body:
10  br i1 undef, label %if.then, label %for.cond.backedge
11
12for.cond.backedge:
13  br i1 undef, label %for.end104, label %for.body
14
15if.then:
16  br i1 undef, label %if.then27, label %if.end.if.end.split_crit_edge.critedge
17
18if.then27:
19; CHECK: tail call void @llvm.assume
20  tail call void @llvm.assume(i1 %p)
21  br label %for.body61.us
22
23if.end.if.end.split_crit_edge.critedge:
24  br label %for.body61
25
26for.body61.us:
27  br i1 undef, label %for.cond.backedge, label %for.body61.us
28
29for.body61:
30  br i1 undef, label %for.cond.backedge, label %for.body61
31
32for.end104:
33  ret void
34}
35
36define void @f_1(i1 %cond, i32* %ptr) {
37; CHECK-LABEL: @f_1(
38; CHECK-LABEL: entry:
39; CHECK: call void @llvm.assume(i1 %cond)
40; CHECK: %val = load i32, i32* %ptr
41; CHECK-LABEL: loop:
42
43entry:
44  br label %loop
45
46loop:
47  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
48  call void @llvm.assume(i1 %cond)
49  %val = load i32, i32* %ptr
50  %x.inc = add i32 %x, %val
51  br label %loop
52}
53
54; Can't hoist because the call may throw and the assume
55; may never execute.
56define void @f_2(i1 %cond, i32* %ptr) {
57; CHECK-LABEL: @f_2(
58; CHECK-LABEL: entry:
59; CHECK-LABEL: loop:
60; CHECK: call void @llvm.assume(i1 %cond)
61; CHECK: %val = load i32, i32* %ptr
62
63entry:
64  br label %loop
65
66loop:
67  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
68  call void @maythrow()
69  call void @llvm.assume(i1 %cond)
70  %val = load i32, i32* %ptr
71  %x.inc = add i32 %x, %val
72  br label %loop
73}
74
75; Note: resulting loop could be peeled and then hoisted, but
76; by default assume is captured in phi cycle.
77define void @f_3(i1 %cond, i32* %ptr) {
78; CHECK-LABEL: @f_3(
79; CHECK-LABEL: entry:
80; CHECK: %val = load i32, i32* %ptr
81; CHECK-LABEL: loop:
82; CHECK: call void @llvm.assume(i1 %x.cmp)
83
84entry:
85  br label %loop
86
87loop:
88  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
89  %x.cmp = phi i1 [%cond, %entry], [%cond.next, %loop]
90  call void @llvm.assume(i1 %x.cmp)
91  %val = load i32, i32* %ptr
92  %cond.next = icmp eq i32 %val, 5
93  %x.inc = add i32 %x, %val
94  br label %loop
95}
96
97
98declare void @maythrow()
99declare void @llvm.assume(i1)
100