[llvm] [AArch64][GlobalISel] Select integer vector reductions into GPRs (PR #212976)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 30 02:47:44 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: Cullen Rhodes (c-rhodes)
<details>
<summary>Changes</summary>
Prototyping a new minimal type-based approach to RegBankSelect (#<!-- -->199040) for compile-time purposes exposed various gaps in instruction selection when not using the existing RegBankSelect pass. These manifested as new fallbacks when compiling CTMark and the IR dataset from [1].
Imported patterns require an FPR result. This patch teaches instruction selection to handle vector reductions with GPR results by using a temporary FPR and inserting a cross-bank copy.
Assisted-by: codex
[1] https://davemgreen.github.io/gisel.html
---
Full diff: https://github.com/llvm/llvm-project/pull/212976.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+22)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir (+28)
``````````diff
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 0c2f3f97ec07d..1fcef85d5c9f6 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2187,6 +2187,28 @@ bool AArch64InstructionSelector::preISelLower(MachineInstr &I) {
MRI.setType(DstReg, LLT::scalar(64));
return true;
}
+ case TargetOpcode::G_VECREDUCE_ADD:
+ case TargetOpcode::G_VECREDUCE_SMAX:
+ case TargetOpcode::G_VECREDUCE_SMIN:
+ case TargetOpcode::G_VECREDUCE_UMAX:
+ case TargetOpcode::G_VECREDUCE_UMIN: {
+ // Imported patterns require an FPR result. For a GPR, use a temporary FPR
+ // and insert a cross-bank copy.
+ Register DstReg = I.getOperand(0).getReg();
+ if (RBI.getRegBank(DstReg, MRI, TRI)->getID() != AArch64::GPRRegBankID)
+ return false;
+
+ LLT DstTy = MRI.getType(DstReg);
+ Register FPRDst = MRI.createGenericVirtualRegister(DstTy);
+ MRI.setRegBank(FPRDst, RBI.getRegBank(AArch64::FPRRegBankID));
+ I.getOperand(0).setReg(FPRDst);
+
+ MIB.setInsertPt(MBB, std::next(I.getIterator()));
+ auto Copy = MIB.buildCopy(DstReg, FPRDst);
+ selectCopy(*Copy, TII, MRI, TRI, RBI);
+ MIB.setInstr(I);
+ return true;
+ }
case AArch64::G_DUP: {
// Convert the type from p0 to s64 to help selection.
LLT DstTy = MRI.getType(I.getOperand(0).getReg());
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir
index e48664da8e97a..c216105197e58 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-reduce-add.mir
@@ -88,6 +88,34 @@ body: |
$w0 = COPY %2(i32)
RET_ReallyLR implicit $w0
+...
+---
+name: add_S_gpr_result
+alignment: 4
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+liveins:
+ - { reg: '$x0' }
+body: |
+ bb.1:
+ liveins: $x0
+
+ ; CHECK-LABEL: name: add_S_gpr_result
+ ; CHECK: liveins: $x0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64sp = COPY $x0
+ ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[COPY]], 0 :: (load (<4 x s32>))
+ ; CHECK-NEXT: [[ADDVv4i32v:%[0-9]+]]:fpr32 = ADDVv4i32v [[LDRQui]]
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[ADDVv4i32v]]
+ ; CHECK-NEXT: $w0 = COPY [[COPY1]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:gpr(p0) = COPY $x0
+ %1:fpr(<4 x i32>) = G_LOAD %0(p0) :: (load (<4 x s32>))
+ %2:gpr(i32) = G_VECREDUCE_ADD %1(<4 x i32>)
+ $w0 = COPY %2(i32)
+ RET_ReallyLR implicit $w0
+
...
---
name: add_S_v2i32
``````````
</details>
https://github.com/llvm/llvm-project/pull/212976
More information about the llvm-commits
mailing list