• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt -licm -basic-aa -licm-n2-threshold=0 < %s -S | FileCheck %s
2; RUN: opt -licm -basic-aa -licm-n2-threshold=200 < %s -S | FileCheck %s --check-prefix=ALIAS-N2
3; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=0 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
4; RUN: opt -aa-pipeline=basic-aa -licm-n2-threshold=200 -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s --check-prefix=ALIAS-N2
5
6define void @test1(i1 %cond, i32* %ptr) {
7; CHECK-LABEL: @test1(
8; CHECK-LABEL: entry:
9; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
10; CHECK: %val = load i32, i32* %ptr
11; CHECK-LABEL: loop:
12
13; ALIAS-N2-LABEL: @test1(
14; ALIAS-N2-LABEL: entry:
15; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
16; ALIAS-N2: %val = load i32, i32* %ptr
17; ALIAS-N2-LABEL: loop:
18
19entry:
20  br label %loop
21
22loop:
23  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
24  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
25  %val = load i32, i32* %ptr
26  %x.inc = add i32 %x, %val
27  br label %loop
28}
29
30;; despite the loop varying invariant.start, we should be
31;; able to hoist the load
32define void @test2(i1 %cond, i32* %ptr) {
33; CHECK-LABEL: @test2(
34; CHECK-LABEL: entry:
35; CHECK: %val = load i32, i32* %ptr
36; CHECK-LABEL: loop:
37; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %piv)
38
39; ALIAS-N2-LABEL: @test2(
40; ALIAS-N2-LABEL: entry:
41; ALIAS-N2:         %val = load i32, i32* %ptr
42; ALIAS-N2-LABEL: loop:
43; ALIAS-N2:         call {}* @llvm.invariant.start.p0i32(i64 4, i32* %piv)
44entry:
45  br label %loop
46
47loop:
48  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
49  %piv = getelementptr i32, i32* %ptr, i32 %x
50  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %piv)
51  %val = load i32, i32* %ptr
52  %x.inc = add i32 %x, %val
53  br label %loop
54}
55
56define void @test3(i1 %cond, i32* %ptr) {
57; CHECK-LABEL: @test3(
58; CHECK-LABEL: entry:
59; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
60; CHECK: %val = load i32, i32* %ptr
61; CHECK-LABEL: loop:
62
63; ALIAS-N2-LABEL: @test3(
64; ALIAS-N2-LABEL: entry:
65; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
66; ALIAS-N2: %val = load i32, i32* %ptr
67; ALIAS-N2-LABEL: loop:
68entry:
69  br label %loop
70
71loop:
72  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
73  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
74  %val = load i32, i32* %ptr
75  %p2 = getelementptr i32, i32* %ptr, i32 1
76  store volatile i32 0, i32* %p2
77  %x.inc = add i32 %x, %val
78  br label %loop
79}
80
81; can't hoist due to init in loop, only well defined if loop exits
82; on first iteration, but we don't bother checking for that currently
83define void @test4(i1 %cond, i32* %ptr) {
84; CHECK-LABEL: @test4(
85; CHECK-LABEL: entry:
86; CHECK-LABEL: loop:
87; CHECK:   store i32 0, i32* %ptr
88; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
89; CHECK: %val = load i32, i32* %ptr
90
91; ALIAS-N2-LABEL: @test4(
92; ALIAS-N2-LABEL: entry:
93; ALIAS-N2-LABEL: loop:
94; ALIAS-N2:   store i32 0, i32* %ptr
95; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
96; ALIAS-N2: %val = load i32, i32* %ptr
97entry:
98  br label %loop
99
100loop:
101  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
102  store i32 0, i32* %ptr
103  call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
104  %val = load i32, i32* %ptr
105  %x.inc = add i32 %x, %val
106  br label %loop
107}
108
109; don't try to reason about scopes
110define void @test5(i1 %cond, i32* %ptr) {
111; CHECK-LABEL: @test5(
112; CHECK-LABEL: entry:
113; CHECK-LABEL: loop:
114; CHECK:   store i32 0, i32* %ptr
115; CHECK: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
116; CHECK: %val = load i32, i32* %ptr
117
118; ALIAS-N2-LABEL: @test5(
119; ALIAS-N2-LABEL: entry:
120; ALIAS-N2-LABEL: loop:
121; ALIAS-N2:   store i32 0, i32* %ptr
122; ALIAS-N2: call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
123; ALIAS-N2: %val = load i32, i32* %ptr
124entry:
125  br label %loop
126
127loop:
128  %x = phi i32 [ 0, %entry ], [ %x.inc, %loop ]
129  store i32 0, i32* %ptr
130  %scope = call {}* @llvm.invariant.start.p0i32(i64 4, i32* %ptr)
131  %val = load i32, i32* %ptr
132  call void @llvm.invariant.end.p0i32({}* %scope, i64 4, i32* %ptr)
133  %x.inc = add i32 %x, %val
134  br label %loop
135}
136
137declare {}* @llvm.invariant.start.p0i32(i64, i32*)
138declare void @llvm.invariant.end.p0i32({}*, i64, i32*)
139