diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp @@ -845,7 +845,7 @@ } break; } - case TargetOpcode::G_BUILD_VECTOR: + case TargetOpcode::G_BUILD_VECTOR: { // If the first source operand belongs to a FPR register bank, then make // sure that we preserve that. if (OpRegBankIdx[1] != PMI_FirstGPR) @@ -877,6 +877,30 @@ } break; } + case TargetOpcode::G_VECREDUCE_FADD: + case TargetOpcode::G_VECREDUCE_FMUL: + case TargetOpcode::G_VECREDUCE_FMAX: + case TargetOpcode::G_VECREDUCE_FMIN: + case TargetOpcode::G_VECREDUCE_ADD: + case TargetOpcode::G_VECREDUCE_MUL: + case TargetOpcode::G_VECREDUCE_AND: + case TargetOpcode::G_VECREDUCE_OR: + case TargetOpcode::G_VECREDUCE_XOR: + case TargetOpcode::G_VECREDUCE_SMAX: + case TargetOpcode::G_VECREDUCE_SMIN: + case TargetOpcode::G_VECREDUCE_UMAX: + case TargetOpcode::G_VECREDUCE_UMIN: + // Reductions produce a scalar value from a vector, the scalar should be on + // FPR bank. + OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR}; + break; + case TargetOpcode::G_VECREDUCE_SEQ_FADD: + case TargetOpcode::G_VECREDUCE_SEQ_FMUL: + // These reductions also take a scalar accumulator input. + // Assign them FPR for now. + OpRegBankIdx = {PMI_FirstFPR, PMI_FirstFPR, PMI_FirstFPR}; + break; + } // Finally construct the computed mapping. SmallVector OpdsMapping(NumOperands); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reductions.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reductions.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-reductions.mir @@ -0,0 +1,43 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -mtriple=aarch64-unknown-unknown -verify-machineinstrs -run-pass=regbankselect -global-isel-abort=1 %s -o - | FileCheck %s + +--- +name: fadd_v2s32 +legalized: true +tracksRegLiveness: true +body: | + bb.1: + liveins: $d0 + + ; CHECK-LABEL: name: fadd_v2s32 + ; CHECK: liveins: $d0 + ; CHECK: [[COPY:%[0-9]+]]:fpr(<2 x s32>) = COPY $d0 + ; CHECK: [[VECREDUCE_FADD:%[0-9]+]]:fpr(s32) = G_VECREDUCE_FADD [[COPY]](<2 x s32>) + ; CHECK: $w0 = COPY [[VECREDUCE_FADD]](s32) + ; CHECK: RET_ReallyLR implicit $w0 + %0:_(<2 x s32>) = COPY $d0 + %1:_(s32) = G_VECREDUCE_FADD %0(<2 x s32>) + $w0 = COPY %1(s32) + RET_ReallyLR implicit $w0 + +... +--- +name: add_v4s32 +legalized: true +tracksRegLiveness: true +body: | + bb.1: + liveins: $q0 + + ; CHECK-LABEL: name: add_v4s32 + ; CHECK: liveins: $q0 + ; CHECK: [[COPY:%[0-9]+]]:fpr(<4 x s32>) = COPY $q0 + ; CHECK: [[VECREDUCE_ADD:%[0-9]+]]:fpr(s32) = G_VECREDUCE_ADD [[COPY]](<4 x s32>) + ; CHECK: $w0 = COPY [[VECREDUCE_ADD]](s32) + ; CHECK: RET_ReallyLR implicit $w0 + %0:_(<4 x s32>) = COPY $q0 + %1:_(s32) = G_VECREDUCE_ADD %0(<4 x s32>) + $w0 = COPY %1(s32) + RET_ReallyLR implicit $w0 + +...