Skip to content

Commit 53943de

Browse files
author
Thorsten Schütt
authored
[GlobalISel] Import extract/insert subvector (#110287)
Test: AArch64/GlobalISel/irtranslator-subvector.ll Reference: https://llvm.org/docs/LangRef.html#llvm-vector-extract-intrinsic https://llvm.org/docs/LangRef.html#llvm-vector-insert-intrinsic
1 parent f8ba021 commit 53943de

File tree

3 files changed

+457
-0
lines changed

3 files changed

+457
-0
lines changed

llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,10 @@ class IRTranslator : public MachineFunctionPass {
546546
bool translateVAArg(const User &U, MachineIRBuilder &MIRBuilder);
547547

548548
bool translateInsertElement(const User &U, MachineIRBuilder &MIRBuilder);
549+
bool translateInsertVector(const User &U, MachineIRBuilder &MIRBuilder);
549550

550551
bool translateExtractElement(const User &U, MachineIRBuilder &MIRBuilder);
552+
bool translateExtractVector(const User &U, MachineIRBuilder &MIRBuilder);
551553

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

llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,6 +2588,10 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
25882588
getOrCreateVReg(*CI.getOperand(0)),
25892589
getOrCreateVReg(*CI.getOperand(1)));
25902590
return true;
2591+
case Intrinsic::vector_extract:
2592+
return translateExtractVector(CI, MIRBuilder);
2593+
case Intrinsic::vector_insert:
2594+
return translateInsertVector(CI, MIRBuilder);
25912595
case Intrinsic::prefetch: {
25922596
Value *Addr = CI.getOperand(0);
25932597
unsigned RW = cast<ConstantInt>(CI.getOperand(1))->getZExtValue();
@@ -3163,6 +3167,57 @@ bool IRTranslator::translateInsertElement(const User &U,
31633167
return true;
31643168
}
31653169

3170+
bool IRTranslator::translateInsertVector(const User &U,
3171+
MachineIRBuilder &MIRBuilder) {
3172+
Register Dst = getOrCreateVReg(U);
3173+
Register Vec = getOrCreateVReg(*U.getOperand(0));
3174+
Register Elt = getOrCreateVReg(*U.getOperand(1));
3175+
3176+
ConstantInt *CI = cast<ConstantInt>(U.getOperand(2));
3177+
unsigned PreferredVecIdxWidth = TLI->getVectorIdxTy(*DL).getSizeInBits();
3178+
3179+
// Resize Index to preferred index width.
3180+
if (CI->getBitWidth() != PreferredVecIdxWidth) {
3181+
APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
3182+
CI = ConstantInt::get(CI->getContext(), NewIdx);
3183+
}
3184+
3185+
// If it is a <1 x Ty> vector, we have to use other means.
3186+
if (auto *ResultType = dyn_cast<FixedVectorType>(U.getOperand(1)->getType());
3187+
ResultType && ResultType->getNumElements() == 1) {
3188+
if (auto *InputType = dyn_cast<FixedVectorType>(U.getOperand(0)->getType());
3189+
InputType && InputType->getNumElements() == 1) {
3190+
// We are inserting an illegal fixed vector into an illegal
3191+
// fixed vector, use the scalar as it is not a legal vector type
3192+
// in LLT.
3193+
return translateCopy(U, *U.getOperand(0), MIRBuilder);
3194+
}
3195+
if (isa<FixedVectorType>(U.getOperand(0)->getType())) {
3196+
// We are inserting an illegal fixed vector into a legal fixed
3197+
// vector, use the scalar as it is not a legal vector type in
3198+
// LLT.
3199+
Register Idx = getOrCreateVReg(*CI);
3200+
MIRBuilder.buildInsertVectorElement(Dst, Vec, Elt, Idx);
3201+
return true;
3202+
}
3203+
if (isa<ScalableVectorType>(U.getOperand(0)->getType())) {
3204+
// We are inserting an illegal fixed vector into a scalable
3205+
// vector, use a scalar element insert.
3206+
LLT VecIdxTy = LLT::scalar(PreferredVecIdxWidth);
3207+
Register Idx = getOrCreateVReg(*CI);
3208+
auto ScaledIndex = MIRBuilder.buildMul(
3209+
VecIdxTy, MIRBuilder.buildVScale(VecIdxTy, 1), Idx);
3210+
MIRBuilder.buildInsertVectorElement(Dst, Vec, Elt, ScaledIndex);
3211+
return true;
3212+
}
3213+
}
3214+
3215+
MIRBuilder.buildInsertSubvector(
3216+
getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)),
3217+
getOrCreateVReg(*U.getOperand(1)), CI->getZExtValue());
3218+
return true;
3219+
}
3220+
31663221
bool IRTranslator::translateExtractElement(const User &U,
31673222
MachineIRBuilder &MIRBuilder) {
31683223
// If it is a <1 x Ty> vector, use the scalar as it is
@@ -3191,6 +3246,54 @@ bool IRTranslator::translateExtractElement(const User &U,
31913246
return true;
31923247
}
31933248

3249+
bool IRTranslator::translateExtractVector(const User &U,
3250+
MachineIRBuilder &MIRBuilder) {
3251+
Register Res = getOrCreateVReg(U);
3252+
Register Vec = getOrCreateVReg(*U.getOperand(0));
3253+
ConstantInt *CI = cast<ConstantInt>(U.getOperand(1));
3254+
unsigned PreferredVecIdxWidth = TLI->getVectorIdxTy(*DL).getSizeInBits();
3255+
3256+
// Resize Index to preferred index width.
3257+
if (CI->getBitWidth() != PreferredVecIdxWidth) {
3258+
APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
3259+
CI = ConstantInt::get(CI->getContext(), NewIdx);
3260+
}
3261+
3262+
// If it is a <1 x Ty> vector, we have to use other means.
3263+
if (auto *ResultType = dyn_cast<FixedVectorType>(U.getType());
3264+
ResultType && ResultType->getNumElements() == 1) {
3265+
if (auto *InputType = dyn_cast<FixedVectorType>(U.getOperand(0)->getType());
3266+
InputType && InputType->getNumElements() == 1) {
3267+
// We are extracting an illegal fixed vector from an illegal fixed vector,
3268+
// use the scalar as it is not a legal vector type in LLT.
3269+
return translateCopy(U, *U.getOperand(0), MIRBuilder);
3270+
}
3271+
if (isa<FixedVectorType>(U.getOperand(0)->getType())) {
3272+
// We are extracting an illegal fixed vector from a legal fixed
3273+
// vector, use the scalar as it is not a legal vector type in
3274+
// LLT.
3275+
Register Idx = getOrCreateVReg(*CI);
3276+
MIRBuilder.buildExtractVectorElement(Res, Vec, Idx);
3277+
return true;
3278+
}
3279+
if (isa<ScalableVectorType>(U.getOperand(0)->getType())) {
3280+
// We are extracting an illegal fixed vector from a scalable
3281+
// vector, use a scalar element extract.
3282+
LLT VecIdxTy = LLT::scalar(PreferredVecIdxWidth);
3283+
Register Idx = getOrCreateVReg(*CI);
3284+
auto ScaledIndex = MIRBuilder.buildMul(
3285+
VecIdxTy, MIRBuilder.buildVScale(VecIdxTy, 1), Idx);
3286+
MIRBuilder.buildExtractVectorElement(Res, Vec, ScaledIndex);
3287+
return true;
3288+
}
3289+
}
3290+
3291+
MIRBuilder.buildExtractSubvector(getOrCreateVReg(U),
3292+
getOrCreateVReg(*U.getOperand(0)),
3293+
CI->getZExtValue());
3294+
return true;
3295+
}
3296+
31943297
bool IRTranslator::translateShuffleVector(const User &U,
31953298
MachineIRBuilder &MIRBuilder) {
31963299
// A ShuffleVector that operates on scalable vectors is a splat vector where

0 commit comments

Comments
 (0)