Index: llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -765,8 +765,14 @@ // We're doing a cross-bank copy into a smaller register. We need a // subregister copy. First, get a register class that's on the same bank // as the destination, but the same size as the source. - const TargetRegisterClass *SubregRC = - getMinClassForRegBank(DstRegBank, SrcSize, true); + // + // Also, note that if the source can be any GPR register, the destination + // can be any GPR register. If the source is in a smaller class, then we + // should respect that in the subregister's class as well. + bool SrcIsAllRegClass = SrcRC == &AArch64::GPR32allRegClass || + SrcRC == &AArch64::GPR64allRegClass; + const TargetRegisterClass *SubregRC = getMinClassForRegBank( + DstRegBank, SrcSize, SrcIsAllRegClass); assert(SubregRC && "Didn't get a register class for subreg?"); // Get the appropriate subregister for the destination. Index: llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-shift-tbz-tbnz.mir =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-shift-tbz-tbnz.mir +++ llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-shift-tbz-tbnz.mir @@ -122,9 +122,8 @@ ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) ; CHECK: %copy:gpr64 = COPY $x0 ; CHECK: %shl:gpr64 = UBFMXri %copy, 62, 61 - ; CHECK: [[COPY:%[0-9]+]]:gpr64all = COPY %shl - ; CHECK: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]].sub_32 - ; CHECK: TBNZW [[COPY1]], 3, %bb.1 + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY %shl.sub_32 + ; CHECK: TBNZW [[COPY]], 3, %bb.1 ; CHECK: B %bb.0 ; CHECK: bb.1: ; CHECK: %second_use:gpr64sp = ORRXri %shl, 8000