207
|
1 ; RUN: opt -S -basic-aa -gvn < %s | FileCheck %s
|
150
|
2
|
|
3 declare void @argmemonly_function(i32 *) argmemonly
|
|
4
|
|
5 define i32 @test0(i32* %P, i32* noalias %P2) {
|
|
6 ; CHECK-LABEL: @test0(
|
|
7 %v1 = load i32, i32* %P
|
|
8 ; CHECK: %v1 = load i32, i32* %P
|
|
9 call void @argmemonly_function(i32* %P2) [ "tag"() ]
|
|
10 ; CHECK: call void @argmemonly_function(
|
|
11 %v2 = load i32, i32* %P
|
|
12 ; CHECK: %v2 = load i32, i32* %P
|
|
13 %diff = sub i32 %v1, %v2
|
|
14 ; CHECK: %diff = sub i32 %v1, %v2
|
|
15 ret i32 %diff
|
|
16 ; CHECK: ret i32 %diff
|
|
17 }
|
|
18
|
|
19 define i32 @test1(i32* %P, i32* noalias %P2) {
|
|
20 ; CHECK-LABEL: @test1(
|
|
21 %v1 = load i32, i32* %P
|
|
22 call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ]
|
|
23 ; CHECK: call void @argmemonly_function(
|
|
24 %v2 = load i32, i32* %P
|
|
25 %diff = sub i32 %v1, %v2
|
|
26 ret i32 %diff
|
|
27 ; CHECK: ret i32 0
|
|
28 }
|
|
29
|
|
30 define i32 @test2(i32* %P, i32* noalias %P2) {
|
|
31 ; Note: in this test we //can// GVN %v1 and %v2 into one value in theory. Calls
|
|
32 ; with deopt operand bundles are not argmemonly because they *read* the entire
|
|
33 ; heap, but they don't write to any location in the heap if the callee does not
|
|
34 ; deoptimize the caller. This fact, combined with the fact that
|
|
35 ; @argmemonly_function is, well, an argmemonly function, can be used to conclude
|
|
36 ; that %P is not written to at the callsite. However LLVM currently cannot
|
|
37 ; describe the "does not write to non-args, and reads the entire heap" effect on
|
|
38 ; a callsite.
|
|
39
|
|
40 ; CHECK-LABEL: @test2(
|
|
41 %v1 = load i32, i32* %P
|
|
42 ; CHECK: %v1 = load i32, i32* %P
|
|
43 call void @argmemonly_function(i32* %P2) [ "deopt"() ]
|
|
44 ; CHECK: call void @argmemonly_function(
|
|
45 %v2 = load i32, i32* %P
|
|
46 ; CHECK: %v2 = load i32, i32* %P
|
|
47 %diff = sub i32 %v1, %v2
|
|
48 ; CHECK: %diff = sub i32 %v1, %v2
|
|
49 ret i32 %diff
|
|
50 ; CHECK: ret i32 %diff
|
|
51 }
|