Skip to content

Commit a1e523b

Browse files
authored
[CIR] ExtVectorElementExpr with pointer to a vector (llvm#168203)
Upstream ExtVectorElementExpr with a pointer to a vector
1 parent 5ed26ad commit a1e523b

File tree

2 files changed

+96
-3
lines changed

2 files changed

+96
-3
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,9 +1174,14 @@ LValue CIRGenFunction::emitExtVectorElementExpr(const ExtVectorElementExpr *e) {
11741174

11751175
// ExtVectorElementExpr's base can either be a vector or pointer to vector.
11761176
if (e->isArrow()) {
1177-
cgm.errorNYI(e->getSourceRange(),
1178-
"emitExtVectorElementExpr: pointer to vector");
1179-
return {};
1177+
// If it is a pointer to a vector, emit the address and form an lvalue with
1178+
// it.
1179+
LValueBaseInfo baseInfo;
1180+
Address ptr = emitPointerWithAlignment(e->getBase(), &baseInfo);
1181+
const auto *clangPtrTy =
1182+
e->getBase()->getType()->castAs<clang::PointerType>();
1183+
base = makeAddrLValue(ptr, clangPtrTy->getPointeeType(), baseInfo);
1184+
base.getQuals().removeObjCGCAttr();
11801185
} else if (e->getBase()->isGLValue()) {
11811186
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
11821187
// emit the base as an lvalue.

clang/test/CIR/CodeGen/vector-ext-element.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,91 @@ void element_expr_from_gl_with_vec_result() {
8383
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
8484
// OGCG: %[[C_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
8585
// OGCG: store <4 x i32> %[[C_VALUE]], ptr %[[C_ADDR]], align 16
86+
87+
void element_expr_from_pointer() {
88+
vi4 *a;
89+
int X = a->x;
90+
int Y = a->y;
91+
}
92+
93+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!cir.vector<4 x !s32i>>, !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, ["a"]
94+
// CIR: %[[X_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["X", init]
95+
// CIR: %[[Y_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["Y", init]
96+
// CIR: %[[TMP_A_PTR:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, !cir.ptr<!cir.vector<4 x !s32i>>
97+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[TMP_A_PTR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
98+
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s64i
99+
// CIR: %[[ELEM_0:.*]] = cir.vec.extract %[[TMP_A]][%[[CONST_0]] : !s64i] : !cir.vector<4 x !s32i>
100+
// CIR: cir.store {{.*}} %[[ELEM_0]], %[[X_ADDR]] : !s32i, !cir.ptr<!s32i>
101+
// CIR: %[[TMP_A_PTR:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, !cir.ptr<!cir.vector<4 x !s32i>>
102+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[TMP_A_PTR:.*]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
103+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s64i
104+
// CIR: %[[ELEM_1:.*]] = cir.vec.extract %[[TMP_A]][%[[CONST_1]] : !s64i] : !cir.vector<4 x !s32i>
105+
// CIR: cir.store {{.*}} %[[ELEM_1]], %[[Y_ADDR]] : !s32i, !cir.ptr<!s32i>
106+
107+
// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8
108+
// LLVM: %[[X_ADDR:.*]] = alloca i32, i64 1, align 4
109+
// LLVM: %[[Y_ADDR:.*]] = alloca i32, i64 1, align 4
110+
// LLVM: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
111+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
112+
// LLVM: %[[ELEM_0:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 0
113+
// LLVM: store i32 %[[ELEM_0]], ptr %[[X_ADDR]], align 4
114+
// LLVM: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
115+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
116+
// LLVM: %[[ELEM_1:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 1
117+
// LLVM: store i32 %[[ELEM_1]], ptr %[[Y_ADDR]], align 4
118+
119+
// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
120+
// OGCG: %[[X_ADDR:.*]] = alloca i32, align 4
121+
// OGCG: %[[Y_ADDR:.*]] = alloca i32, align 4
122+
// OGCG: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
123+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
124+
// OGCG: %[[ELEM_0:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 0
125+
// OGCG: store i32 %[[ELEM_0]], ptr %[[X_ADDR]], align 4
126+
// OGCG: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
127+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
128+
// OGCG: %[[ELEM_1:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 1
129+
// OGCG: store i32 %[[ELEM_1]], ptr %[[Y_ADDR]], align 4
130+
131+
void element_expr_from_pointer_with_vec_result() {
132+
vi4 *a;
133+
vi2 b = a->xy;
134+
vi4 c = a->wzyx;
135+
}
136+
137+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.ptr<!cir.vector<4 x !s32i>>, !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, ["a"]
138+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>, ["b", init]
139+
// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init]
140+
// CIR: %[[TMP_A_PTR:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, !cir.ptr<!cir.vector<4 x !s32i>>
141+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[TMP_A_PTR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
142+
// CIR: %[[POISON:.*]] = cir.const #cir.poison : !cir.vector<4 x !s32i>
143+
// CIR: %[[B_VALUE:.*]] = cir.vec.shuffle(%[[TMP_A]], %[[POISON]] : !cir.vector<4 x !s32i>) [#cir.int<0> : !s32i, #cir.int<1> : !s32i] : !cir.vector<2 x !s32i>
144+
// CIR: cir.store {{.*}} %[[B_VALUE]], %[[B_ADDR]] : !cir.vector<2 x !s32i>, !cir.ptr<!cir.vector<2 x !s32i>>
145+
// CIR: %[[TMP_A_PTR:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.ptr<!cir.vector<4 x !s32i>>>, !cir.ptr<!cir.vector<4 x !s32i>>
146+
// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[TMP_A_PTR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
147+
// CIR: %[[POISON:.*]] = cir.const #cir.poison : !cir.vector<4 x !s32i>
148+
// CIR: %[[C_VALUE:.*]] = cir.vec.shuffle(%[[TMP_A]], %[[POISON]] : !cir.vector<4 x !s32i>) [#cir.int<3> : !s32i, #cir.int<2> : !s32i, #cir.int<1> : !s32i, #cir.int<0> : !s32i] : !cir.vector<4 x !s32i>
149+
// CIR: cir.store {{.*}} %[[C_VALUE]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
150+
151+
// LLVM: %[[A_ADDR:.*]] = alloca ptr, i64 1, align 8
152+
// LLVM: %[[B_ADDR:.*]] = alloca <2 x i32>, i64 1, align 8
153+
// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16
154+
// LLVM: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
155+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
156+
// LLVM: %[[B_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
157+
// LLVM: store <2 x i32> %[[B_VALUE]], ptr %[[B_ADDR]], align 8
158+
// LLVM: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
159+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
160+
// LLVM: %[[C_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
161+
// LLVM: store <4 x i32> %[[C_VALUE]], ptr %[[C_ADDR]], align 16
162+
163+
// OGCG: %[[A_ADDR:.*]] = alloca ptr, align 8
164+
// OGCG: %[[B_ADDR:.*]] = alloca <2 x i32>, align 8
165+
// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16
166+
// OGCG: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
167+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
168+
// OGCG: %[[B_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <2 x i32> <i32 0, i32 1>
169+
// OGCG: store <2 x i32> %[[B_VALUE]], ptr %[[B_ADDR]], align 8
170+
// OGCG: %[[TMP_A_PTR:.*]] = load ptr, ptr %[[A_ADDR]], align 8
171+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[TMP_A_PTR]], align 16
172+
// OGCG: %[[C_VALUE:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
173+
// OGCG: store <4 x i32> %[[C_VALUE]], ptr %[[C_ADDR]], align 16

0 commit comments

Comments
 (0)