@@ -631,10 +631,49 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
631631 lv.getVectorIdx ()));
632632 }
633633
634+ if (lv.isExtVectorElt ())
635+ return emitLoadOfExtVectorElementLValue (lv);
636+
634637 cgm.errorNYI (loc, " emitLoadOfLValue" );
635638 return RValue::get (nullptr );
636639}
637640
641+ int64_t CIRGenFunction::getAccessedFieldNo (unsigned int idx,
642+ const mlir::ArrayAttr elts) {
643+ auto elt = mlir::cast<mlir::IntegerAttr>(elts[idx]);
644+ return elt.getInt ();
645+ }
646+
647+ // If this is a reference to a subset of the elements of a vector, create an
648+ // appropriate shufflevector.
649+ RValue CIRGenFunction::emitLoadOfExtVectorElementLValue (LValue lv) {
650+ mlir::Location loc = lv.getExtVectorPointer ().getLoc ();
651+ mlir::Value vec = builder.createLoad (loc, lv.getExtVectorAddress ());
652+
653+ // HLSL allows treating scalars as one-element vectors. Converting the scalar
654+ // IR value to a vector here allows the rest of codegen to behave as normal.
655+ if (getLangOpts ().HLSL && !mlir::isa<cir::VectorType>(vec.getType ())) {
656+ cgm.errorNYI (loc, " emitLoadOfExtVectorElementLValue: HLSL" );
657+ return {};
658+ }
659+
660+ const mlir::ArrayAttr elts = lv.getExtVectorElts ();
661+
662+ // If the result of the expression is a non-vector type, we must be extracting
663+ // a single element. Just codegen as an extractelement.
664+ const auto *exprVecTy = lv.getType ()->getAs <clang::VectorType>();
665+ if (!exprVecTy) {
666+ int64_t indexValue = getAccessedFieldNo (0 , elts);
667+ cir::ConstantOp index =
668+ builder.getConstInt (loc, builder.getSInt64Ty (), indexValue);
669+ return RValue::get (cir::VecExtractOp::create (builder, loc, vec, index));
670+ }
671+
672+ cgm.errorNYI (
673+ loc, " emitLoadOfExtVectorElementLValue: Result of expr is vector type" );
674+ return {};
675+ }
676+
638677static cir::FuncOp emitFunctionDeclPointer (CIRGenModule &cgm, GlobalDecl gd) {
639678 assert (!cir::MissingFeatures::weakRefReference ());
640679 return cgm.getAddrOfFunction (gd);
@@ -1120,6 +1159,46 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
11201159 return lv;
11211160}
11221161
1162+ LValue CIRGenFunction::emitExtVectorElementExpr (const ExtVectorElementExpr *e) {
1163+ // Emit the base vector as an l-value.
1164+ LValue base;
1165+
1166+ // ExtVectorElementExpr's base can either be a vector or pointer to vector.
1167+ if (e->isArrow ()) {
1168+ cgm.errorNYI (e->getSourceRange (),
1169+ " emitExtVectorElementExpr: pointer to vector" );
1170+ return {};
1171+ } else if (e->getBase ()->isGLValue ()) {
1172+ // Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
1173+ // emit the base as an lvalue.
1174+ assert (e->getBase ()->getType ()->isVectorType ());
1175+ base = emitLValue (e->getBase ());
1176+ } else {
1177+ // Otherwise, the base is a normal rvalue (as in (V+V).x), emit it as such.
1178+ cgm.errorNYI (e->getSourceRange (),
1179+ " emitExtVectorElementExpr: base is a normal rvalue" );
1180+ return {};
1181+ }
1182+
1183+ QualType type =
1184+ e->getType ().withCVRQualifiers (base.getQuals ().getCVRQualifiers ());
1185+
1186+ // Encode the element access list into a vector of unsigned indices.
1187+ SmallVector<uint32_t , 4 > indices;
1188+ e->getEncodedElementAccess (indices);
1189+
1190+ if (base.isSimple ()) {
1191+ SmallVector<int64_t > attrElts (indices.begin (), indices.end ());
1192+ mlir::ArrayAttr elts = builder.getI64ArrayAttr (attrElts);
1193+ return LValue::makeExtVectorElt (base.getAddress (), elts, type,
1194+ base.getBaseInfo ());
1195+ }
1196+
1197+ cgm.errorNYI (e->getSourceRange (),
1198+ " emitExtVectorElementExpr: isSimple is false" );
1199+ return {};
1200+ }
1201+
11231202LValue CIRGenFunction::emitStringLiteralLValue (const StringLiteral *e,
11241203 llvm::StringRef name) {
11251204 cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral (e, name);
0 commit comments