xref: /llvm-project/llvm/test/Transforms/InstCombine/gep-vector.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine %s -S | FileCheck %s
3
4@block = global [64 x [8192 x i8]] zeroinitializer, align 1
5
6define <2 x ptr> @vectorindex1() {
7; CHECK-LABEL: @vectorindex1(
8; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> <i64 0, i64 1>, <2 x i64> splat (i64 8192))
9;
10  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, <2 x i64> <i64 0, i64 1>, i64 8192
11  ret <2 x ptr> %1
12}
13
14define <2 x ptr> @vectorindex2() {
15; CHECK-LABEL: @vectorindex2(
16; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> splat (i64 1), <2 x i64> <i64 8191, i64 8193>)
17;
18  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, i64 1, <2 x i64> <i64 8191, i64 8193>
19  ret <2 x ptr> %1
20}
21
22define <2 x ptr> @vectorindex3() {
23; CHECK-LABEL: @vectorindex3(
24; CHECK-NEXT:    ret <2 x ptr> getelementptr inbounds ([64 x [8192 x i8]], ptr @block, <2 x i64> zeroinitializer, <2 x i64> <i64 0, i64 1>, <2 x i64> <i64 8191, i64 8193>)
25;
26  %1 = getelementptr inbounds [64 x [8192 x i8]], ptr @block, i64 0, <2 x i64> <i64 0, i64 1>, <2 x i64> <i64 8191, i64 8193>
27  ret <2 x ptr> %1
28}
29
30; Negative test - datalayout's alloc size for the 2 types must match.
31
32define ptr @bitcast_vec_to_array_gep(ptr %x, i64 %y, i64 %z) {
33; CHECK-LABEL: @bitcast_vec_to_array_gep(
34; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
35; CHECK-NEXT:    ret ptr [[GEP]]
36;
37  %gep = getelementptr [7 x i32], ptr %x, i64 %y, i64 %z
38  ret ptr %gep
39}
40
41; Negative test - datalayout's alloc size for the 2 types must match.
42
43define ptr @bitcast_array_to_vec_gep(ptr %x, i64 %y, i64 %z) {
44; CHECK-LABEL: @bitcast_array_to_vec_gep(
45; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <3 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
46; CHECK-NEXT:    ret ptr [[GEP]]
47;
48  %gep = getelementptr inbounds <3 x i32>, ptr %x, i64 %y, i64 %z
49  ret ptr %gep
50}
51
52; Sizes and types match - safe to remove bitcast.
53
54define ptr @bitcast_vec_to_array_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
55; CHECK-LABEL: @bitcast_vec_to_array_gep_matching_alloc_size(
56; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i32], ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
57; CHECK-NEXT:    ret ptr [[GEP]]
58;
59  %gep = getelementptr [4 x i32], ptr %x, i64 %y, i64 %z
60  ret ptr %gep
61}
62
63; Sizes and types match - safe to remove bitcast.
64
65define ptr @bitcast_array_to_vec_gep_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
66; CHECK-LABEL: @bitcast_array_to_vec_gep_matching_alloc_size(
67; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds <4 x i32>, ptr [[X:%.*]], i64 [[Y:%.*]], i64 [[Z:%.*]]
68; CHECK-NEXT:    ret ptr [[GEP]]
69;
70  %gep = getelementptr inbounds <4 x i32>, ptr %x, i64 %y, i64 %z
71  ret ptr %gep
72}
73
74; Negative test - datalayout's alloc size for the 2 types must match.
75
76define ptr addrspace(3) @bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
77; CHECK-LABEL: @bitcast_vec_to_array_addrspace(
78; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
79; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
80; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
81;
82  %asc = addrspacecast ptr %x to ptr addrspace(3)
83  %gep = getelementptr [7 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
84  ret ptr addrspace(3) %gep
85}
86
87; Negative test - datalayout's alloc size for the 2 types must match.
88
89define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace(ptr %x, i64 %y, i64 %z) {
90; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace(
91; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
92; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [7 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
93; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
94;
95  %asc = addrspacecast ptr %x to ptr addrspace(3)
96  %gep = getelementptr inbounds [7 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
97  ret ptr addrspace(3) %gep
98}
99
100; Sizes and types match - safe to remove bitcast.
101
102define ptr addrspace(3) @bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
103; CHECK-LABEL: @bitcast_vec_to_array_addrspace_matching_alloc_size(
104; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
105; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
106; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
107;
108  %asc = addrspacecast ptr %x to ptr addrspace(3)
109  %gep = getelementptr [4 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
110  ret ptr addrspace(3) %gep
111}
112
113; Sizes and types match - safe to remove bitcast.
114
115define ptr addrspace(3) @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(ptr %x, i64 %y, i64 %z) {
116; CHECK-LABEL: @inbounds_bitcast_vec_to_array_addrspace_matching_alloc_size(
117; CHECK-NEXT:    [[ASC:%.*]] = addrspacecast ptr [[X:%.*]] to ptr addrspace(3)
118; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [4 x i32], ptr addrspace(3) [[ASC]], i64 [[Y:%.*]], i64 [[Z:%.*]]
119; CHECK-NEXT:    ret ptr addrspace(3) [[GEP]]
120;
121  %asc = addrspacecast ptr %x to ptr addrspace(3)
122  %gep = getelementptr inbounds [4 x i32], ptr addrspace(3) %asc, i64 %y, i64 %z
123  ret ptr addrspace(3) %gep
124}
125
126; Negative test - avoid doing bitcast on ptr, because '16' should be scaled by 'vscale'.
127
128define ptr @test_accumulate_constant_offset_vscale_nonzero(<vscale x 16 x i1> %pg, ptr %base) {
129; CHECK-LABEL: @test_accumulate_constant_offset_vscale_nonzero(
130; CHECK-NEXT:    [[TMP1:%.*]] = call i64 @llvm.vscale.i64()
131; CHECK-NEXT:    [[TMP2:%.*]] = shl i64 [[TMP1]], 4
132; CHECK-NEXT:    [[GEP_OFFS:%.*]] = or disjoint i64 [[TMP2]], 4
133; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 [[GEP_OFFS]]
134; CHECK-NEXT:    ret ptr [[GEP]]
135;
136  %gep = getelementptr <vscale x 16 x i8>, ptr %base, i64 1, i64 4
137  ret ptr %gep
138}
139
140define ptr @test_accumulate_constant_offset_vscale_zero(<vscale x 16 x i1> %pg, ptr %base) {
141; CHECK-LABEL: @test_accumulate_constant_offset_vscale_zero(
142; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[BASE:%.*]], i64 4
143; CHECK-NEXT:    ret ptr [[GEP]]
144;
145  %gep = getelementptr <vscale x 16 x i8>, ptr %base, i64 0, i64 4
146  ret ptr %gep
147}
148