1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes='function(scalarizer)' %s | FileCheck %s
4 ; Check that the scalarizer can handle vector GEPs with scalar indices
6 @vec = global <4 x ptr> <ptr null, ptr null, ptr null, ptr null>
8 @ptr = global [4 x i16] [i16 1, i16 2, i16 3, i16 4]
9 @ptrptr = global ptr null
12 define void @test1() {
13 ; CHECK-LABEL: @test1(
15 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x ptr>, ptr @vec, align 32
16 ; CHECK-NEXT: [[DOTI0:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 0
17 ; CHECK-NEXT: [[DOTI01:%.*]] = getelementptr i16, ptr [[DOTI0]], i16 1
18 ; CHECK-NEXT: [[DOTI1:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 1
19 ; CHECK-NEXT: [[DOTI12:%.*]] = getelementptr i16, ptr [[DOTI1]], i16 1
20 ; CHECK-NEXT: [[DOTI2:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 2
21 ; CHECK-NEXT: [[DOTI23:%.*]] = getelementptr i16, ptr [[DOTI2]], i16 1
22 ; CHECK-NEXT: [[DOTI3:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 3
23 ; CHECK-NEXT: [[DOTI34:%.*]] = getelementptr i16, ptr [[DOTI3]], i16 1
24 ; CHECK-NEXT: ret void
27 %0 = load <4 x ptr>, ptr @vec
28 %1 = getelementptr i16, <4 x ptr> %0, i16 1
34 define void @test2() {
35 ; CHECK-LABEL: @test2(
37 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x ptr>, ptr @vec, align 32
38 ; CHECK-NEXT: [[DOTI0:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 0
39 ; CHECK-NEXT: [[DOTI1:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 1
40 ; CHECK-NEXT: [[DOTI2:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 2
41 ; CHECK-NEXT: [[DOTI3:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 3
42 ; CHECK-NEXT: [[INDEX:%.*]] = load i16, ptr @index, align 2
43 ; CHECK-NEXT: [[DOTI01:%.*]] = getelementptr i16, ptr [[DOTI0]], i16 [[INDEX]]
44 ; CHECK-NEXT: [[DOTI12:%.*]] = getelementptr i16, ptr [[DOTI1]], i16 [[INDEX]]
45 ; CHECK-NEXT: [[DOTI23:%.*]] = getelementptr i16, ptr [[DOTI2]], i16 [[INDEX]]
46 ; CHECK-NEXT: [[DOTI34:%.*]] = getelementptr i16, ptr [[DOTI3]], i16 [[INDEX]]
47 ; CHECK-NEXT: ret void
50 %0 = load <4 x ptr>, ptr @vec
51 %index = load i16, ptr @index
52 %1 = getelementptr i16, <4 x ptr> %0, i16 %index
57 ; Check that the scalarizer can handle vector GEPs with scalar pointer
60 define <4 x ptr> @test3_constexpr() {
61 ; CHECK-LABEL: @test3_constexpr(
63 ; CHECK-NEXT: ret <4 x ptr> getelementptr (i16, ptr @ptr, <4 x i64> <i64 0, i64 1, i64 2, i64 3>)
66 ret <4 x ptr> getelementptr (i16, ptr @ptr, <4 x i64> <i64 0, i64 1, i64 2, i64 3>)
70 define <4 x ptr> @test3_constbase(i16 %idx) {
71 ; CHECK-LABEL: @test3_constbase(
73 ; CHECK-NEXT: [[OFFSET:%.*]] = getelementptr [4 x i16], ptr @ptr, i16 0, i16 [[IDX:%.*]]
74 ; CHECK-NEXT: [[GEP_I0:%.*]] = getelementptr i16, ptr [[OFFSET]], i16 0
75 ; CHECK-NEXT: [[GEP_I1:%.*]] = getelementptr i16, ptr [[OFFSET]], i16 1
76 ; CHECK-NEXT: [[GEP_I2:%.*]] = getelementptr i16, ptr [[OFFSET]], i16 2
77 ; CHECK-NEXT: [[GEP_I3:%.*]] = getelementptr i16, ptr [[OFFSET]], i16 3
78 ; CHECK-NEXT: [[GEP_UPTO0:%.*]] = insertelement <4 x ptr> poison, ptr [[GEP_I0]], i64 0
79 ; CHECK-NEXT: [[GEP_UPTO1:%.*]] = insertelement <4 x ptr> [[GEP_UPTO0]], ptr [[GEP_I1]], i64 1
80 ; CHECK-NEXT: [[GEP_UPTO2:%.*]] = insertelement <4 x ptr> [[GEP_UPTO1]], ptr [[GEP_I2]], i64 2
81 ; CHECK-NEXT: [[GEP:%.*]] = insertelement <4 x ptr> [[GEP_UPTO2]], ptr [[GEP_I3]], i64 3
82 ; CHECK-NEXT: ret <4 x ptr> [[GEP]]
85 %offset = getelementptr [4 x i16], ptr @ptr, i16 0, i16 %idx
86 %gep = getelementptr i16, ptr %offset, <4 x i16> <i16 0, i16 1, i16 2, i16 3>
90 ; Constant pointer with a variable vector offset
91 define <4 x ptr> @test3_varoffset(<4 x i16> %offset) {
92 ; CHECK-LABEL: @test3_varoffset(
94 ; CHECK-NEXT: [[OFFSET_I0:%.*]] = extractelement <4 x i16> [[OFFSET:%.*]], i64 0
95 ; CHECK-NEXT: [[GEP_I0:%.*]] = getelementptr i16, ptr @ptr, i16 [[OFFSET_I0]]
96 ; CHECK-NEXT: [[OFFSET_I1:%.*]] = extractelement <4 x i16> [[OFFSET]], i64 1
97 ; CHECK-NEXT: [[GEP_I1:%.*]] = getelementptr i16, ptr @ptr, i16 [[OFFSET_I1]]
98 ; CHECK-NEXT: [[OFFSET_I2:%.*]] = extractelement <4 x i16> [[OFFSET]], i64 2
99 ; CHECK-NEXT: [[GEP_I2:%.*]] = getelementptr i16, ptr @ptr, i16 [[OFFSET_I2]]
100 ; CHECK-NEXT: [[OFFSET_I3:%.*]] = extractelement <4 x i16> [[OFFSET]], i64 3
101 ; CHECK-NEXT: [[GEP_I3:%.*]] = getelementptr i16, ptr @ptr, i16 [[OFFSET_I3]]
102 ; CHECK-NEXT: [[GEP_UPTO0:%.*]] = insertelement <4 x ptr> poison, ptr [[GEP_I0]], i64 0
103 ; CHECK-NEXT: [[GEP_UPTO1:%.*]] = insertelement <4 x ptr> [[GEP_UPTO0]], ptr [[GEP_I1]], i64 1
104 ; CHECK-NEXT: [[GEP_UPTO2:%.*]] = insertelement <4 x ptr> [[GEP_UPTO1]], ptr [[GEP_I2]], i64 2
105 ; CHECK-NEXT: [[GEP:%.*]] = insertelement <4 x ptr> [[GEP_UPTO2]], ptr [[GEP_I3]], i64 3
106 ; CHECK-NEXT: ret <4 x ptr> [[GEP]]
109 %gep = getelementptr i16, ptr @ptr, <4 x i16> %offset
113 ; non-constant pointer
114 define void @test4() {
115 ; CHECK-LABEL: @test4(
117 ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr @ptrptr, align 8
118 ; CHECK-NEXT: [[DOTI0:%.*]] = getelementptr i16, ptr [[TMP0]], i16 0
119 ; CHECK-NEXT: [[DOTI1:%.*]] = getelementptr i16, ptr [[TMP0]], i16 1
120 ; CHECK-NEXT: [[DOTI2:%.*]] = getelementptr i16, ptr [[TMP0]], i16 2
121 ; CHECK-NEXT: [[DOTI3:%.*]] = getelementptr i16, ptr [[TMP0]], i16 3
122 ; CHECK-NEXT: ret void
125 %0 = load ptr, ptr @ptrptr
126 %1 = getelementptr i16, ptr %0, <4 x i16> <i16 0, i16 1, i16 2, i16 3>
131 ; constant index, inbounds
132 define void @test5() {
133 ; CHECK-LABEL: @test5(
135 ; CHECK-NEXT: [[TMP0:%.*]] = load <4 x ptr>, ptr @vec, align 32
136 ; CHECK-NEXT: [[DOTI0:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 0
137 ; CHECK-NEXT: [[DOTI01:%.*]] = getelementptr inbounds i16, ptr [[DOTI0]], i16 1
138 ; CHECK-NEXT: [[DOTI1:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 1
139 ; CHECK-NEXT: [[DOTI12:%.*]] = getelementptr inbounds i16, ptr [[DOTI1]], i16 1
140 ; CHECK-NEXT: [[DOTI2:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 2
141 ; CHECK-NEXT: [[DOTI23:%.*]] = getelementptr inbounds i16, ptr [[DOTI2]], i16 1
142 ; CHECK-NEXT: [[DOTI3:%.*]] = extractelement <4 x ptr> [[TMP0]], i64 3
143 ; CHECK-NEXT: [[DOTI34:%.*]] = getelementptr inbounds i16, ptr [[DOTI3]], i16 1
144 ; CHECK-NEXT: ret void
147 %0 = load <4 x ptr>, ptr @vec
148 %1 = getelementptr inbounds i16, <4 x ptr> %0, i16 1