Skip to content
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

[CIR] Vector types, part 2 #387

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1672,14 +1672,39 @@ def GetMemberOp : CIR_Op<"get_member"> {
let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
// VecInsertOp
//===----------------------------------------------------------------------===//

def VecInsertOp : CIR_Op<"vec.insert", [Pure,
TypesMatchWith<"argument type matches vector element type", "vec", "value",
"$_self.cast<VectorType>().getEltType()">,
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.
}];

let arguments = (ins CIR_VectorType:$vec, AnyType:$value, CIR_IntType:$index);
let results = (outs CIR_VectorType:$result);

let assemblyFormat = [{
$value `,` $vec `[` $index `:` type($index) `]` attr-dict `:` type($vec)
}];

let hasVerifier = 0;
}

//===----------------------------------------------------------------------===//
// VecExtractOp
//===----------------------------------------------------------------------===//

def VecExtractOp : CIR_Op<"vec.extract", [Pure,
TypesMatchWith<"type of 'result' matches element type of 'vec'",
"vec", "result",
"$_self.cast<VectorType>().getEltType()">]> {
TypesMatchWith<"type of 'result' matches element type of 'vec'", "vec",
"result", "$_self.cast<VectorType>().getEltType()">]> {

let summary = "Extract one element from a vector object";
let description = [{
Expand All @@ -1691,7 +1716,7 @@ def VecExtractOp : CIR_Op<"vec.extract", [Pure,
let results = (outs CIR_AnyType:$result);

let assemblyFormat = [{
$vec `[` $index `:` type($index) `]` type($vec) `->` type($result) attr-dict
$vec `[` $index `:` type($index) `]` attr-dict `:` type($vec)
}];

let hasVerifier = 0;
Expand Down
37 changes: 28 additions & 9 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,16 +545,18 @@ void CIRGenFunction::buildStoreOfScalar(mlir::Value Value, Address Addr,
bool Volatile, QualType Ty,
LValueBaseInfo BaseInfo, bool isInit,
bool isNontemporal) {
if (!CGM.getCodeGenOpts().PreserveVec3Type && Ty->isVectorType() &&
Ty->castAs<clang::VectorType>()->getNumElements() == 3)
llvm_unreachable("NYI: Special treatment of 3-element vectors");

Value = buildToMemory(Value, Ty);

if (Ty->isAtomicType()) {
llvm_unreachable("NYI");
}

if (const auto *ClangVecTy = Ty->getAs<clang::VectorType>()) {
if (!CGM.getCodeGenOpts().PreserveVec3Type &&
ClangVecTy->getNumElements() == 3)
llvm_unreachable("NYI: Special treatment of 3-element vector store");
}

// Update the alloca with more info on initialization.
assert(Addr.getPointer() && "expected pointer to exist");
auto SrcAlloca =
Expand Down Expand Up @@ -622,6 +624,18 @@ RValue CIRGenFunction::buildLoadOfBitfieldLValue(LValue LV,
}

void CIRGenFunction::buildStoreThroughLValue(RValue Src, LValue Dst) {
if (!Dst.isSimple()) {
if (Dst.isVectorElt()) {
// Read/modify/write the vector, inserting the new element
mlir::Location loc = Dst.getVectorPointer().getLoc();
mlir::Value Vector = builder.createLoad(loc, Dst.getVectorAddress());
Vector = builder.create<mlir::cir::VecInsertOp>(
loc, Vector, Src.getScalarVal(), Dst.getVectorIdx());
builder.createStore(loc, Vector, Dst.getVectorAddress());
return;
}
llvm_unreachable("NYI: non-simple store through lvalue");
}
assert(Dst.isSimple() && "only implemented simple");

// There's special magic for assigning into an ARC-qualified l-value.
Expand Down Expand Up @@ -1387,7 +1401,10 @@ LValue CIRGenFunction::buildArraySubscriptExpr(const ArraySubscriptExpr *E,
// with this subscript.
if (E->getBase()->getType()->isVectorType() &&
!isa<ExtVectorElementExpr>(E->getBase())) {
llvm_unreachable("vector subscript is NYI");
LValue LHS = buildLValue(E->getBase());
auto Index = EmitIdxAfterBase(/*Promote=*/false);
return LValue::MakeVectorElt(LHS.getAddress(), Index,
E->getBase()->getType(), LHS.getBaseInfo());
}

// All the other cases basically behave like simple offsetting.
Expand Down Expand Up @@ -2369,16 +2386,18 @@ mlir::Value CIRGenFunction::buildLoadOfScalar(Address Addr, bool Volatile,
QualType Ty, mlir::Location Loc,
LValueBaseInfo BaseInfo,
bool isNontemporal) {
if (!CGM.getCodeGenOpts().PreserveVec3Type && Ty->isVectorType() &&
Ty->castAs<clang::VectorType>()->getNumElements() == 3)
llvm_unreachable("NYI: Special treatment of 3-element vectors");

// Atomic operations have to be done on integral types
LValue AtomicLValue = LValue::makeAddr(Addr, Ty, getContext(), BaseInfo);
if (Ty->isAtomicType() || LValueIsSuitableForInlineAtomic(AtomicLValue)) {
llvm_unreachable("NYI");
}

if (const auto *ClangVecTy = Ty->getAs<clang::VectorType>()) {
if (!CGM.getCodeGenOpts().PreserveVec3Type &&
ClangVecTy->getNumElements() == 3)
llvm_unreachable("NYI: Special treatment of 3-element vector load");
}

mlir::cir::LoadOp Load = builder.create<mlir::cir::LoadOp>(
Loc, Addr.getElementType(), Addr.getPointer());

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,7 +1646,7 @@ mlir::Value ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) {
if (dstTy.isa<mlir::cir::BoolType>())
return boolVal;

llvm_unreachable("destination type for negation unary operator is NYI");
llvm_unreachable("destination type for logical-not unary operator is NYI");
}

// Conversion from bool, integral, or floating-point to integral or
Expand Down
26 changes: 26 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class LValue {
unsigned Alignment;
mlir::Value V;
mlir::Type ElementType;
mlir::Value VectorIdx; // Index for vector subscript
LValueBaseInfo BaseInfo;
const CIRGenBitFieldInfo *BitFieldInfo{0};

Expand Down Expand Up @@ -301,6 +302,31 @@ class LValue {
const clang::Qualifiers &getQuals() const { return Quals; }
clang::Qualifiers &getQuals() { return Quals; }

// vector element lvalue
Address getVectorAddress() const {
return Address(getVectorPointer(), ElementType, getAlignment());
}
mlir::Value getVectorPointer() const {
assert(isVectorElt());
return V;
}
mlir::Value getVectorIdx() const {
assert(isVectorElt());
return VectorIdx;
}

static LValue MakeVectorElt(Address vecAddress, mlir::Value Index,
clang::QualType type, LValueBaseInfo BaseInfo) {
LValue R;
R.LVType = VectorElt;
R.V = vecAddress.getPointer();
R.ElementType = vecAddress.getElementType();
R.VectorIdx = Index;
R.Initialize(type, type.getQualifiers(), vecAddress.getAlignment(),
BaseInfo);
return R;
}

// bitfield lvalue
Address getBitFieldAddress() const {
return Address(getBitFieldPointer(), ElementType, getAlignment());
Expand Down
Loading
Loading