summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2020-01-01 15:23:58 -0500
committerMatt Arsenault <arsenm2@gmail.com>2020-01-06 11:10:13 -0500
commitf1c85ecdfcc3b1c3500ab91ac7c1fb9d2cd8aa78 (patch)
tree05130c652fbc142fa0e5a7739763e4f26af532d8 /llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
parentd67c4cc2eb4ddc450c886598b934c111e721ab0c (diff)
downloadbcm5719-llvm-f1c85ecdfcc3b1c3500ab91ac7c1fb9d2cd8aa78.tar.gz
bcm5719-llvm-f1c85ecdfcc3b1c3500ab91ac7c1fb9d2cd8aa78.zip
AMDGPU/GlobalISel: Select more G_EXTRACTs correctly
This assumed a 32-bit extract size, which would produce invalid copies with 64-bit extracts. Handle the easy case. Ideally we would have a way to get the proper subreg index for any 32-bit offset, but there should probably be a tablegenerated way of getting the subreg index for any size and offset.
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp24
1 files changed, 19 insertions, 5 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
index d1b36ca6df5..f553ec92c3f 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp
@@ -441,15 +441,29 @@ bool AMDGPUInstructionSelector::selectG_UADDO_USUBO(MachineInstr &I) const {
bool AMDGPUInstructionSelector::selectG_EXTRACT(MachineInstr &I) const {
MachineBasicBlock *BB = I.getParent();
+ Register DstReg = I.getOperand(0).getReg();
+ Register SrcReg = I.getOperand(1).getReg();
+ LLT DstTy = MRI->getType(DstReg);
+ LLT SrcTy = MRI->getType(SrcReg);
+ const unsigned SrcSize = SrcTy.getSizeInBits();
+ const unsigned DstSize = DstTy.getSizeInBits();
+
+ // TODO: Should handle any multiple of 32 offset.
unsigned Offset = I.getOperand(2).getImm();
- if (Offset % 32 != 0)
+ if (Offset % DstSize != 0)
return false;
- unsigned SubReg = TRI.getSubRegFromChannel(Offset / 32);
+ const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, *MRI, TRI);
+ const TargetRegisterClass *SrcRC =
+ TRI.getRegClassForSizeOnBank(SrcSize, *SrcBank, *MRI);
+ if (!SrcRC)
+ return false;
+
+ ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(SrcRC, DstSize / 8);
+
const DebugLoc &DL = I.getDebugLoc();
- MachineInstr *Copy = BuildMI(*BB, &I, DL, TII.get(TargetOpcode::COPY),
- I.getOperand(0).getReg())
- .addReg(I.getOperand(1).getReg(), 0, SubReg);
+ MachineInstr *Copy = BuildMI(*BB, &I, DL, TII.get(TargetOpcode::COPY), DstReg)
+ .addReg(SrcReg, 0, SubRegs[Offset / DstSize]);
for (const MachineOperand &MO : Copy->operands()) {
const TargetRegisterClass *RC =
OpenPOWER on IntegriCloud