Index: lib/Target/AMDGPU/AMDGPUGISel.td =================================================================== --- /dev/null +++ lib/Target/AMDGPU/AMDGPUGISel.td @@ -0,0 +1,34 @@ +//===-- AMDGPUGIsel.td - AMDGPU GlobalISel Patterns---------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This files contains patterns that should only be used by GlobalISel. For +// example patterns for V_* instructions that have S_* equivalents. +// SelectionDAG does not support selecting V_* instructions. +//===----------------------------------------------------------------------===// + +include "AMDGPU.td" + +class GISelVop2Pat < + SDPatternOperator node, + Instruction inst, + ValueType dst_type, RegisterClass rc0, RegisterClass rc1 = rc0, + ValueType src0_type = dst_type, ValueType src1_type = dst_type> : GCNPat < + + (dst_type (node (src0_type rc0:$src0), (src1_type rc1:$src1))), + (inst src0_type:$src0, src1_type:$src1) +>; + +multiclass GISelVOP2DefaultPat < + SDPatternOperator node, Instruction inst, ValueType type> { + + def : GISelVop2Pat ; + + def : GISelVop2Pat ; +} + +defm : GISelVOP2DefaultPat ; Index: lib/Target/AMDGPU/AMDGPUInstructionSelector.h =================================================================== --- lib/Target/AMDGPU/AMDGPUInstructionSelector.h +++ lib/Target/AMDGPU/AMDGPUInstructionSelector.h @@ -19,10 +19,17 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +namespace { +#define GET_GLOBALISEL_PREDICATE_BITSET +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATE_BITSET +} + namespace llvm { class AMDGPUInstrInfo; class AMDGPURegisterBankInfo; +class AMDGPUSubtarget; class MachineInstr; class MachineOperand; class MachineRegisterInfo; @@ -33,9 +40,11 @@ class AMDGPUInstructionSelector : public InstructionSelector { public: AMDGPUInstructionSelector(const SISubtarget &STI, - const AMDGPURegisterBankInfo &RBI); + const AMDGPURegisterBankInfo &RBI, + const AMDGPUTargetMachine &TM); bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override; + static const char *getName(); private: struct GEPInfo { @@ -46,6 +55,9 @@ GEPInfo(const MachineInstr &GEP) : GEP(GEP), Imm(0) { } }; + /// tblgen-erated 'select' implementation. + bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; + MachineOperand getSubOperand64(MachineOperand &MO, unsigned SubIdx) const; bool selectG_CONSTANT(MachineInstr &I) const; bool selectG_ADD(MachineInstr &I) const; @@ -56,10 +68,22 @@ bool selectSMRD(MachineInstr &I, ArrayRef AddrInfo) const; bool selectG_LOAD(MachineInstr &I) const; bool selectG_STORE(MachineInstr &I) const; + bool selectImpl(MachineInstr &I) const; const SIInstrInfo &TII; const SIRegisterInfo &TRI; const AMDGPURegisterBankInfo &RBI; + const AMDGPUTargetMachine &TM; + const SISubtarget &STI; + bool EnableLateStructurizeCFG; +#define GET_GLOBALISEL_PREDICATES_DECL +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATES_DECL + +#define GET_GLOBALISEL_TEMPORARIES_DECL +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_DECL + protected: AMDGPUAS AMDGPUASI; }; Index: lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp +++ lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp @@ -17,6 +17,9 @@ #include "AMDGPURegisterBankInfo.h" #include "AMDGPURegisterInfo.h" #include "AMDGPUSubtarget.h" +#include "AMDGPUTargetMachine.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelector.h" +#include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" @@ -31,10 +34,28 @@ using namespace llvm; +#define GET_GLOBALISEL_IMPL +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_IMPL + AMDGPUInstructionSelector::AMDGPUInstructionSelector( - const SISubtarget &STI, const AMDGPURegisterBankInfo &RBI) + const SISubtarget &STI, const AMDGPURegisterBankInfo &RBI, + const AMDGPUTargetMachine &TM) : InstructionSelector(), TII(*STI.getInstrInfo()), - TRI(*STI.getRegisterInfo()), RBI(RBI), AMDGPUASI(STI.getAMDGPUAS()) {} + TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM), + STI(STI), + EnableLateStructurizeCFG(AMDGPUTargetMachine::EnableLateStructurizeCFG), +#define GET_GLOBALISEL_PREDICATES_INIT +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_PREDICATES_INIT +#define GET_GLOBALISEL_TEMPORARIES_INIT +#include "AMDGPUGenGlobalISel.inc" +#undef GET_GLOBALISEL_TEMPORARIES_INIT + ,AMDGPUASI(STI.getAMDGPUAS()) +{ +} + +const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; } MachineOperand AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO, @@ -416,6 +437,8 @@ switch (I.getOpcode()) { default: break; + case TargetOpcode::G_OR: + return selectImpl(I, CoverageInfo); case TargetOpcode::G_ADD: return selectG_ADD(I); case TargetOpcode::G_CONSTANT: Index: lib/Target/AMDGPU/AMDGPUSubtarget.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUSubtarget.cpp +++ lib/Target/AMDGPU/AMDGPUSubtarget.cpp @@ -378,7 +378,7 @@ RegBankInfo.reset(new AMDGPURegisterBankInfo(*getRegisterInfo())); InstSelector.reset(new AMDGPUInstructionSelector( - *this, *static_cast(RegBankInfo.get()))); + *this, *static_cast(RegBankInfo.get()), TM)); } void SISubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy, Index: lib/Target/AMDGPU/CMakeLists.txt =================================================================== --- lib/Target/AMDGPU/CMakeLists.txt +++ lib/Target/AMDGPU/CMakeLists.txt @@ -15,6 +15,9 @@ tablegen(LLVM AMDGPUGenSearchableTables.inc -gen-searchable-tables) tablegen(LLVM AMDGPUGenSubtargetInfo.inc -gen-subtarget) +set(LLVM_TARGET_DEFINITIONS AMDGPUGISel.td) +tablegen(LLVM AMDGPUGenGlobalISel.inc -gen-global-isel) + add_public_tablegen_target(AMDGPUCommonTableGen) add_llvm_target(AMDGPUCodeGen Index: lib/Target/AMDGPU/SIRegisterInfo.h =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.h +++ lib/Target/AMDGPU/SIRegisterInfo.h @@ -227,6 +227,9 @@ // Not a callee saved register. return AMDGPU::SGPR30_SGPR31; } + const TargetRegisterClass * + getConstrainedRegClassForOperand(const MachineOperand &MO, + const MachineRegisterInfo &MRI) const override; private: void buildSpillLoadStore(MachineBasicBlock::iterator MI, Index: lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.cpp +++ lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "SIRegisterInfo.h" +#include "AMDGPURegisterBankInfo.h" #include "AMDGPUSubtarget.h" #include "SIInstrInfo.h" #include "SIMachineFunctionInfo.h" @@ -1558,3 +1559,23 @@ return Empty; return AMDGPURegisterInfo::getRegUnitPressureSets(RegUnit); } + +const TargetRegisterClass * +SIRegisterInfo::getConstrainedRegClassForOperand(const MachineOperand &MO, + const MachineRegisterInfo &MRI) const { + unsigned Size = getRegSizeInBits(MO.getReg(), MRI); + const RegisterBank *RB = MRI.getRegBankOrNull(MO.getReg()); + if (!RB) + return nullptr; + + switch (Size) { + case 32: + return RB->getID() == AMDGPU::VGPRRegBankID ? &AMDGPU::VGPR_32RegClass : + &AMDGPU::SReg_32RegClass; + case 64: + return RB->getID() == AMDGPU::VGPRRegBankID ? &AMDGPU::VReg_64RegClass : + &AMDGPU::SReg_64RegClass; + default: + llvm_unreachable("not implemented"); + } +} Index: test/CodeGen/AMDGPU/GlobalISel/inst-select-or.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/inst-select-or.mir @@ -0,0 +1,39 @@ +# 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 @or(i32 addrspace(1)* %global0) {ret void} +... +--- + +name: or +legalized: true +regBankSelected: true + +# GCN-LABEL: name: or +body: | + bb.0: + liveins: $sgpr0, $sgpr1, $vgpr0, $vgpr3_vgpr4 + %0:sgpr(s32) = COPY $sgpr0 + %1:sgpr(s32) = COPY $sgpr1 + %2:vgpr(s32) = COPY $vgpr0 + %3:vgpr(s64) = COPY $vgpr3_vgpr4 + + ; or ss + ; GCN: [[SGPR:%[0-9]+]]:sreg_32 = S_OR_B32 %0, %1 + %4:sgpr(s32) = G_OR %0, %1 + + ; or vs + ; GCN: V_OR_B32_e64 [[SGPR]], %2 + %5:vgpr(s32) = G_OR %2, %4 + + ; or sv + ; GCN: V_OR_B32_e64 [[SGPR]], %5 + %6:vgpr(s32) = G_OR %4, %5 + + ; or vv + ; GCN: V_OR_B32_e64 %6, %2 + %7:vgpr(s32) = G_OR %6, %2 + + G_STORE %7, %3 :: (store 4 into %ir.global0) +... +---