-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[CIR] Upstream insert op for VectorType #139146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1969,6 +1969,43 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> { | |
| let hasVerifier = 1; | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // VecInsertOp | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| def VecInsertOp : CIR_Op<"vec.insert", [Pure, | ||
| TypesMatchWith<"argument type matches vector element type", "vec", "value", | ||
| "cast<VectorType>($_self).getElementType()">, | ||
| AllTypesMatch<["result", "vec"]>]> { | ||
|
|
||
| let summary = "Insert one element into a vector object"; | ||
| let description = [{ | ||
| The `cir.vec.insert` operation replaces the element of the given vector at | ||
| the given index with the given value. The new vector with the inserted | ||
| element is returned. | ||
|
|
||
| ```mlir | ||
| %value = cir.const #cir.int<5> : !s32i | ||
| %index = cir.const #cir.int<2> : !s32i | ||
| %vec_tmp = cir.load %0 : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> | ||
| %new_vec = cir.vec.insert %value, %vec_tmp[%index : !s32i] : !cir.vector<4 x !s32i> | ||
| ``` | ||
| }]; | ||
|
|
||
| let arguments = (ins | ||
| CIR_VectorType:$vec, | ||
| AnyType:$value, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is enforced through |
||
| CIR_AnyFundamentalIntType:$index | ||
| ); | ||
|
|
||
| let results = (outs CIR_VectorType:$result); | ||
|
|
||
| let assemblyFormat = [{ | ||
| $value `,` $vec `[` $index `:` type($index) `]` attr-dict `:` | ||
| qualified(type($vec)) | ||
| }]; | ||
| } | ||
|
|
||
| //===----------------------------------------------------------------------===// | ||
| // VecExtractOp | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,6 +205,17 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr, | |
| void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst, | ||
| bool isInit) { | ||
| if (!dst.isSimple()) { | ||
| if (dst.isVectorElt()) { | ||
| // Read/modify/write the vector, inserting the new element | ||
| const mlir::Location loc = dst.getVectorPointer().getLoc(); | ||
| const mlir::Value vector = | ||
| builder.createLoad(loc, dst.getVectorAddress().getPointer()); | ||
| const mlir::Value newVector = builder.create<cir::VecInsertOp>( | ||
| loc, vector, src.getScalarVal(), dst.getVectorIdx()); | ||
| builder.createStore(loc, newVector, dst.getVectorAddress().getPointer()); | ||
| return; | ||
| } | ||
|
|
||
| cgm.errorNYI(dst.getPointer().getLoc(), | ||
| "emitStoreThroughLValue: non-simple lvalue"); | ||
| return; | ||
|
|
@@ -418,6 +429,13 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) { | |
| if (lv.isSimple()) | ||
| return RValue::get(emitLoadOfScalar(lv, loc)); | ||
|
|
||
| if (lv.isVectorElt()) { | ||
| const mlir::Value load = | ||
| builder.createLoad(getLoc(loc), lv.getVectorAddress().getPointer()); | ||
| return RValue::get(builder.create<cir::VecExtractOp>(getLoc(loc), load, | ||
| lv.getVectorIdx())); | ||
| } | ||
|
|
||
| cgm.errorNYI(loc, "emitLoadOfLValue"); | ||
| return RValue::get(nullptr); | ||
| } | ||
|
|
@@ -638,12 +656,6 @@ static Address emitArraySubscriptPtr(CIRGenFunction &cgf, | |
|
|
||
| LValue | ||
| CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) { | ||
| if (e->getBase()->getType()->isVectorType() && | ||
| !isa<ExtVectorElementExpr>(e->getBase())) { | ||
| cgm.errorNYI(e->getSourceRange(), "emitArraySubscriptExpr: VectorType"); | ||
| return LValue::makeAddr(Address::invalid(), e->getType(), LValueBaseInfo()); | ||
| } | ||
|
|
||
| if (isa<ExtVectorElementExpr>(e->getBase())) { | ||
| cgm.errorNYI(e->getSourceRange(), | ||
| "emitArraySubscriptExpr: ExtVectorElementExpr"); | ||
|
|
@@ -666,18 +678,28 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) { | |
| assert((e->getIdx() == e->getLHS() || e->getIdx() == e->getRHS()) && | ||
| "index was neither LHS nor RHS"); | ||
|
|
||
| auto emitIdxAfterBase = [&]() -> mlir::Value { | ||
| auto emitIdxAfterBase = [&](bool promote) -> mlir::Value { | ||
| const mlir::Value idx = emitScalarExpr(e->getIdx()); | ||
|
|
||
| // Extend or truncate the index type to 32 or 64-bits. | ||
| auto ptrTy = mlir::dyn_cast<cir::PointerType>(idx.getType()); | ||
| if (ptrTy && mlir::isa<cir::IntType>(ptrTy.getPointee())) | ||
| if (promote && ptrTy && ptrTy.isPtrTo<cir::IntType>()) | ||
| cgm.errorNYI(e->getSourceRange(), | ||
| "emitArraySubscriptExpr: index type cast"); | ||
| return idx; | ||
| }; | ||
|
|
||
| const mlir::Value idx = emitIdxAfterBase(); | ||
| // If the base is a vector type, then we are forming a vector element | ||
| // with this subscript. | ||
| if (e->getBase()->getType()->isVectorType() && | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You dropped a comment from the incubator here. Can you bring it in? |
||
| !isa<ExtVectorElementExpr>(e->getBase())) { | ||
| const mlir::Value idx = emitIdxAfterBase(/*promote=*/false); | ||
| const LValue lhs = emitLValue(e->getBase()); | ||
| return LValue::makeVectorElt(lhs.getAddress(), idx, e->getBase()->getType(), | ||
| lhs.getBaseInfo()); | ||
| } | ||
|
|
||
| const mlir::Value idx = emitIdxAfterBase(/*promote=*/true); | ||
| if (const Expr *array = getSimpleArrayDecayOperand(e->getBase())) { | ||
| LValue arrayLV; | ||
| if (const auto *ase = dyn_cast<ArraySubscriptExpr>(array)) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the original vector become invalid, or is it preserved in its original state, or if referenced will it contain the inserted value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I understood, if we didn't emit StoreOp, the old vector will be in its original state, but I will double check in IR and LLVM dialect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description in the incubator is confusing: we don't implicitly store. Perhaps rewrite to something like: