1; RUN: opt -S -mtriple=amdgcn--amdhsa -load-store-vectorizer < %s | FileCheck %s
2
3; Check that vectorizer can find a GEP through bitcast
4; CHECK-LABEL: @vect_zext_bitcast_f32_to_i32_idx
5; CHECK: load <4 x i32>
6define void @vect_zext_bitcast_f32_to_i32_idx(float addrspace(1)* %arg1, i32 %base) {
7  %add1 = add nuw i32 %base, 0
8  %zext1 = zext i32 %add1 to i64
9  %gep1 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext1
10  %f2i1 = bitcast float addrspace(1)* %gep1 to i32 addrspace(1)*
11  %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
12  %add2 = add nuw i32 %base, 1
13  %zext2 = zext i32 %add2 to i64
14  %gep2 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext2
15  %f2i2 = bitcast float addrspace(1)* %gep2 to i32 addrspace(1)*
16  %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
17  %add3 = add nuw i32 %base, 2
18  %zext3 = zext i32 %add3 to i64
19  %gep3 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext3
20  %f2i3 = bitcast float addrspace(1)* %gep3 to i32 addrspace(1)*
21  %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
22  %add4 = add nuw i32 %base, 3
23  %zext4 = zext i32 %add4 to i64
24  %gep4 = getelementptr inbounds float, float addrspace(1)* %arg1, i64 %zext4
25  %f2i4 = bitcast float addrspace(1)* %gep4 to i32 addrspace(1)*
26  %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
27  ret void
28}
29
30; CHECK-LABEL: @vect_zext_bitcast_i8_st1_to_i32_idx
31; CHECK: load i32
32; CHECK: load i32
33; CHECK: load i32
34; CHECK: load i32
35define void @vect_zext_bitcast_i8_st1_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) {
36  %add1 = add nuw i32 %base, 0
37  %zext1 = zext i32 %add1 to i64
38  %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1
39  %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)*
40  %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
41  %add2 = add nuw i32 %base, 1
42  %zext2 = zext i32 %add2 to i64
43  %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2
44  %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)*
45  %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
46  %add3 = add nuw i32 %base, 2
47  %zext3 = zext i32 %add3 to i64
48  %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3
49  %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)*
50  %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
51  %add4 = add nuw i32 %base, 3
52  %zext4 = zext i32 %add4 to i64
53  %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4
54  %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)*
55  %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
56  ret void
57}
58
59; CHECK-LABEL: @vect_zext_bitcast_i8_st4_to_i32_idx
60; CHECK: load <4 x i32>
61define void @vect_zext_bitcast_i8_st4_to_i32_idx(i8 addrspace(1)* %arg1, i32 %base) {
62  %add1 = add nuw i32 %base, 0
63  %zext1 = zext i32 %add1 to i64
64  %gep1 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext1
65  %f2i1 = bitcast i8 addrspace(1)* %gep1 to i32 addrspace(1)*
66  %load1 = load i32, i32 addrspace(1)* %f2i1, align 4
67  %add2 = add nuw i32 %base, 4
68  %zext2 = zext i32 %add2 to i64
69  %gep2 = getelementptr inbounds i8,i8 addrspace(1)* %arg1, i64 %zext2
70  %f2i2 = bitcast i8 addrspace(1)* %gep2 to i32 addrspace(1)*
71  %load2 = load i32, i32 addrspace(1)* %f2i2, align 4
72  %add3 = add nuw i32 %base, 8
73  %zext3 = zext i32 %add3 to i64
74  %gep3 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext3
75  %f2i3 = bitcast i8 addrspace(1)* %gep3 to i32 addrspace(1)*
76  %load3 = load i32, i32 addrspace(1)* %f2i3, align 4
77  %add4 = add nuw i32 %base, 12
78  %zext4 = zext i32 %add4 to i64
79  %gep4 = getelementptr inbounds i8, i8 addrspace(1)* %arg1, i64 %zext4
80  %f2i4 = bitcast i8 addrspace(1)* %gep4 to i32 addrspace(1)*
81  %load4 = load i32, i32 addrspace(1)* %f2i4, align 4
82  ret void
83}
84
85; CHECK-LABEL: @vect_zext_bitcast_negative_ptr_delta
86; CHECK: load <2 x i32>
87define void @vect_zext_bitcast_negative_ptr_delta(i32 addrspace(1)* %p, i32 %base) {
88  %p.bitcasted = bitcast i32 addrspace(1)* %p to i16 addrspace(1)*
89  %a.offset = add nuw i32 %base, 4
90  %t.offset.zexted = zext i32 %base to i64
91  %a.offset.zexted = zext i32 %a.offset to i64
92  %t.ptr = getelementptr inbounds i16, i16 addrspace(1)* %p.bitcasted, i64 %t.offset.zexted
93  %a.ptr = getelementptr inbounds i16, i16 addrspace(1)* %p.bitcasted, i64 %a.offset.zexted
94  %b.ptr = getelementptr inbounds i16, i16 addrspace(1)* %t.ptr, i64 6
95  %a.ptr.bitcasted = bitcast i16 addrspace(1)* %a.ptr to i32 addrspace(1)*
96  %b.ptr.bitcasted = bitcast i16 addrspace(1)* %b.ptr to i32 addrspace(1)*
97  %a.val = load i32, i32 addrspace(1)* %a.ptr.bitcasted
98  %b.val = load i32, i32 addrspace(1)* %b.ptr.bitcasted
99  ret void
100}
101
102; Check i1 corner case
103; CHECK-LABEL: @zexted_i1_gep_index
104; CHECK: load i32
105; CHECK: load i32
106define void @zexted_i1_gep_index(i32 addrspace(1)* %p, i32 %val) {
107  %selector = icmp eq i32 %val, 0
108  %flipped = xor i1 %selector, 1
109  %index.0 = zext i1 %selector to i64
110  %index.1 = zext i1 %flipped to i64
111  %gep.0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.0
112  %gep.1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.1
113  %val0 = load i32, i32 addrspace(1)* %gep.0
114  %val1 = load i32, i32 addrspace(1)* %gep.1
115  ret void
116}
117
118; Check i1 corner case
119; CHECK-LABEL: @sexted_i1_gep_index
120; CHECK: load i32
121; CHECK: load i32
122define void @sexted_i1_gep_index(i32 addrspace(1)* %p, i32 %val) {
123  %selector = icmp eq i32 %val, 0
124  %flipped = xor i1 %selector, 1
125  %index.0 = sext i1 %selector to i64
126  %index.1 = sext i1 %flipped to i64
127  %gep.0 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.0
128  %gep.1 = getelementptr inbounds i32, i32 addrspace(1)* %p, i64 %index.1
129  %val0 = load i32, i32 addrspace(1)* %gep.0
130  %val1 = load i32, i32 addrspace(1)* %gep.1
131  ret void
132}
133