d7bec224471edbf97c4c3b34c4b55205d500d09e
[oota-llvm.git] / test / Analysis / BasicAA / featuretest.ll
1 ; This testcase tests for various features the basicaa test should be able to 
2 ; determine, as noted in the comments.
3
4 ; RUN: llvm-as < %s | opt -basicaa -load-vn -gcse -instcombine -dce | llvm-dis | not grep REMOVE
5
6 %Global = external global { int }
7
8 implementation
9
10
11 ; Array test:  Test that operations on one local array do not invalidate 
12 ; operations on another array.  Important for scientific codes.
13 ;
14 int %different_array_test(long %A, long %B) {
15         %Array1 = alloca int, uint 100
16         %Array2 = alloca int, uint 200
17
18         %pointer = getelementptr int* %Array1, long %A
19         %val = load int* %pointer
20
21         %pointer2 = getelementptr int* %Array2, long %B
22         store int 7, int* %pointer2
23
24         %REMOVE = load int* %pointer ; redundant with above load
25         %retval = sub int %REMOVE, %val
26         ret int %retval
27 }
28
29 ; Constant index test: Constant indexes into the same array should not 
30 ; interfere with each other.  Again, important for scientific codes.
31 ;
32 int %constant_array_index_test() {
33         %Array = alloca int, uint 100
34         %P1 = getelementptr int* %Array, long 7
35         %P2 = getelementptr int* %Array, long 6
36         
37         %A = load int* %P1
38         store int 1, int* %P2   ; Should not invalidate load
39         %BREMOVE = load int* %P1
40         %Val = sub int %A, %BREMOVE
41         ret int %Val
42 }
43
44 ; Test that if two pointers are spaced out by a constant getelementptr, that 
45 ; they cannot alias.
46 int %gep_distance_test(int* %A) {
47         %REMOVEu = load int* %A
48         %B = getelementptr int* %A, long 2  ; Cannot alias A
49         store int 7, int* %B
50         %REMOVEv = load int* %A
51         %r = sub int %REMOVEu, %REMOVEv
52         ret int %r
53 }
54
55 ; Test that if two pointers are spaced out by a constant offset, that they
56 ; cannot alias, even if there is a variable offset between them...
57 int %gep_distance_test2({int,int}* %A, long %distance) {
58         %A = getelementptr {int,int}* %A, long 0, uint 0
59         %REMOVEu = load int* %A
60         %B = getelementptr {int,int}* %A, long %distance, uint 1
61         store int 7, int* %B    ; B cannot alias A, it's at least 4 bytes away
62         %REMOVEv = load int* %A
63         %r = sub int %REMOVEu, %REMOVEv
64         ret int %r
65 }
66
67 ; Test that we can do funny pointer things and that distance calc will still 
68 ; work.
69 int %gep_distance_test3(int * %A) {
70         %X = load int* %A
71         %B = cast int* %A to sbyte*
72         %C = getelementptr sbyte* %B, long 4
73         %Y = load sbyte* %C
74         ret int 8
75 }
76
77 ; Test that we can disambiguate globals reached through constantexpr geps
78 int %constexpr_test() {
79    %X = alloca int
80    %Y = load int* %X
81    store int 5, int* getelementptr ({ int }* %Global, long 0, uint 0)
82    %REMOVE = load int* %X
83    %retval = sub int %Y, %REMOVE
84    ret int %retval
85 }