[LICM] Hoist calls to readonly argmemonly functions even with stores in the loop
[oota-llvm.git] / test / Transforms / LICM / argmemonly-call.ll
1 ; RUN: opt -S -basicaa -licm %s | FileCheck %s
2 declare i32 @foo() readonly argmemonly nounwind
3 declare i32 @foo2() readonly nounwind
4 declare i32 @bar(i32* %loc2) readonly argmemonly nounwind
5
6 define void @test(i32* %loc) {
7 ; CHECK-LABEL: @test
8 ; CHECK: @foo
9 ; CHECK-LABEL: loop:
10   br label %loop
11
12 loop:
13   %res = call i32 @foo()
14   store i32 %res, i32* %loc
15   br label %loop
16 }
17
18 ; Negative test: show argmemonly is required
19 define void @test_neg(i32* %loc) {
20 ; CHECK-LABEL: @test_neg
21 ; CHECK-LABEL: loop:
22 ; CHECK: @foo
23   br label %loop
24
25 loop:
26   %res = call i32 @foo2()
27   store i32 %res, i32* %loc
28   br label %loop
29 }
30
31 define void @test2(i32* noalias %loc, i32* noalias %loc2) {
32 ; CHECK-LABEL: @test2
33 ; CHECK: @bar
34 ; CHECK-LABEL: loop:
35   br label %loop
36
37 loop:
38   %res = call i32 @bar(i32* %loc2)
39   store i32 %res, i32* %loc
40   br label %loop
41 }
42
43 ; Negative test: %might clobber gep
44 define void @test3(i32* %loc) {
45 ; CHECK-LABEL: @test3
46 ; CHECK-LABEL: loop:
47 ; CHECK: @bar
48   br label %loop
49
50 loop:
51   %res = call i32 @bar(i32* %loc)
52   %gep = getelementptr i32, i32 *%loc, i64 1000000
53   store i32 %res, i32* %gep
54   br label %loop
55 }
56
57
58 ; Negative test: %loc might alias %loc2
59 define void @test4(i32* %loc, i32* %loc2) {
60 ; CHECK-LABEL: @test4
61 ; CHECK-LABEL: loop:
62 ; CHECK: @bar
63   br label %loop
64
65 loop:
66   %res = call i32 @bar(i32* %loc2)
67   store i32 %res, i32* %loc
68   br label %loop
69 }