cca829b9457e0a80828e60c4b1d615187550629e
[oota-llvm.git] / test / Transforms / LoopVectorize / X86 / vector_ptr_load_store.ll
1 ; RUN: opt -basicaa -loop-vectorize -mcpu=corei7-avx -debug -S < %s 2>&1 | FileCheck %s
2 ; REQUIRES: asserts
3
4 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
5 target triple = "x86_64-apple-macosx10.8.0"
6
7 %0 = type { %0*, %1 }
8 %1 = type { i8*, i32 }
9
10 @p = global [2048 x [8 x i32*]] zeroinitializer, align 16
11 @q = global [2048 x i16] zeroinitializer, align 16
12 @r = global [2048 x i16] zeroinitializer, align 16
13
14 ; Tests for widest type
15 ; Ensure that we count the pointer store in the first test case. We have a
16 ; consecutive vector of pointers store, therefore we should count it towards the
17 ; widest vector count.
18 ;
19 ; CHECK: test_consecutive_store
20 ; CHECK: The Smallest and Widest types: 64 / 64 bits.
21 define void @test_consecutive_store(%0**, %0**, %0** nocapture) nounwind ssp uwtable align 2 {
22   %4 = load %0*, %0** %2, align 8
23   %5 = icmp eq %0** %0, %1
24   br i1 %5, label %12, label %6
25
26 ; <label>:6                                       ; preds = %3
27   br label %7
28
29 ; <label>:7                                       ; preds = %7, %6
30   %8 = phi %0** [ %0, %6 ], [ %9, %7 ]
31   store %0* %4, %0** %8, align 8
32   %9 = getelementptr inbounds %0*, %0** %8, i64 1
33   %10 = icmp eq %0** %9, %1
34   br i1 %10, label %11, label %7
35
36 ; <label>:11                                      ; preds = %7
37   br label %12
38
39 ; <label>:12                                      ; preds = %11, %3
40   ret void
41 }
42
43 ; However, if the store of a set of pointers is not to consecutive memory we do
44 ; NOT count the store towards the widest vector type.
45 ; In the test case below we add i16 types to store it in an array of pointer,
46 ; therefore the widest type should be i16.
47 ; int* p[2048][8];
48 ; short q[2048];
49 ;   for (int y = 0; y < 8; ++y)
50 ;     for (int i = 0; i < 1024; ++i) {
51 ;       p[i][y] = (int*) (1 + q[i]);
52 ;     }
53 ; CHECK: test_nonconsecutive_store
54 ; CHECK: The Smallest and Widest types: 16 / 16 bits.
55 define void @test_nonconsecutive_store() nounwind ssp uwtable {
56   br label %1
57
58 ; <label>:1                                       ; preds = %14, %0
59   %2 = phi i64 [ 0, %0 ], [ %15, %14 ]
60   br label %3
61
62 ; <label>:3                                       ; preds = %3, %1
63   %4 = phi i64 [ 0, %1 ], [ %11, %3 ]
64   %5 = getelementptr inbounds [2048 x i16], [2048 x i16]* @q, i64 0, i64 %4
65   %6 = load i16, i16* %5, align 2
66   %7 = sext i16 %6 to i64
67   %8 = add i64 %7, 1
68   %9 = inttoptr i64 %8 to i32*
69   %10 = getelementptr inbounds [2048 x [8 x i32*]], [2048 x [8 x i32*]]* @p, i64 0, i64 %4, i64 %2
70   store i32* %9, i32** %10, align 8
71   %11 = add i64 %4, 1
72   %12 = trunc i64 %11 to i32
73   %13 = icmp ne i32 %12, 1024
74   br i1 %13, label %3, label %14
75
76 ; <label>:14                                      ; preds = %3
77   %15 = add i64 %2, 1
78   %16 = trunc i64 %15 to i32
79   %17 = icmp ne i32 %16, 8
80   br i1 %17, label %1, label %18
81
82 ; <label>:18                                      ; preds = %14
83   ret void
84 }
85
86
87 @ia = global [1024 x i32*] zeroinitializer, align 16
88 @ib = global [1024 x i32] zeroinitializer, align 16
89 @ic = global [1024 x i8] zeroinitializer, align 16
90 @p2 = global [2048 x [8 x i32*]] zeroinitializer, align 16
91 @q2 = global [2048 x i16] zeroinitializer, align 16
92
93 ;; Now we check the same rules for loads. We should take consecutive loads of
94 ;; pointer types into account.
95 ; CHECK: test_consecutive_ptr_load
96 ; CHECK: The Smallest and Widest types: 8 / 64 bits.
97 define i8 @test_consecutive_ptr_load() nounwind readonly ssp uwtable {
98   br label %1
99
100 ; <label>:1                                       ; preds = %1, %0
101   %2 = phi i64 [ 0, %0 ], [ %10, %1 ]
102   %3 = phi i8 [ 0, %0 ], [ %9, %1 ]
103   %4 = getelementptr inbounds [1024 x i32*], [1024 x i32*]* @ia, i32 0, i64 %2
104   %5 = load i32*, i32** %4, align 4
105   %6 = ptrtoint i32* %5 to i64
106   %7 = trunc i64 %6 to i8
107   %8 = add i8 %3, 1
108   %9 = add i8 %7, %8
109   %10 = add i64 %2, 1
110   %11 = icmp ne i64 %10, 1024
111   br i1 %11, label %1, label %12
112
113 ; <label>:12                                      ; preds = %1
114   %13 = phi i8 [ %9, %1 ]
115   ret i8 %13
116 }
117
118 ;; However, we should not take unconsecutive loads of pointers into account.
119 ; CHECK: test_nonconsecutive_ptr_load
120 ; CHECK: LV: The Smallest and Widest types: 16 / 16 bits.
121 define void @test_nonconsecutive_ptr_load() nounwind ssp uwtable {
122   br label %1
123
124 ; <label>:1                                       ; preds = %13, %0
125   %2 = phi i64 [ 0, %0 ], [ %14, %13 ]
126   br label %3
127
128 ; <label>:3                                       ; preds = %3, %1
129   %4 = phi i64 [ 0, %1 ], [ %10, %3 ]
130   %5 = getelementptr inbounds [2048 x [8 x i32*]], [2048 x [8 x i32*]]* @p2, i64 0, i64 %4, i64 %2
131   %6 = getelementptr inbounds [2048 x i16], [2048 x i16]* @q2, i64 0, i64 %4
132   %7 = load i32*, i32** %5, align 2
133   %8 = ptrtoint i32* %7 to i64
134   %9 = trunc i64 %8 to i16
135   store i16 %9, i16* %6, align 8
136   %10 = add i64 %4, 1
137   %11 = trunc i64 %10 to i32
138   %12 = icmp ne i32 %11, 1024
139   br i1 %12, label %3, label %13
140
141 ; <label>:13                                      ; preds = %3
142   %14 = add i64 %2, 1
143   %15 = trunc i64 %14 to i32
144   %16 = icmp ne i32 %15, 8
145   br i1 %16, label %1, label %17
146
147 ; <label>:17                                      ; preds = %13
148   ret void
149 }
150