Skip to content

Commit

Permalink
[GlobalISel] Import extract/insert subvector (llvm#110287)
Browse files Browse the repository at this point in the history
  • Loading branch information
tschuett authored and VitaNuo committed Oct 2, 2024
1 parent 0a8f58f commit b487db9
Show file tree
Hide file tree
Showing 3 changed files with 457 additions and 0 deletions.
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,8 +546,10 @@ class IRTranslator : public MachineFunctionPass {
bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);

bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
bool translateInsertVector(const User &U, MachineIRBuilder &MIRBuilder);

bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
bool translateExtractVector(const User &U, MachineIRBuilder &MIRBuilder);

bool translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder);

Expand Down
103 changes: 103 additions & 0 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2588,6 +2588,10 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
getOrCreateVReg(*CI.getOperand(0)),
getOrCreateVReg(*CI.getOperand(1)));
return true;
case Intrinsic::vector_extract:
return translateExtractVector(CI, MIRBuilder);
case Intrinsic::vector_insert:
return translateInsertVector(CI, MIRBuilder);
case Intrinsic::prefetch: {
Value *Addr = CI.getOperand(0);
unsigned RW = cast<ConstantInt>(CI.getOperand(1))->getZExtValue();
Expand Down Expand Up @@ -3163,6 +3167,57 @@ bool IRTranslator::translateInsertElement(const User &U,
return true;
}

bool IRTranslator::translateInsertVector(const User &U,
MachineIRBuilder &MIRBuilder) {
Register Dst = getOrCreateVReg(U);
Register Vec = getOrCreateVReg(*U.getOperand(0));
Register Elt = getOrCreateVReg(*U.getOperand(1));

ConstantInt *CI = cast<ConstantInt>(U.getOperand(2));
unsigned PreferredVecIdxWidth = TLI->getVectorIdxTy(*DL).getSizeInBits();

// Resize Index to preferred index width.
if (CI->getBitWidth() != PreferredVecIdxWidth) {
APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
CI = ConstantInt::get(CI->getContext(), NewIdx);
}

// If it is a <1 x Ty> vector, we have to use other means.
if (auto *ResultType = dyn_cast<FixedVectorType>(U.getOperand(1)->getType());
ResultType && ResultType->getNumElements() == 1) {
if (auto *InputType = dyn_cast<FixedVectorType>(U.getOperand(0)->getType());
InputType && InputType->getNumElements() == 1) {
// We are inserting an illegal fixed vector into an illegal
// fixed vector, use the scalar as it is not a legal vector type
// in LLT.
return translateCopy(U, *U.getOperand(0), MIRBuilder);
}
if (isa<FixedVectorType>(U.getOperand(0)->getType())) {
// We are inserting an illegal fixed vector into a legal fixed
// vector, use the scalar as it is not a legal vector type in
// LLT.
Register Idx = getOrCreateVReg(*CI);
MIRBuilder.buildInsertVectorElement(Dst, Vec, Elt, Idx);
return true;
}
if (isa<ScalableVectorType>(U.getOperand(0)->getType())) {
// We are inserting an illegal fixed vector into a scalable
// vector, use a scalar element insert.
LLT VecIdxTy = LLT::scalar(PreferredVecIdxWidth);
Register Idx = getOrCreateVReg(*CI);
auto ScaledIndex = MIRBuilder.buildMul(
VecIdxTy, MIRBuilder.buildVScale(VecIdxTy, 1), Idx);
MIRBuilder.buildInsertVectorElement(Dst, Vec, Elt, ScaledIndex);
return true;
}
}

MIRBuilder.buildInsertSubvector(
getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)),
getOrCreateVReg(*U.getOperand(1)), CI->getZExtValue());
return true;
}

bool IRTranslator::translateExtractElement(const User &U,
MachineIRBuilder &MIRBuilder) {
// If it is a <1 x Ty> vector, use the scalar as it is
Expand Down Expand Up @@ -3191,6 +3246,54 @@ bool IRTranslator::translateExtractElement(const User &U,
return true;
}

bool IRTranslator::translateExtractVector(const User &U,
MachineIRBuilder &MIRBuilder) {
Register Res = getOrCreateVReg(U);
Register Vec = getOrCreateVReg(*U.getOperand(0));
ConstantInt *CI = cast<ConstantInt>(U.getOperand(1));
unsigned PreferredVecIdxWidth = TLI->getVectorIdxTy(*DL).getSizeInBits();

// Resize Index to preferred index width.
if (CI->getBitWidth() != PreferredVecIdxWidth) {
APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
CI = ConstantInt::get(CI->getContext(), NewIdx);
}

// If it is a <1 x Ty> vector, we have to use other means.
if (auto *ResultType = dyn_cast<FixedVectorType>(U.getType());
ResultType && ResultType->getNumElements() == 1) {
if (auto *InputType = dyn_cast<FixedVectorType>(U.getOperand(0)->getType());
InputType && InputType->getNumElements() == 1) {
// We are extracting an illegal fixed vector from an illegal fixed vector,
// use the scalar as it is not a legal vector type in LLT.
return translateCopy(U, *U.getOperand(0), MIRBuilder);
}
if (isa<FixedVectorType>(U.getOperand(0)->getType())) {
// We are extracting an illegal fixed vector from a legal fixed
// vector, use the scalar as it is not a legal vector type in
// LLT.
Register Idx = getOrCreateVReg(*CI);
MIRBuilder.buildExtractVectorElement(Res, Vec, Idx);
return true;
}
if (isa<ScalableVectorType>(U.getOperand(0)->getType())) {
// We are extracting an illegal fixed vector from a scalable
// vector, use a scalar element extract.
LLT VecIdxTy = LLT::scalar(PreferredVecIdxWidth);
Register Idx = getOrCreateVReg(*CI);
auto ScaledIndex = MIRBuilder.buildMul(
VecIdxTy, MIRBuilder.buildVScale(VecIdxTy, 1), Idx);
MIRBuilder.buildExtractVectorElement(Res, Vec, ScaledIndex);
return true;
}
}

MIRBuilder.buildExtractSubvector(getOrCreateVReg(U),
getOrCreateVReg(*U.getOperand(0)),
CI->getZExtValue());
return true;
}

bool IRTranslator::translateShuffleVector(const User &U,
MachineIRBuilder &MIRBuilder) {
// A ShuffleVector that operates on scalable vectors is a splat vector where
Expand Down
Loading

0 comments on commit b487db9

Please sign in to comment.