Index: lib/Target/AMDGPU/AMDGPUInstructionSelector.h =================================================================== --- lib/Target/AMDGPU/AMDGPUInstructionSelector.h +++ lib/Target/AMDGPU/AMDGPUInstructionSelector.h @@ -47,6 +47,7 @@ }; MachineOperand getSubOperand64(MachineOperand &MO, unsigned SubIdx) const; + bool selectCOPY(MachineInstr &I) const; bool selectG_CONSTANT(MachineInstr &I) const; bool selectG_ADD(MachineInstr &I) const; bool selectG_GEP(MachineInstr &I) const; Index: lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -36,6 +36,31 @@ : InstructionSelector(), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), AMDGPUASI(STI.getAMDGPUAS()) {} +bool AMDGPUInstructionSelector::selectCOPY(MachineInstr &I) const { + MachineBasicBlock *BB = I.getParent(); + MachineFunction *MF = BB->getParent(); + MachineRegisterInfo &MRI = MF->getRegInfo(); + I.setDesc(TII.get(TargetOpcode::COPY)); + unsigned Size = RBI.getSizeInBits(I.getOperand(0).getReg(), MRI, TRI); + for (const MachineOperand &MO : I.operands()) { + if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) + continue; + const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI); + if (!OpBank) + continue; + + const TargetRegisterClass *RC; + if (OpBank->getID() == AMDGPU::SGPRRegBankID) { + RC = Size == 32 ? &AMDGPU::SGPR_32RegClass : &AMDGPU::SReg_64RegClass; + } else { + assert(OpBank->getID() == AMDGPU::VGPRRegBankID); + RC = Size == 32 ? &AMDGPU::VGPR_32RegClass : &AMDGPU::VReg_64RegClass; + } + RBI.constrainGenericRegister(MO.getReg(), *RC, MRI); + } + return true; +} + MachineOperand AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO, unsigned SubIdx) const { @@ -519,6 +544,8 @@ return selectSimple(I); case TargetOpcode::G_ADD: return selectG_ADD(I); + case TargetOpcode::G_BITCAST: + return selectCOPY(I); case TargetOpcode::G_CONSTANT: return selectG_CONSTANT(I); case TargetOpcode::G_GEP: Index: test/CodeGen/AMDGPU/GlobalISel/inst-select-bitcast.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/inst-select-bitcast.mir @@ -0,0 +1,26 @@ +# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN + +--- | + define amdgpu_kernel void @bitcast(i32 addrspace(1)* %global0) {ret void} +... +--- + +name: bitcast +legalized: true +regBankSelected: true + +# GCN-LABEL: name: bitcast +# GCN: [[A:%[0-9]+]]:vgpr_32 = COPY $vgpr0 +# GCN: [[B:%[0-9]+]]:vreg_64 = COPY $vgpr3_vgpr4 +# GCN: FLAT_STORE_DWORD [[B]], [[A]] + +body: | + bb.0: + liveins: $sgpr0, $vgpr3_vgpr4 + %0:vgpr(s32) = COPY $vgpr0 + %1:vgpr(s64) = COPY $vgpr3_vgpr4 + %2:vgpr(<2 x s16>) = G_BITCAST %0 + %3:vgpr(s32) = G_BITCAST %2 + G_STORE %3, %1 :: (store 4 into %ir.global0) +... +---