[llvm] [AArch64][GlobalISel] Select narrow G_INSERT_VECTOR_ELT GPR operands (PR #203568)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 12 08:35:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
RegBankSelect currently extends narrow i8/i16 G_INSERT_VECTOR_ELT GPR operands to 32-bits. Move this widening to pre-isel lowering. This will help enable a simple fast pure type-based RBS alternative.
Assisted-by: codex
---
Full diff: https://github.com/llvm/llvm-project/pull/203568.diff
4 Files Affected:
- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+24-11)
- (modified) llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp (-20)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/regbank-insert-vector-elt.mir (+28)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir (+30)
``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index cf650fd5c4e72..6b244f784c7c0 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2200,19 +2200,32 @@ bool AArch64InstructionSelector::preISelLower(MachineInstr &I) {
return true;
}
case AArch64::G_INSERT_VECTOR_ELT: {
- // Convert the type from p0 to s64 to help selection.
LLT DstTy = MRI.getType(I.getOperand(0).getReg());
LLT SrcVecTy = MRI.getType(I.getOperand(1).getReg());
- if (!SrcVecTy.isPointerVector())
- return false;
- auto NewSrc = MIB.buildCopy(LLT::scalar(64), I.getOperand(2).getReg());
- MRI.setType(I.getOperand(1).getReg(),
- DstTy.changeElementType(LLT::scalar(64)));
- MRI.setType(I.getOperand(0).getReg(),
- DstTy.changeElementType(LLT::scalar(64)));
- MRI.setRegClass(NewSrc.getReg(0), &AArch64::GPR64RegClass);
- I.getOperand(2).setReg(NewSrc.getReg(0));
- return true;
+ if (SrcVecTy.isPointerVector()) {
+ // Convert the type from p0 to s64 to help selection.
+ auto NewSrc = MIB.buildCopy(LLT::scalar(64), I.getOperand(2).getReg());
+ MRI.setType(I.getOperand(1).getReg(),
+ DstTy.changeElementType(LLT::scalar(64)));
+ MRI.setType(I.getOperand(0).getReg(),
+ DstTy.changeElementType(LLT::scalar(64)));
+ MRI.setRegClass(NewSrc.getReg(0), &AArch64::GPR64RegClass);
+ I.getOperand(2).setReg(NewSrc.getReg(0));
+ return true;
+ }
+
+ Register EltReg = I.getOperand(2).getReg();
+ LLT EltTy = MRI.getType(EltReg);
+ if (EltTy.isScalar() &&
+ (EltTy.getSizeInBits() == 8 || EltTy.getSizeInBits() == 16) &&
+ RBI.getRegBank(EltReg, MRI, TRI)->getID() == AArch64::GPRRegBankID) {
+ // Convert the type from s8/s16 to s32 to help selection.
+ auto NewElt = MIB.buildCopy(LLT::scalar(32), EltReg);
+ MRI.setRegClass(NewElt.getReg(0), &AArch64::GPR32RegClass);
+ I.getOperand(2).setReg(NewElt.getReg(0));
+ return true;
+ }
+ return false;
}
case TargetOpcode::G_UITOFP:
case TargetOpcode::G_SITOFP: {
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 4767493e107b4..90b5992acf598 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -520,19 +520,6 @@ void AArch64RegisterBankInfo::applyMappingImpl(
OpdMapper.getInstrMapping().getID() <= 4) &&
"Don't know how to handle that ID");
return applyDefaultMapping(OpdMapper);
- case TargetOpcode::G_INSERT_VECTOR_ELT: {
- if (foldTruncOfI32Constant(MI, 2, MRI, *this))
- return applyDefaultMapping(OpdMapper);
-
- // Extend smaller gpr operands to 32 bit.
- Builder.setInsertPt(*MI.getParent(), MI.getIterator());
- LLT OperandType = MRI.getType(MI.getOperand(2).getReg());
- auto Ext = Builder.buildAnyExt(OperandType.changeElementSize(32),
- MI.getOperand(2).getReg());
- MRI.setRegBank(Ext.getReg(0), getRegBank(AArch64::GPRRegBankID));
- MI.getOperand(2).setReg(Ext.getReg(0));
- return applyDefaultMapping(OpdMapper);
- }
case AArch64::G_DUP: {
if (foldTruncOfI32Constant(MI, 1, MRI, *this))
return applyDefaultMapping(OpdMapper);
@@ -1330,13 +1317,6 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
if (getRegBank(MI.getOperand(2).getReg(), MRI, TRI) == &AArch64::FPRRegBank)
OpRegBankIdx[2] = PMI_FirstFPR;
else {
- // If the type is i8/i16, and the regbank will be GPR, then we change the
- // type to i32 in applyMappingImpl.
- LLT Ty = MRI.getType(MI.getOperand(2).getReg());
- if (Ty.getSizeInBits() == 8 || Ty.getSizeInBits() == 16) {
- // Calls applyMappingImpl()
- MappingID = CustomMappingID;
- }
OpRegBankIdx[2] = PMI_FirstGPR;
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-insert-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-insert-vector-elt.mir
index b0620a8f81dce..f7e442dd77ce1 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-insert-vector-elt.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-insert-vector-elt.mir
@@ -61,6 +61,34 @@ body: |
$q0 = COPY %2(<4 x s32>)
RET_ReallyLR implicit $q0
+...
+---
+name: v8s8_gpr_narrow
+alignment: 4
+legalized: true
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $d0, $w0
+
+ ; CHECK-LABEL: name: v8s8_gpr_narrow
+ ; CHECK: liveins: $d0, $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY $w0
+ ; CHECK-NEXT: %trunc:gpr(s8) = G_TRUNC [[COPY]](s32)
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(<8 x s8>) = COPY $d0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:gpr(s64) = G_CONSTANT i64 1
+ ; CHECK-NEXT: [[IVEC:%[0-9]+]]:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT [[COPY1]], %trunc(s8), [[C]](s64)
+ ; CHECK-NEXT: $d0 = COPY [[IVEC]](<8 x s8>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %0:_(s32) = COPY $w0
+ %trunc:_(s8) = G_TRUNC %0
+ %1:_(<8 x s8>) = COPY $d0
+ %3:_(s64) = G_CONSTANT i64 1
+ %2:_(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %trunc(s8), %3(s64)
+ $d0 = COPY %2(<8 x s8>)
+ RET_ReallyLR implicit $d0
+
...
---
name: v2s64_fpr
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir
index ed665271472cb..e761c3a808980 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-insert-vector-elt.mir
@@ -27,6 +27,36 @@ body: |
$q0 = COPY %2(<16 x s8>)
RET_ReallyLR implicit $q0
+...
+---
+name: v8s8_gpr_narrow
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+body: |
+ bb.0:
+ liveins: $d0, $w0
+
+ ; CHECK-LABEL: name: v8s8_gpr_narrow
+ ; CHECK: liveins: $d0, $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], [[COPY1]], %subreg.dsub
+ ; CHECK-NEXT: [[INSvi8gpr:%[0-9]+]]:fpr128 = INSvi8gpr [[INSERT_SUBREG]], 1, [[COPY]]
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[INSvi8gpr]].dsub
+ ; CHECK-NEXT: $d0 = COPY [[COPY2]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %0:gpr(s32) = COPY $w0
+ %trunc:gpr(s8) = G_TRUNC %0
+ %1:fpr(<8 x s8>) = COPY $d0
+ %3:gpr(s64) = G_CONSTANT i64 1
+ %2:fpr(<8 x s8>) = G_INSERT_VECTOR_ELT %1, %trunc(s8), %3(s64)
+ $d0 = COPY %2(<8 x s8>)
+ RET_ReallyLR implicit $d0
+
...
---
name: v8s8_gpr
``````````
</details>
https://github.com/llvm/llvm-project/pull/203568
More information about the llvm-commits
mailing list