<div dir="ltr">The test "<span style="font-size:12.800000190734863px">CodeGen/AMDGPU/GlobalISel</span><wbr style="font-size:12.800000190734863px"><span style="font-size:12.800000190734863px">/inst-select-load-smrd.mir"</span> also fails on some our GreenDragon bots as well, e.g. the Clang Stage 1: configure, RA started failing at <a href="http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_check/26790/">http://lab.llvm.org:8080/green/job/clang-stage1-configure-RA_check/26790/</a> .<div><br></div><div>Alex</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 31 January 2017 at 07:53, Mikael Holmén via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Tom,<br>
<br>
The new test<br>
<br>
test/CodeGen/AMDGPU/GlobalISel<wbr>/inst-select-load-smrd.mir<br>
<br>
in this commit fails for me:<br>
<br>
/data/repo/llvm-patch/test/Cod<wbr>eGen/AMDGPU/GlobalISel/inst-<wbr>select-load-smrd.mir:57:9: error: expected string not found in input<br>
# SIVI: [[ADD_PTR_LO:%[0-9]+]] = S_ADD_U32 [[PTR_LO]], [[K_SUB0]]<br>
        ^<br>
<stdin>:217:2: note: scanning from here<br>
 %48 = COPY %19.sub0<br>
 ^<br>
<stdin>:217:2: note: with variable "PTR_LO" equal to "%47"<br>
 %48 = COPY %19.sub0<br>
 ^<br>
<stdin>:217:2: note: with variable "K_SUB0" equal to "%56"<br>
 %48 = COPY %19.sub0<br>
 ^<br>
<stdin>:241:2: note: possible intended match here<br>
 %29 = S_ADDC_U32 %32, %33, implicit-def %scc, implicit %scc<br>
 ^<br>
<br>
Looking at the generated output I see<br>
<br>
    %59 = S_MOV_B32 4294967292<br>
    %60 = S_MOV_B32 3<br>
    %16 = REG_SEQUENCE %59, 1, %60, 2<br>
    %53 = S_ADD_U32 %55, %56, implicit-def %scc<br>
    %55 = COPY %0.sub0<br>
    %56 = COPY %16.sub0<br>
<br>
so the s_ADD_U32 using %55 and %56 is output before the COPY:s that define %55 and %56?<br>
<br>
I just ran the test both on top-of-tree and exactly on commit r293551 and both fail.<br>
<br>
Anyone idea? I suppose it works for you so something fishy seems to be going on.<br>
<br>
Regards,<br>
Mikael<br>
<br>
<br>
<br>
On 01/30/2017 10:56 PM, Tom Stellard via llvm-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: tstellar<br>
Date: Mon Jan 30 15:56:46 2017<br>
New Revision: 293551<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=293551&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=293551&view=rev</a><br>
Log:<br>
Re-commit AMDGPU/GlobalISel: Add support for simple shaders<br>
<br>
Fix build when global-isel is disabled and fix a warning.<br>
<br>
Summary: We can select constant/global G_LOAD, global G_STORE, and G_GEP.<br>
<br>
Reviewers: qcolombet, MatzeB, t.p.northover, ab, arsenm<br>
<br>
Subscribers: mehdi_amini, vkalintiris, kzhuravl, wdng, nhaehnle, mgorny, yaxunl, tony-tye, modocache, llvm-commits, dberris<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D26730" rel="noreferrer" target="_blank">https://reviews.llvm.org/D2673<wbr>0</a><br>
<br>
Added:<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUGenRegisterBankInfo.def<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.h<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.h<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.h<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBanks.td<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>flat.mir<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>smrd.mir<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-store-<wbr>flat.mir<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/regbankselect.mir<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/shader-epilogs.ll<br>
    llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/smrd.ll<br>
Modified:<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPU.td<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.h<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUISelLowering.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUSubtarget.h<br>
    llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUTargetMachine.cpp<br>
    llvm/trunk/lib/Target/AMDGPU/C<wbr>MakeLists.txt<br>
    llvm/trunk/lib/Target/AMDGPU/U<wbr>tils/AMDGPUBaseInfo.cpp<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPU.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPU.td?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPU.td?rev=293551&r1=<wbr>293550&r2=293551&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPU.td (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPU.td Mon Jan 30 15:56:46 2017<br>
@@ -562,5 +562,6 @@ include "Processors.td"<br>
 include "AMDGPUInstrInfo.td"<br>
 include "AMDGPUIntrinsics.td"<br>
 include "AMDGPURegisterInfo.td"<br>
+include "AMDGPURegisterBanks.td"<br>
 include "AMDGPUInstructions.td"<br>
 include "AMDGPUCallingConv.td"<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUCallLowering.cpp?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUCallLowering.cpp?re<wbr>v=293551&r1=293550&r2=293551&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.cpp Mon Jan 30 15:56:46 2017<br>
@@ -14,8 +14,13 @@<br>
 //===------------------------<wbr>------------------------------<wbr>----------------===//<br>
<br>
 #include "AMDGPUCallLowering.h"<br>
+#include "AMDGPU.h"<br>
 #include "AMDGPUISelLowering.h"<br>
-<br>
+#include "AMDGPUSubtarget.h"<br>
+#include "SIISelLowering.h"<br>
+#include "SIRegisterInfo.h"<br>
+#include "SIMachineFunctionInfo.h"<br>
+#include "llvm/CodeGen/CallingConvLower<wbr>.h"<br>
 #include "llvm/CodeGen/GlobalISel/Machi<wbr>neIRBuilder.h"<br>
 #include "llvm/CodeGen/MachineInstrBuil<wbr>der.h"<br>
<br>
@@ -30,13 +35,135 @@ AMDGPUCallLowering::AMDGPUCall<wbr>Lowering(c<br>
 }<br>
<br>
 bool AMDGPUCallLowering::lowerRetur<wbr>n(MachineIRBuilder &MIRBuilder,<br>
-                                        const Value *Val, unsigned VReg) const {<br>
+                                     const Value *Val, unsigned VReg) const {<br>
+  MIRBuilder.buildInstr(AMDGPU::<wbr>S_ENDPGM);<br>
   return true;<br>
 }<br>
<br>
+unsigned AMDGPUCallLowering::lowerParam<wbr>eterPtr(MachineIRBuilder &MIRBuilder,<br>
+                                               Type *ParamTy,<br>
+                                               unsigned Offset) const {<br>
+<br>
+  MachineFunction &MF = MIRBuilder.getMF();<br>
+  const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>()<wbr>.getRegisterInfo();<br>
+  MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+  const Function &F = *MF.getFunction();<br>
+  const DataLayout &DL = F.getParent()->getDataLayout()<wbr>;<br>
+  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::CONSTANT_ADDRESS);<br>
+  LLT PtrType(*PtrTy, DL);<br>
+  unsigned DstReg = MRI.createGenericVirtualRegist<wbr>er(PtrType);<br>
+  unsigned KernArgSegmentPtr =<br>
+      TRI->getPreloadedValue(MF, SIRegisterInfo::KERNARG_SEGMEN<wbr>T_PTR);<br>
+  unsigned KernArgSegmentVReg = MRI.getLiveInVirtReg(KernArgSe<wbr>gmentPtr);<br>
+<br>
+  unsigned OffsetReg = MRI.createGenericVirtualRegist<wbr>er(LLT::scalar(64));<br>
+  MIRBuilder.buildConstant(Offse<wbr>tReg, Offset);<br>
+<br>
+  MIRBuilder.buildGEP(DstReg, KernArgSegmentVReg, OffsetReg);<br>
+<br>
+  return DstReg;<br>
+}<br>
+<br>
+void AMDGPUCallLowering::lowerParam<wbr>eter(MachineIRBuilder &MIRBuilder,<br>
+                                        Type *ParamTy, unsigned Offset,<br>
+                                        unsigned DstReg) const {<br>
+  MachineFunction &MF = MIRBuilder.getMF();<br>
+  const Function &F = *MF.getFunction();<br>
+  const DataLayout &DL = F.getParent()->getDataLayout()<wbr>;<br>
+  PointerType *PtrTy = PointerType::get(ParamTy, AMDGPUAS::CONSTANT_ADDRESS);<br>
+  MachinePointerInfo PtrInfo(UndefValue::get(PtrTy)<wbr>);<br>
+  unsigned TypeSize = DL.getTypeStoreSize(ParamTy);<br>
+  unsigned Align = DL.getABITypeAlignment(ParamTy<wbr>);<br>
+  unsigned PtrReg = lowerParameterPtr(MIRBuilder, ParamTy, Offset);<br>
+<br>
+  MachineMemOperand *MMO =<br>
+      MF.getMachineMemOperand(PtrInf<wbr>o, MachineMemOperand::MOLoad |<br>
+                                       MachineMemOperand::MONonTempo<wbr>ral |<br>
+                                       MachineMemOperand::MOInvarian<wbr>t,<br>
+                                       TypeSize, Align);<br>
+<br>
+  MIRBuilder.buildLoad(DstReg, PtrReg, *MMO);<br>
+}<br>
+<br>
 bool AMDGPUCallLowering::lowerForma<wbr>lArguments(MachineIRBuilder &MIRBuilder,<br>
                                               const Function &F,<br>
                                               ArrayRef<unsigned> VRegs) const {<br>
-  // TODO: Implement once there are generic loads/stores.<br>
+<br>
+  MachineFunction &MF = MIRBuilder.getMF();<br>
+  const SISubtarget *Subtarget = static_cast<const SISubtarget *>(&MF.getSubtarget());<br>
+  MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+  SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionIn<wbr>fo>();<br>
+  const SIRegisterInfo *TRI = MF.getSubtarget<SISubtarget>()<wbr>.getRegisterInfo();<br>
+  const DataLayout &DL = F.getParent()->getDataLayout()<wbr>;<br>
+<br>
+  SmallVector<CCValAssign, 16> ArgLocs;<br>
+  CCState CCInfo(F.getCallingConv(), F.isVarArg(), MF, ArgLocs, F.getContext());<br>
+<br>
+  // FIXME: How should these inputs interact with inreg / custom SGPR inputs?<br>
+  if (Info->hasPrivateSegmentBuffer<wbr>()) {<br>
+    unsigned PrivateSegmentBufferReg = Info->addPrivateSegmentBuffer(<wbr>*TRI);<br>
+    MF.addLiveIn(PrivateSegmentBuf<wbr>ferReg, &AMDGPU::SReg_128RegClass);<br>
+    CCInfo.AllocateReg(PrivateSegm<wbr>entBufferReg);<br>
+  }<br>
+<br>
+  if (Info->hasDispatchPtr()) {<br>
+    unsigned DispatchPtrReg = Info->addDispatchPtr(*TRI);<br>
+    // FIXME: Need to add reg as live-in<br>
+    CCInfo.AllocateReg(DispatchPtr<wbr>Reg);<br>
+  }<br>
+<br>
+  if (Info->hasQueuePtr()) {<br>
+    unsigned QueuePtrReg = Info->addQueuePtr(*TRI);<br>
+    // FIXME: Need to add reg as live-in<br>
+    CCInfo.AllocateReg(QueuePtrReg<wbr>);<br>
+  }<br>
+<br>
+  if (Info->hasKernargSegmentPtr()) {<br>
+    unsigned InputPtrReg = Info->addKernargSegmentPtr(*TR<wbr>I);<br>
+    const LLT P2 = LLT::pointer(2, 64);<br>
+    unsigned VReg = MRI.createGenericVirtualRegist<wbr>er(P2);<br>
+    MRI.addLiveIn(InputPtrReg, VReg);<br>
+    MIRBuilder.getMBB().addLiveIn(<wbr>InputPtrReg);<br>
+    MIRBuilder.buildCopy(VReg, InputPtrReg);<br>
+    CCInfo.AllocateReg(InputPtrReg<wbr>);<br>
+  }<br>
+<br>
+  if (Info->hasDispatchID()) {<br>
+    unsigned DispatchIDReg = Info->addDispatchID(*TRI);<br>
+    // FIXME: Need to add reg as live-in<br>
+    CCInfo.AllocateReg(DispatchIDR<wbr>eg);<br>
+  }<br>
+<br>
+  if (Info->hasFlatScratchInit()) {<br>
+    unsigned FlatScratchInitReg = Info->addFlatScratchInit(*TRI)<wbr>;<br>
+    // FIXME: Need to add reg as live-in<br>
+    CCInfo.AllocateReg(FlatScratch<wbr>InitReg);<br>
+  }<br>
+<br>
+  unsigned NumArgs = F.arg_size();<br>
+  Function::const_arg_iterator CurOrigArg = F.arg_begin();<br>
+  const AMDGPUTargetLowering &TLI = *getTLI<AMDGPUTargetLowering>(<wbr>);<br>
+  for (unsigned i = 0; i != NumArgs; ++i, ++CurOrigArg) {<br>
+    CurOrigArg->getType()->dump();<br>
+    MVT ValVT = TLI.getValueType(DL, CurOrigArg->getType()).getSimp<wbr>leVT();<br>
+    ISD::ArgFlagsTy Flags;<br>
+    Flags.setOrigAlign(DL.getABITy<wbr>peAlignment(CurOrigArg-><wbr>getType()));<br>
+    CCAssignFn *AssignFn = CCAssignFnForCall(F.getCalling<wbr>Conv(),<br>
+                                             /*IsVarArg=*/false);<br>
+    bool Res =<br>
+        AssignFn(i, ValVT, ValVT, CCValAssign::Full, Flags, CCInfo);<br>
+    assert(!Res && "Call operand has unhandled type");<br>
+    (void)Res;<br>
+  }<br>
+<br>
+  Function::const_arg_iterator Arg = F.arg_begin();<br>
+  for (unsigned i = 0; i != NumArgs; ++i, ++Arg) {<br>
+    // FIXME: We should be getting DebugInfo from the arguments some how.<br>
+    CCValAssign &VA = ArgLocs[i];<br>
+    lowerParameter(MIRBuilder, Arg->getType(),<br>
+                   VA.getLocMemOffset() +<br>
+                   Subtarget->getExplicitKernelA<wbr>rgOffset(MF), VRegs[i]);<br>
+  }<br>
+<br>
   return true;<br>
 }<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUCallLowering.h?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUCallLowering.h?rev=<wbr>293551&r1=293550&r2=293551&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.h (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUCallLowering.h Mon Jan 30 15:56:46 2017<br>
@@ -22,6 +22,13 @@ namespace llvm {<br>
 class AMDGPUTargetLowering;<br>
<br>
 class AMDGPUCallLowering: public CallLowering {<br>
+<br>
+  unsigned lowerParameterPtr(MachineIRBui<wbr>lder &MIRBuilder, Type *ParamTy,<br>
+                             unsigned Offset) const;<br>
+<br>
+  void lowerParameter(MachineIRBuilde<wbr>r &MIRBuilder, Type *ParamTy,<br>
+                      unsigned Offset, unsigned DstReg) const;<br>
+<br>
  public:<br>
   AMDGPUCallLowering(const AMDGPUTargetLowering &TLI);<br>
<br>
@@ -29,6 +36,7 @@ class AMDGPUCallLowering: public CallLow<br>
                    unsigned VReg) const override;<br>
   bool lowerFormalArguments(MachineIR<wbr>Builder &MIRBuilder, const Function &F,<br>
                             ArrayRef<unsigned> VRegs) const override;<br>
+  CCAssignFn *CCAssignFnForCall(CallingConv<wbr>::ID CC, bool IsVarArg) const;<br>
 };<br>
 } // End of namespace llvm;<br>
 #endif<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUGenRegisterBankInfo.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUGenRegisterBankInfo.def?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUGenRegisterBankInfo<wbr>.def?rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUGenRegisterBankInfo.def (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUGenRegisterBankInfo.def Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,62 @@<br>
+//===- AMDGPUGenRegisterBankInfo.def -----------------------------*<wbr>- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file defines all the static objects used by AMDGPURegisterBankInfo.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_BUILD_GLOBAL_ISEL<br>
+#error "You shouldn't build this"<br>
+#endif<br>
+<br>
+namespace llvm {<br>
+namespace AMDGPU {<br>
+<br>
+enum PartialMappingIdx {<br>
+  None = - 1,<br>
+  PM_SGPR32 = 0,<br>
+  PM_SGPR64 = 1,<br>
+  PM_VGPR32 = 2,<br>
+  PM_VGPR64 = 3<br>
+};<br>
+<br>
+const RegisterBankInfo::PartialMappi<wbr>ng PartMappings[] {<br>
+  // StartIdx, Length, RegBank<br>
+  {0, 32, SGPRRegBank},<br>
+  {0, 64, SGPRRegBank},<br>
+  {0, 32, VGPRRegBank},<br>
+  {0, 64, VGPRRegBank}<br>
+};<br>
+<br>
+const RegisterBankInfo::ValueMapping ValMappings[] {<br>
+  // SGPR 32-bit<br>
+  {&PartMappings[0], 1},<br>
+  // SGPR 64-bit<br>
+  {&PartMappings[1], 1},<br>
+  // VGPR 32-bit<br>
+  {&PartMappings[2], 1},<br>
+  // VGPR 64-bit<br>
+  {&PartMappings[3], 1}<br>
+};<br>
+<br>
+enum ValueMappingIdx {<br>
+  SGPRStartIdx = 0,<br>
+  VGPRStartIdx = 2<br>
+};<br>
+<br>
+const RegisterBankInfo::ValueMapping *getValueMapping(unsigned BankID,<br>
+                                                      unsigned Size) {<br>
+  assert(Size % 32 == 0);<br>
+  unsigned Idx = BankID == AMDGPU::SGPRRegBankID ? SGPRStartIdx : VGPRStartIdx;<br>
+  Idx += (Size / 32) - 1;<br>
+  return &ValMappings[Idx];<br>
+}<br>
+<br>
+} // End AMDGPU namespace.<br>
+} // End llvm namespace.<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUISelLowering.cpp?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUISelLowering.cpp?re<wbr>v=293551&r1=293550&r2=293551&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUISelLowering.cpp Mon Jan 30 15:56:46 2017<br>
@@ -15,6 +15,7 @@<br>
<br>
 #include "AMDGPUISelLowering.h"<br>
 #include "AMDGPU.h"<br>
+#include "AMDGPUCallLowering.h"<br>
 #include "AMDGPUFrameLowering.h"<br>
 #include "AMDGPUIntrinsicInfo.h"<br>
 #include "AMDGPURegisterInfo.h"<br>
@@ -670,6 +671,11 @@ bool AMDGPUTargetLowering::isNarrow<wbr>ingPr<br>
 // TargetLowering Callbacks<br>
 //===------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
+CCAssignFn *AMDGPUCallLowering::CCAssignF<wbr>nForCall(CallingConv::ID CC,<br>
+                                                  bool IsVarArg) const {<br>
+  return CC_AMDGPU;<br>
+}<br>
+<br>
 /// The SelectionDAGBuilder will automatically promote function arguments<br>
 /// with illegal types.  However, this does not work for the AMDGPU targets<br>
 /// since the function arguments are stored in memory as these illegal types.<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUInstructionSelector.cpp?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUInstructionSelector<wbr>.cpp?rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.cpp (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.cpp Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,418 @@<br>
+//===- AMDGPUInstructionSelector.cpp ----------------------------*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file implements the targeting of the InstructionSelector class for<br>
+/// AMDGPU.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "AMDGPUInstructionSelector.h"<br>
+#include "AMDGPUInstrInfo.h"<br>
+#include "AMDGPURegisterBankInfo.h"<br>
+#include "AMDGPURegisterInfo.h"<br>
+#include "AMDGPUSubtarget.h"<br>
+#include "llvm/CodeGen/MachineBasicBloc<wbr>k.h"<br>
+#include "llvm/CodeGen/MachineFunction.<wbr>h"<br>
+#include "llvm/CodeGen/MachineInstr.h"<br>
+#include "llvm/CodeGen/MachineInstrBuil<wbr>der.h"<br>
+#include "llvm/CodeGen/MachineRegisterI<wbr>nfo.h"<br>
+#include "llvm/IR/Type.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+#define DEBUG_TYPE "amdgpu-isel"<br>
+<br>
+using namespace llvm;<br>
+<br>
+AMDGPUInstructionSelector::AM<wbr>DGPUInstructionSelector(<br>
+    const SISubtarget &STI, const AMDGPURegisterBankInfo &RBI)<br>
+    : InstructionSelector(), TII(*STI.getInstrInfo()),<br>
+      TRI(*STI.getRegisterInfo()), RBI(RBI) {}<br>
+<br>
+MachineOperand<br>
+AMDGPUInstructionSelector::ge<wbr>tSubOperand64(MachineOperand &MO,<br>
+                                           unsigned SubIdx) const {<br>
+<br>
+  MachineInstr *MI = MO.getParent();<br>
+  MachineBasicBlock *BB = MO.getParent()->getParent();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  MachineRegisterInfo &MRI = MF->getRegInfo();<br>
+  unsigned DstReg = MRI.createVirtualRegister(&AMD<wbr>GPU::SGPR_32RegClass);<br>
+<br>
+  if (MO.isReg()) {<br>
+    unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.ge<wbr>tSubReg(), SubIdx);<br>
+    unsigned Reg = MO.getReg();<br>
+    BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)<br>
+            .addReg(Reg, 0, ComposedSubIdx);<br>
+<br>
+    return MachineOperand::CreateReg(DstR<wbr>eg, MO.isDef(), MO.isImplicit(),<br>
+                                     MO.isKill(), MO.isDead(), MO.isUndef(),<br>
+                                     MO.isEarlyClobber(), 0, MO.isDebug(),<br>
+                                     MO.isInternalRead());<br>
+  }<br>
+<br>
+  assert(MO.isImm());<br>
+<br>
+  APInt Imm(64, MO.getImm());<br>
+<br>
+  switch (SubIdx) {<br>
+  default:<br>
+    llvm_unreachable("do not know to split immediate with this sub index.");<br>
+  case AMDGPU::sub0:<br>
+    return MachineOperand::CreateImm(Imm.<wbr>getLoBits(32).getSExtValue());<br>
+  case AMDGPU::sub1:<br>
+    return MachineOperand::CreateImm(Imm.<wbr>getHiBits(32).getSExtValue());<br>
+  }<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectG_ADD(MachineInstr &I) const {<br>
+  MachineBasicBlock *BB = I.getParent();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  MachineRegisterInfo &MRI = MF->getRegInfo();<br>
+  unsigned Size = RBI.getSizeInBits(I.getOperand<wbr>(0).getReg(), MRI, TRI);<br>
+  unsigned DstLo = MRI.createVirtualRegister(&AMD<wbr>GPU::SReg_32RegClass);<br>
+  unsigned DstHi = MRI.createVirtualRegister(&AMD<wbr>GPU::SReg_32RegClass);<br>
+<br>
+  if (Size != 64)<br>
+    return false;<br>
+<br>
+  DebugLoc DL = I.getDebugLoc();<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_U32), DstLo)<br>
+          .add(getSubOperand64(I.getOper<wbr>and(1), AMDGPU::sub0))<br>
+          .add(getSubOperand64(I.getOper<wbr>and(2), AMDGPU::sub0));<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADDC_U32), DstHi)<br>
+          .add(getSubOperand64(I.getOper<wbr>and(1), AMDGPU::sub1))<br>
+          .add(getSubOperand64(I.getOper<wbr>and(2), AMDGPU::sub1));<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), I.getOperand(0).getReg())<br>
+          .addReg(DstLo)<br>
+          .addImm(AMDGPU::sub0)<br>
+          .addReg(DstHi)<br>
+          .addImm(AMDGPU::sub1);<br>
+<br>
+  for (MachineOperand &MO : I.explicit_operands()) {<br>
+    if (!MO.isReg() || TargetRegisterInfo::isPhysical<wbr>Register(MO.getReg()))<br>
+      continue;<br>
+    RBI.constrainGenericRegister(M<wbr>O.getReg(), AMDGPU::SReg_64RegClass, MRI);<br>
+  }<br>
+<br>
+  I.eraseFromParent();<br>
+  return true;<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectG_GEP(MachineInstr &I) const {<br>
+  return selectG_ADD(I);<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectG_STORE(MachineInstr &I) const {<br>
+  MachineBasicBlock *BB = I.getParent();<br>
+  DebugLoc DL = I.getDebugLoc();<br>
+<br>
+  // FIXME: Select store instruction based on address space<br>
+  MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(AMDGPU::FLAT_STORE_DWO<wbr>RD))<br>
+          .add(I.getOperand(1))<br>
+          .add(I.getOperand(0))<br>
+          .addImm(0)<br>
+          .addImm(0)<br>
+          .addImm(0);<br>
+<br>
+  // Now that we selected an opcode, we need to constrain the register<br>
+  // operands to use appropriate classes.<br>
+  bool Ret = constrainSelectedInstRegOperan<wbr>ds(*Flat, TII, TRI, RBI);<br>
+<br>
+  I.eraseFromParent();<br>
+  return Ret;<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectG_CONSTANT(MachineInstr &I) const {<br>
+  MachineBasicBlock *BB = I.getParent();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  MachineRegisterInfo &MRI = MF->getRegInfo();<br>
+  unsigned DstReg = I.getOperand(0).getReg();<br>
+  unsigned Size = RBI.getSizeInBits(DstReg, MRI, TRI);<br>
+<br>
+  if (Size == 32) {<br>
+    I.setDesc(TII.get(AMDGPU::S_MO<wbr>V_B32));<br>
+    return constrainSelectedInstRegOperan<wbr>ds(I, TII, TRI, RBI);<br>
+  }<br>
+<br>
+  assert(Size == 64);<br>
+<br>
+  DebugLoc DL = I.getDebugLoc();<br>
+  unsigned LoReg = MRI.createVirtualRegister(&AMD<wbr>GPU::SReg_32RegClass);<br>
+  unsigned HiReg = MRI.createVirtualRegister(&AMD<wbr>GPU::SReg_32RegClass);<br>
+  const APInt &Imm = I.getOperand(1).getCImm()->get<wbr>Value();<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), LoReg)<br>
+          .addImm(Imm.trunc(32).getZExtV<wbr>alue());<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), HiReg)<br>
+          .addImm(Imm.ashr(32).getZExtVa<wbr>lue());<br>
+<br>
+  BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)<br>
+          .addReg(LoReg)<br>
+          .addImm(AMDGPU::sub0)<br>
+          .addReg(HiReg)<br>
+          .addImm(AMDGPU::sub1);<br>
+  // We can't call constrainSelectedInstRegOperan<wbr>ds here, because it doesn't<br>
+  // work for target independent opcodes<br>
+  I.eraseFromParent();<br>
+  return RBI.constrainGenericRegister(D<wbr>stReg, AMDGPU::SReg_64RegClass, MRI);<br>
+}<br>
+<br>
+static bool isConstant(const MachineInstr &MI) {<br>
+  return MI.getOpcode() == TargetOpcode::G_CONSTANT;<br>
+}<br>
+<br>
+void AMDGPUInstructionSelector::get<wbr>AddrModeInfo(const MachineInstr &Load,<br>
+    const MachineRegisterInfo &MRI, SmallVectorImpl<GEPInfo> &AddrInfo) const {<br>
+<br>
+  const MachineInstr *PtrMI = MRI.getUniqueVRegDef(Load.getO<wbr>perand(1).getReg());<br>
+<br>
+  assert(PtrMI);<br>
+<br>
+  if (PtrMI->getOpcode() != TargetOpcode::G_GEP)<br>
+    return;<br>
+<br>
+  GEPInfo GEPInfo(*PtrMI);<br>
+<br>
+  for (unsigned i = 1, e = 3; i < e; ++i) {<br>
+    const MachineOperand &GEPOp = PtrMI->getOperand(i);<br>
+    const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.get<wbr>Reg());<br>
+    assert(OpDef);<br>
+    if (isConstant(*OpDef)) {<br>
+      // FIXME: Is it possible to have multiple Imm parts?  Maybe if we<br>
+      // are lacking other optimizations.<br>
+      assert(GEPInfo.Imm == 0);<br>
+      GEPInfo.Imm = OpDef->getOperand(1).getCImm()<wbr>->getSExtValue();<br>
+      continue;<br>
+    }<br>
+    const RegisterBank *OpBank = RBI.getRegBank(GEPOp.getReg(), MRI, TRI);<br>
+    if (OpBank->getID() == AMDGPU::SGPRRegBankID)<br>
+      GEPInfo.SgprParts.push_back(GE<wbr>POp.getReg());<br>
+    else<br>
+      GEPInfo.VgprParts.push_back(GE<wbr>POp.getReg());<br>
+  }<br>
+<br>
+  AddrInfo.push_back(GEPInfo);<br>
+  getAddrModeInfo(*PtrMI, MRI, AddrInfo);<br>
+}<br>
+<br>
+static bool isInstrUniform(const MachineInstr &MI) {<br>
+  if (!MI.hasOneMemOperand())<br>
+    return false;<br>
+<br>
+  const MachineMemOperand *MMO = *MI.memoperands_begin();<br>
+  const Value *Ptr = MMO->getValue();<br>
+<br>
+  // UndefValue means this is a load of a kernel input.  These are uniform.<br>
+  // Sometimes LDS instructions have constant pointers.<br>
+  // If Ptr is null, then that means this mem operand contains a<br>
+  // PseudoSourceValue like GOT.<br>
+  if (!Ptr || isa<UndefValue>(Ptr) || isa<Argument>(Ptr) ||<br>
+      isa<Constant>(Ptr) || isa<GlobalValue>(Ptr))<br>
+    return true;<br>
+<br>
+  const Instruction *I = dyn_cast<Instruction>(Ptr);<br>
+  return I && I->getMetadata("amdgpu.uniform<wbr>");<br>
+}<br>
+<br>
+static unsigned getSmrdOpcode(unsigned BaseOpcode, unsigned LoadSize) {<br>
+<br>
+  if (LoadSize == 32)<br>
+    return BaseOpcode;<br>
+<br>
+  switch (BaseOpcode) {<br>
+  case AMDGPU::S_LOAD_DWORD_IMM:<br>
+    switch (LoadSize) {<br>
+    case 64:<br>
+      return AMDGPU::S_LOAD_DWORDX2_IMM;<br>
+    case 128:<br>
+      return AMDGPU::S_LOAD_DWORDX4_IMM;<br>
+    case 256:<br>
+      return AMDGPU::S_LOAD_DWORDX8_IMM;<br>
+    case 512:<br>
+      return AMDGPU::S_LOAD_DWORDX16_IMM;<br>
+    }<br>
+    break;<br>
+  case AMDGPU::S_LOAD_DWORD_IMM_ci:<br>
+    switch (LoadSize) {<br>
+    case 64:<br>
+      return AMDGPU::S_LOAD_DWORDX2_IMM_ci;<br>
+    case 128:<br>
+      return AMDGPU::S_LOAD_DWORDX4_IMM_ci;<br>
+    case 256:<br>
+      return AMDGPU::S_LOAD_DWORDX8_IMM_ci;<br>
+    case 512:<br>
+      return AMDGPU::S_LOAD_DWORDX16_IMM_ci<wbr>;<br>
+    }<br>
+    break;<br>
+  case AMDGPU::S_LOAD_DWORD_SGPR:<br>
+    switch (LoadSize) {<br>
+    case 64:<br>
+      return AMDGPU::S_LOAD_DWORDX2_SGPR;<br>
+    case 128:<br>
+      return AMDGPU::S_LOAD_DWORDX4_SGPR;<br>
+    case 256:<br>
+      return AMDGPU::S_LOAD_DWORDX8_SGPR;<br>
+    case 512:<br>
+      return AMDGPU::S_LOAD_DWORDX16_SGPR;<br>
+    }<br>
+    break;<br>
+  }<br>
+  llvm_unreachable("Invalid base smrd opcode or size");<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::has<wbr>VgprParts(ArrayRef<GEPInfo> AddrInfo) const {<br>
+  for (const GEPInfo &GEPInfo : AddrInfo) {<br>
+    if (!GEPInfo.VgprParts.empty())<br>
+      return true;<br>
+  }<br>
+  return false;<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectSMRD(MachineInstr &I,<br>
+                                           ArrayRef<GEPInfo> AddrInfo) const {<br>
+<br>
+  if (!I.hasOneMemOperand())<br>
+    return false;<br>
+<br>
+  if ((*I.memoperands_begin())->get<wbr>AddrSpace() != AMDGPUAS::CONSTANT_ADDRESS)<br>
+    return false;<br>
+<br>
+  if (!isInstrUniform(I))<br>
+    return false;<br>
+<br>
+  if (hasVgprParts(AddrInfo))<br>
+    return false;<br>
+<br>
+  MachineBasicBlock *BB = I.getParent();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  const SISubtarget &Subtarget = MF->getSubtarget<SISubtarget>(<wbr>);<br>
+  MachineRegisterInfo &MRI = MF->getRegInfo();<br>
+  unsigned DstReg = I.getOperand(0).getReg();<br>
+  const DebugLoc &DL = I.getDebugLoc();<br>
+  unsigned Opcode;<br>
+  unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI);<br>
+<br>
+  if (!AddrInfo.empty() && AddrInfo[0].SgprParts.size() == 1) {<br>
+<br>
+    const GEPInfo &GEPInfo = AddrInfo[0];<br>
+<br>
+    unsigned PtrReg = GEPInfo.SgprParts[0];<br>
+    int64_t EncodedImm = AMDGPU::getSMRDEncodedOffset(S<wbr>ubtarget, GEPInfo.Imm);<br>
+    if (AMDGPU::isLegalSMRDImmOffset(<wbr>Subtarget, GEPInfo.Imm)) {<br>
+      Opcode = getSmrdOpcode(AMDGPU::S_LOAD_D<wbr>WORD_IMM, LoadSize);<br>
+<br>
+      MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)<br>
+                                 .addReg(PtrReg)<br>
+                                 .addImm(EncodedImm)<br>
+                                 .addImm(0); // glc<br>
+      return constrainSelectedInstRegOperan<wbr>ds(*SMRD, TII, TRI, RBI);<br>
+    }<br>
+<br>
+    if (Subtarget.getGeneration() == AMDGPUSubtarget::SEA_ISLANDS &&<br>
+        isUInt<32>(EncodedImm)) {<br>
+      Opcode = getSmrdOpcode(AMDGPU::S_LOAD_D<wbr>WORD_IMM_ci, LoadSize);<br>
+      MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)<br>
+                                   .addReg(PtrReg)<br>
+                                   .addImm(EncodedImm)<br>
+                                   .addImm(0); // glc<br>
+      return constrainSelectedInstRegOperan<wbr>ds(*SMRD, TII, TRI, RBI);<br>
+    }<br>
+<br>
+    if (isUInt<32>(GEPInfo.Imm)) {<br>
+      Opcode = getSmrdOpcode(AMDGPU::S_LOAD_D<wbr>WORD_SGPR, LoadSize);<br>
+      unsigned OffsetReg = MRI.createVirtualRegister(&AMD<wbr>GPU::SReg_32RegClass);<br>
+      BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), OffsetReg)<br>
+              .addImm(GEPInfo.Imm);<br>
+<br>
+      MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)<br>
+                                   .addReg(PtrReg)<br>
+                                   .addReg(OffsetReg)<br>
+                                   .addImm(0); // glc<br>
+      return constrainSelectedInstRegOperan<wbr>ds(*SMRD, TII, TRI, RBI);<br>
+    }<br>
+  }<br>
+<br>
+  unsigned PtrReg = I.getOperand(1).getReg();<br>
+  Opcode = getSmrdOpcode(AMDGPU::S_LOAD_D<wbr>WORD_IMM, LoadSize);<br>
+  MachineInstr *SMRD = BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg)<br>
+                               .addReg(PtrReg)<br>
+                               .addImm(0)<br>
+                               .addImm(0); // glc<br>
+  return constrainSelectedInstRegOperan<wbr>ds(*SMRD, TII, TRI, RBI);<br>
+}<br>
+<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ectG_LOAD(MachineInstr &I) const {<br>
+  MachineBasicBlock *BB = I.getParent();<br>
+  MachineFunction *MF = BB->getParent();<br>
+  MachineRegisterInfo &MRI = MF->getRegInfo();<br>
+  DebugLoc DL = I.getDebugLoc();<br>
+  unsigned DstReg = I.getOperand(0).getReg();<br>
+  unsigned PtrReg = I.getOperand(1).getReg();<br>
+  unsigned LoadSize = RBI.getSizeInBits(DstReg, MRI, TRI);<br>
+  unsigned Opcode;<br>
+<br>
+  SmallVector<GEPInfo, 4> AddrInfo;<br>
+<br>
+  getAddrModeInfo(I, MRI, AddrInfo);<br>
+<br>
+  if (selectSMRD(I, AddrInfo)) {<br>
+    I.eraseFromParent();<br>
+    return true;<br>
+  }<br>
+<br>
+  switch (LoadSize) {<br>
+  default:<br>
+    llvm_unreachable("Load size not supported\n");<br>
+  case 32:<br>
+    Opcode = AMDGPU::FLAT_LOAD_DWORD;<br>
+    break;<br>
+  case 64:<br>
+    Opcode = AMDGPU::FLAT_LOAD_DWORDX2;<br>
+    break;<br>
+  }<br>
+<br>
+  MachineInstr *Flat = BuildMI(*BB, &I, DL, TII.get(Opcode))<br>
+                               .add(I.getOperand(0))<br>
+                               .addReg(PtrReg)<br>
+                               .addImm(0)<br>
+                               .addImm(0)<br>
+                               .addImm(0);<br>
+<br>
+  bool Ret = constrainSelectedInstRegOperan<wbr>ds(*Flat, TII, TRI, RBI);<br>
+  I.eraseFromParent();<br>
+  return Ret;<br>
+}<br>
+<br>
+bool AMDGPUInstructionSelector::sel<wbr>ect(MachineInstr &I) const {<br>
+<br>
+  if (!isPreISelGenericOpcode(I.get<wbr>Opcode()))<br>
+    return true;<br>
+<br>
+  switch (I.getOpcode()) {<br>
+  default:<br>
+    break;<br>
+  case TargetOpcode::G_ADD:<br>
+    return selectG_ADD(I);<br>
+  case TargetOpcode::G_CONSTANT:<br>
+    return selectG_CONSTANT(I);<br>
+  case TargetOpcode::G_GEP:<br>
+    return selectG_GEP(I);<br>
+  case TargetOpcode::G_LOAD:<br>
+    return selectG_LOAD(I);<br>
+  case TargetOpcode::G_STORE:<br>
+    return selectG_STORE(I);<br>
+  }<br>
+  return false;<br>
+}<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUInstructionSelector.h?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUInstructionSelector<wbr>.h?rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.h (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUInstructionSelector.h Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,65 @@<br>
+//===- AMDGPUInstructionSelector ------------------------------<wbr>--*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file declares the targeting of the InstructionSelector class for<br>
+/// AMDGPU.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUI<wbr>NSTRUCTIONSELECTOR_H<br>
+#define LLVM_LIB_TARGET_AMDGPU_AMDGPUI<wbr>NSTRUCTIONSELECTOR_H<br>
+<br>
+#include "llvm/CodeGen/GlobalISel/Instr<wbr>uctionSelector.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/ADT/SmallVector.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class AMDGPUInstrInfo;<br>
+class AMDGPURegisterBankInfo;<br>
+class MachineInstr;<br>
+class MachineOperand;<br>
+class MachineRegisterInfo;<br>
+class SIInstrInfo;<br>
+class SIRegisterInfo;<br>
+class SISubtarget;<br>
+<br>
+class AMDGPUInstructionSelector : public InstructionSelector {<br>
+public:<br>
+  AMDGPUInstructionSelector(cons<wbr>t SISubtarget &STI,<br>
+                            const AMDGPURegisterBankInfo &RBI);<br>
+<br>
+  bool select(MachineInstr &I) const override;<br>
+<br>
+private:<br>
+  struct GEPInfo {<br>
+    const MachineInstr &GEP;<br>
+    SmallVector<unsigned, 2> SgprParts;<br>
+    SmallVector<unsigned, 2> VgprParts;<br>
+    int64_t Imm;<br>
+    GEPInfo(const MachineInstr &GEP) : GEP(GEP), Imm(0) { }<br>
+  };<br>
+<br>
+  MachineOperand getSubOperand64(MachineOperand &MO, unsigned SubIdx) const;<br>
+  bool selectG_CONSTANT(MachineInstr &I) const;<br>
+  bool selectG_ADD(MachineInstr &I) const;<br>
+  bool selectG_GEP(MachineInstr &I) const;<br>
+  bool hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const;<br>
+  void getAddrModeInfo(const MachineInstr &Load, const MachineRegisterInfo &MRI,<br>
+                       SmallVectorImpl<GEPInfo> &AddrInfo) const;<br>
+  bool selectSMRD(MachineInstr &I, ArrayRef<GEPInfo> AddrInfo) const;<br>
+  bool selectG_LOAD(MachineInstr &I) const;<br>
+  bool selectG_STORE(MachineInstr &I) const;<br>
+<br>
+  const SIInstrInfo &TII;<br>
+  const SIRegisterInfo &TRI;<br>
+  const AMDGPURegisterBankInfo &RBI;<br>
+};<br>
+<br>
+} // End llvm namespace.<br>
+#endif<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPULegalizerInfo.cpp?<wbr>rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.cpp (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.cpp Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,62 @@<br>
+//===- AMDGPULegalizerInfo.cpp ------------------------------<wbr>-----*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file implements the targeting of the Machinelegalizer class for<br>
+/// AMDGPU.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "AMDGPULegalizerInfo.h"<br>
+#include "llvm/CodeGen/ValueTypes.h"<br>
+#include "llvm/IR/Type.h"<br>
+#include "llvm/IR/DerivedTypes.h"<br>
+#include "llvm/Target/TargetOpcodes.h"<br>
+#include "llvm/Support/Debug.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+#ifndef LLVM_BUILD_GLOBAL_ISEL<br>
+#error "You shouldn't build this"<br>
+#endif<br>
+<br>
+AMDGPULegalizerInfo::AMDGPULe<wbr>galizerInfo() {<br>
+  using namespace TargetOpcode;<br>
+<br>
+  const LLT S32 = LLT::scalar(32);<br>
+  const LLT S64 = LLT::scalar(64);<br>
+  const LLT P1 = LLT::pointer(1, 64);<br>
+  const LLT P2 = LLT::pointer(2, 64);<br>
+<br>
+  setAction({G_CONSTANT, S64}, Legal);<br>
+<br>
+  setAction({G_GEP, P1}, Legal);<br>
+  setAction({G_GEP, P2}, Legal);<br>
+  setAction({G_GEP, 1, S64}, Legal);<br>
+<br>
+  setAction({G_LOAD, P1}, Legal);<br>
+  setAction({G_LOAD, P2}, Legal);<br>
+  setAction({G_LOAD, S32}, Legal);<br>
+  setAction({G_LOAD, 1, P1}, Legal);<br>
+  setAction({G_LOAD, 1, P2}, Legal);<br>
+<br>
+  setAction({G_STORE, S32}, Legal);<br>
+  setAction({G_STORE, 1, P1}, Legal);<br>
+<br>
+  // FIXME: When RegBankSelect inserts copies, it will only create new<br>
+  // registers with scalar types.  This means we can end up with<br>
+  // G_LOAD/G_STORE/G_GEP instruction with scalar types for their pointer<br>
+  // operands.  In assert builds, the instruction selector will assert<br>
+  // if it sees a generic instruction which isn't legal, so we need to<br>
+  // tell it that scalar types are legal for pointer operands<br>
+  setAction({G_GEP, S64}, Legal);<br>
+  setAction({G_LOAD, 1, S64}, Legal);<br>
+  setAction({G_STORE, 1, S64}, Legal);<br>
+<br>
+  computeTables();<br>
+}<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPULegalizerInfo.h?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPULegalizerInfo.h?rev<wbr>=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.h (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPULegalizerInfo.h Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,30 @@<br>
+//===- AMDGPULegalizerInfo ------------------------------<wbr>---------*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file declares the targeting of the Machinelegalizer class for<br>
+/// AMDGPU.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUM<wbr>ACHINELEGALIZER_H<br>
+#define LLVM_LIB_TARGET_AMDGPU_AMDGPUM<wbr>ACHINELEGALIZER_H<br>
+<br>
+#include "llvm/CodeGen/GlobalISel/Legal<wbr>izerInfo.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class LLVMContext;<br>
+<br>
+/// This class provides the information for the target register banks.<br>
+class AMDGPULegalizerInfo : public LegalizerInfo {<br>
+public:<br>
+  AMDGPULegalizerInfo();<br>
+};<br>
+} // End llvm namespace.<br>
+#endif<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPURegisterBankInfo.cp<wbr>p?rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.cpp (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.cpp Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,228 @@<br>
+//===- AMDGPURegisterBankInfo.cpp ------------------------------<wbr>-*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file implements the targeting of the RegisterBankInfo class for<br>
+/// AMDGPU.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#include "AMDGPURegisterBankInfo.h"<br>
+#include "AMDGPUInstrInfo.h"<br>
+#include "SIRegisterInfo.h"<br>
+#include "llvm/CodeGen/GlobalISel/Regis<wbr>terBank.h"<br>
+#include "llvm/CodeGen/GlobalISel/Regis<wbr>terBankInfo.h"<br>
+#include "llvm/IR/Constants.h"<br>
+#include "llvm/Target/TargetRegisterInf<wbr>o.h"<br>
+#include "llvm/Target/TargetSubtargetIn<wbr>fo.h"<br>
+<br>
+#define GET_TARGET_REGBANK_IMPL<br>
+#include "AMDGPUGenRegisterBank.inc"<br>
+<br>
+// This file will be TableGen'ed at some point.<br>
+#include "AMDGPUGenRegisterBankInfo.def<wbr>"<br>
+<br>
+using namespace llvm;<br>
+<br>
+#ifndef LLVM_BUILD_GLOBAL_ISEL<br>
+#error "You shouldn't build this"<br>
+#endif<br>
+<br>
+AMDGPURegisterBankInfo::AMDGP<wbr>URegisterBankInfo(const TargetRegisterInfo &TRI)<br>
+    : AMDGPUGenRegisterBankInfo(),<br>
+      TRI(static_cast<const SIRegisterInfo*>(&TRI)) {<br>
+<br>
+  // HACK: Until this is fully tablegen'd<br>
+  static bool AlreadyInit = false;<br>
+  if (AlreadyInit)<br>
+    return;<br>
+<br>
+  AlreadyInit = true;<br>
+<br>
+  const RegisterBank &RBSGPR = getRegBank(AMDGPU::SGPRRegBank<wbr>ID);<br>
+  assert(&RBSGPR == &AMDGPU::SGPRRegBank);<br>
+<br>
+  const RegisterBank &RBVGPR = getRegBank(AMDGPU::VGPRRegBank<wbr>ID);<br>
+  assert(&RBVGPR == &AMDGPU::VGPRRegBank);<br>
+<br>
+}<br>
+<br>
+unsigned AMDGPURegisterBankInfo::copyCo<wbr>st(const RegisterBank &A,<br>
+                                           const RegisterBank &B,<br>
+                                           unsigned Size) const {<br>
+  return RegisterBankInfo::copyCost(A, B, Size);<br>
+}<br>
+<br>
+const RegisterBank &AMDGPURegisterBankInfo::getRe<wbr>gBankFromRegClass(<br>
+    const TargetRegisterClass &RC) const {<br>
+<br>
+  if (TRI->isSGPRClass(&RC))<br>
+    return getRegBank(AMDGPU::SGPRRegBank<wbr>ID);<br>
+<br>
+  return getRegBank(AMDGPU::VGPRRegBank<wbr>ID);<br>
+}<br>
+<br>
+RegisterBankInfo::Instruction<wbr>Mappings<br>
+AMDGPURegisterBankInfo::getIn<wbr>strAlternativeMappings(<br>
+    const MachineInstr &MI) const {<br>
+<br>
+  const MachineFunction &MF = *MI.getParent()->getParent();<br>
+  const MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+<br>
+  unsigned Size = getSizeInBits(MI.getOperand(0)<wbr>.getReg(), MRI, *TRI);<br>
+<br>
+  InstructionMappings AltMappings;<br>
+  switch (MI.getOpcode()) {<br>
+  case TargetOpcode::G_LOAD: {<br>
+    // FIXME: Should we be hard coding the size for these mappings?<br>
+    InstructionMapping SSMapping(1, 1,<br>
+      getOperandsMapping({AMDGPU::ge<wbr>tValueMapping(AMDGPU::SGPRRegB<wbr>ankID, Size),<br>
+                          AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, 64)}),<br>
+      2); // Num Operands<br>
+    AltMappings.emplace_back(std::<wbr>move(SSMapping));<br>
+<br>
+    InstructionMapping VVMapping(2, 1,<br>
+      getOperandsMapping({AMDGPU::ge<wbr>tValueMapping(AMDGPU::VGPRRegB<wbr>ankID, Size),<br>
+                          AMDGPU::getValueMapping(AMDGPU<wbr>::VGPRRegBankID, 64)}),<br>
+      2); // Num Operands<br>
+    AltMappings.emplace_back(std::<wbr>move(VVMapping));<br>
+<br>
+    // FIXME: Should this be the pointer-size (64-bits) or the size of the<br>
+    // register that will hold the bufffer resourc (128-bits).<br>
+    InstructionMapping VSMapping(3, 1,<br>
+      getOperandsMapping({AMDGPU::ge<wbr>tValueMapping(AMDGPU::VGPRRegB<wbr>ankID, Size),<br>
+                          AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, 64)}),<br>
+      2); // Num Operands<br>
+    AltMappings.emplace_back(std::<wbr>move(VSMapping));<br>
+<br>
+    return AltMappings;<br>
+<br>
+  }<br>
+  default:<br>
+    break;<br>
+  }<br>
+  return RegisterBankInfo::getInstrAlte<wbr>rnativeMappings(MI);<br>
+}<br>
+<br>
+void AMDGPURegisterBankInfo::applyM<wbr>appingImpl(<br>
+    const OperandsMapper &OpdMapper) const {<br>
+  return applyDefaultMapping(OpdMapper)<wbr>;<br>
+}<br>
+<br>
+static bool isInstrUniform(const MachineInstr &MI) {<br>
+  if (!MI.hasOneMemOperand())<br>
+    return false;<br>
+<br>
+  const MachineMemOperand *MMO = *MI.memoperands_begin();<br>
+  return AMDGPU::isUniformMMO(MMO);<br>
+}<br>
+<br>
+RegisterBankInfo::Instruction<wbr>Mapping<br>
+AMDGPURegisterBankInfo::getIn<wbr>strMappingForLoad(const MachineInstr &MI) const {<br>
+<br>
+  const MachineFunction &MF = *MI.getParent()->getParent();<br>
+  const MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+  RegisterBankInfo::InstructionM<wbr>apping Mapping =<br>
+      InstructionMapping{1, 1, nullptr, MI.getNumOperands()};<br>
+  SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands(<wbr>));<br>
+  unsigned Size = getSizeInBits(MI.getOperand(0)<wbr>.getReg(), MRI, *TRI);<br>
+  unsigned PtrSize = getSizeInBits(MI.getOperand(1)<wbr>.getReg(), MRI, *TRI);<br>
+<br>
+  const ValueMapping *ValMapping;<br>
+  const ValueMapping *PtrMapping;<br>
+<br>
+  if (isInstrUniform(MI)) {<br>
+    // We have a uniform instruction so we want to use an SMRD load<br>
+    ValMapping = AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, Size);<br>
+    PtrMapping = AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, PtrSize);<br>
+  } else {<br>
+    ValMapping = AMDGPU::getValueMapping(AMDGPU<wbr>::VGPRRegBankID, Size);<br>
+    // FIXME: What would happen if we used SGPRRegBankID here?<br>
+    PtrMapping = AMDGPU::getValueMapping(AMDGPU<wbr>::VGPRRegBankID, PtrSize);<br>
+  }<br>
+<br>
+  OpdsMapping[0] = ValMapping;<br>
+  OpdsMapping[1] = PtrMapping;<br>
+  Mapping.setOperandsMapping(get<wbr>OperandsMapping(OpdsMapping));<br>
+  return Mapping;<br>
+<br>
+  // FIXME: Do we want to add a mapping for FLAT load, or should we just<br>
+  // handle that during instruction selection?<br>
+}<br>
+<br>
+RegisterBankInfo::Instruction<wbr>Mapping<br>
+AMDGPURegisterBankInfo::getIn<wbr>strMapping(const MachineInstr &MI) const {<br>
+  RegisterBankInfo::InstructionM<wbr>apping Mapping = getInstrMappingImpl(MI);<br>
+<br>
+  if (Mapping.isValid())<br>
+    return Mapping;<br>
+<br>
+  const MachineFunction &MF = *MI.getParent()->getParent();<br>
+  const MachineRegisterInfo &MRI = MF.getRegInfo();<br>
+  Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};<br>
+  SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands(<wbr>));<br>
+<br>
+  switch (MI.getOpcode()) {<br>
+  default: break;<br>
+  case AMDGPU::G_CONSTANT: {<br>
+    unsigned Size = MRI.getType(MI.getOperand(0).g<wbr>etReg()).getSizeInBits();<br>
+    OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, Size);<br>
+    Mapping.setOperandsMapping(get<wbr>OperandsMapping(OpdsMapping));<br>
+    return Mapping;<br>
+  }<br>
+  case AMDGPU::G_GEP: {<br>
+    for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {<br>
+      if (!MI.getOperand(i).isReg())<br>
+        continue;<br>
+<br>
+      unsigned Size = MRI.getType(MI.getOperand(i).g<wbr>etReg()).getSizeInBits();<br>
+      OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU<wbr>::SGPRRegBankID, Size);<br>
+    }<br>
+    Mapping.setOperandsMapping(get<wbr>OperandsMapping(OpdsMapping));<br>
+    return Mapping;<br>
+  }<br>
+  case AMDGPU::G_STORE: {<br>
+    assert(MI.getOperand(0).isReg(<wbr>));<br>
+    unsigned Size = MRI.getType(MI.getOperand(0).g<wbr>etReg()).getSizeInBits();<br>
+    // FIXME: We need to specify a different reg bank once scalar stores<br>
+    // are supported.<br>
+    const ValueMapping *ValMapping =<br>
+        AMDGPU::getValueMapping(AMDGPU<wbr>::VGPRRegBankID, Size);<br>
+    // FIXME: Depending on the type of store, the pointer could be in<br>
+    // the SGPR Reg bank.<br>
+    // FIXME: Pointer size should be based on the address space.<br>
+    const ValueMapping *PtrMapping =<br>
+        AMDGPU::getValueMapping(AMDGPU<wbr>::VGPRRegBankID, 64);<br>
+<br>
+    OpdsMapping[0] = ValMapping;<br>
+    OpdsMapping[1] = PtrMapping;<br>
+    Mapping.setOperandsMapping(get<wbr>OperandsMapping(OpdsMapping));<br>
+    return Mapping;<br>
+  }<br>
+<br>
+  case AMDGPU::G_LOAD:<br>
+    return getInstrMappingForLoad(MI);<br>
+  }<br>
+<br>
+  unsigned BankID = AMDGPU::SGPRRegBankID;<br>
+<br>
+  Mapping = InstructionMapping{1, 1, nullptr, MI.getNumOperands()};<br>
+  unsigned Size = 0;<br>
+  for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) {<br>
+    // If the operand is not a register default to the size of the previous<br>
+    // operand.<br>
+    // FIXME: Can't we pull the types from the MachineInstr rather than the<br>
+    // operands.<br>
+    if (MI.getOperand(Idx).isReg())<br>
+      Size = getSizeInBits(MI.getOperand(Id<wbr>x).getReg(), MRI, *TRI);<br>
+    OpdsMapping.push_back(AMDGPU::<wbr>getValueMapping(BankID, Size));<br>
+  }<br>
+  Mapping.setOperandsMapping(get<wbr>OperandsMapping(OpdsMapping));<br>
+<br>
+  return Mapping;<br>
+}<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPURegisterBankInfo.h?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPURegisterBankInfo.h?<wbr>rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.h (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBankInfo.h Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,65 @@<br>
+//===- AMDGPURegisterBankInfo ------------------------------<wbr>-----*- C++ -*-==//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// \file<br>
+/// This file declares the targeting of the RegisterBankInfo class for AMDGPU.<br>
+/// \todo This should be generated by TableGen.<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUR<wbr>EGISTERBANKINFO_H<br>
+#define LLVM_LIB_TARGET_AMDGPU_AMDGPUR<wbr>EGISTERBANKINFO_H<br>
+<br>
+#include "llvm/CodeGen/GlobalISel/Regis<wbr>terBankInfo.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+class SIRegisterInfo;<br>
+class TargetRegisterInfo;<br>
+<br>
+namespace AMDGPU {<br>
+enum {<br>
+  SGPRRegBankID = 0,<br>
+  VGPRRegBankID = 1,<br>
+  NumRegisterBanks<br>
+};<br>
+} // End AMDGPU namespace.<br>
+<br>
+/// This class provides the information for the target register banks.<br>
+class AMDGPUGenRegisterBankInfo : public RegisterBankInfo {<br>
+<br>
+protected:<br>
+<br>
+#define GET_TARGET_REGBANK_CLASS<br>
+#include "AMDGPUGenRegisterBank.inc"<br>
+<br>
+};<br>
+class AMDGPURegisterBankInfo : public AMDGPUGenRegisterBankInfo {<br>
+  const SIRegisterInfo *TRI;<br>
+<br>
+  /// See RegisterBankInfo::applyMapping<wbr>.<br>
+  void applyMappingImpl(const OperandsMapper &OpdMapper) const override;<br>
+<br>
+  RegisterBankInfo::InstructionM<wbr>apping<br>
+  getInstrMappingForLoad(const MachineInstr &MI) const;<br>
+<br>
+public:<br>
+  AMDGPURegisterBankInfo(const TargetRegisterInfo &TRI);<br>
+<br>
+  unsigned copyCost(const RegisterBank &A, const RegisterBank &B,<br>
+                    unsigned Size) const override;<br>
+<br>
+  const RegisterBank &<br>
+  getRegBankFromRegClass(const TargetRegisterClass &RC) const override;<br>
+<br>
+  InstructionMappings<br>
+  getInstrAlternativeMappings(co<wbr>nst MachineInstr &MI) const override;<br>
+<br>
+  InstructionMapping getInstrMapping(const MachineInstr &MI) const override;<br>
+};<br>
+} // End llvm namespace.<br>
+#endif<br>
<br>
Added: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBanks.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPURegisterBanks.td?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPURegisterBanks.td?re<wbr>v=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBanks.td (added)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPURegisterBanks.td Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,16 @@<br>
+//=- AMDGPURegisterBank.td - Describe the AMDGPU Banks -------*- tablegen -*-=//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+<br>
+def SGPRRegBank : RegisterBank<"SGPR",<br>
+  [SReg_32, SReg_64, SReg_128, SReg_256, SReg_512]<br>
+>;<br>
+<br>
+def VGPRRegBank : RegisterBank<"VGPR",<br>
+  [VGPR_32, VReg_64, VReg_96, VReg_128, VReg_256, VReg_512]<br>
+>;<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUSubtarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUSubtarget.h?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUSubtarget.h?rev=293<wbr>551&r1=293550&r2=293551&view=<wbr>diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUSubtarget.h (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUSubtarget.h Mon Jan 30 15:56:46 2017<br>
@@ -517,6 +517,21 @@ public:<br>
     return GISel->getCallLowering();<br>
   }<br>
<br>
+  const InstructionSelector *getInstructionSelector() const override {<br>
+    assert(GISel && "Access to GlobalISel APIs not set");<br>
+    return GISel->getInstructionSelector(<wbr>);<br>
+  }<br>
+<br>
+  const LegalizerInfo *getLegalizerInfo() const override {<br>
+    assert(GISel && "Access to GlobalISel APIs not set");<br>
+    return GISel->getLegalizerInfo();<br>
+  }<br>
+<br>
+  const RegisterBankInfo *getRegBankInfo() const override {<br>
+    assert(GISel && "Access to GlobalISel APIs not set");<br>
+    return GISel->getRegBankInfo();<br>
+  }<br>
+<br>
   const SIRegisterInfo *getRegisterInfo() const override {<br>
     return &InstrInfo.getRegisterInfo();<br>
   }<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUTargetMachine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/AMDGPUTargetMachine.cpp?<wbr>rev=293551&r1=293550&r2=293551<wbr>&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUTargetMachine.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/A<wbr>MDGPUTargetMachine.cpp Mon Jan 30 15:56:46 2017<br>
@@ -16,18 +16,20 @@<br>
 #include "AMDGPUTargetMachine.h"<br>
 #include "AMDGPU.h"<br>
 #include "AMDGPUCallLowering.h"<br>
+#include "AMDGPUInstructionSelector.h"<br>
+#include "AMDGPULegalizerInfo.h"<br>
+#ifdef LLVM_BUILD_GLOBAL_ISEL<br>
+#include "AMDGPURegisterBankInfo.h"<br>
+#endif<br>
 #include "AMDGPUTargetObjectFile.h"<br>
 #include "AMDGPUTargetTransformInfo.h"<br>
 #include "GCNSchedStrategy.h"<br>
 #include "R600MachineScheduler.h"<br>
 #include "SIMachineScheduler.h"<br>
-#include "llvm/ADT/SmallString.h"<br>
-#include "llvm/ADT/STLExtras.h"<br>
-#include "llvm/ADT/StringRef.h"<br>
-#include "llvm/ADT/Triple.h"<br>
-#include "llvm/CodeGen/GlobalISel/GISel<wbr>Accessor.h"<br>
+#include "llvm/CodeGen/GlobalISel/Instr<wbr>uctionSelect.h"<br>
 #include "llvm/CodeGen/GlobalISel/IRTra<wbr>nslator.h"<br>
-#include "llvm/CodeGen/MachineScheduler<wbr>.h"<br>
+#include "llvm/CodeGen/GlobalISel/Legal<wbr>izer.h"<br>
+#include "llvm/CodeGen/GlobalISel/RegBa<wbr>nkSelect.h"<br>
 #include "llvm/CodeGen/Passes.h"<br>
 #include "llvm/CodeGen/TargetPassConfig<wbr>.h"<br>
 #include "llvm/Support/TargetRegistry.h<wbr>"<br>
@@ -287,9 +289,21 @@ namespace {<br>
<br>
 struct SIGISelActualAccessor : public GISelAccessor {<br>
   std::unique_ptr<AMDGPUCallLow<wbr>ering> CallLoweringInfo;<br>
+  std::unique_ptr<InstructionSel<wbr>ector> InstSelector;<br>
+  std::unique_ptr<LegalizerInfo> Legalizer;<br>
+  std::unique_ptr<RegisterBankIn<wbr>fo> RegBankInfo;<br>
   const AMDGPUCallLowering *getCallLowering() const override {<br>
     return CallLoweringInfo.get();<br>
   }<br>
+  const InstructionSelector *getInstructionSelector() const override {<br>
+    return InstSelector.get();<br>
+  }<br>
+  const LegalizerInfo *getLegalizerInfo() const override {<br>
+    return Legalizer.get();<br>
+  }<br>
+  const RegisterBankInfo *getRegBankInfo() const override {<br>
+    return RegBankInfo.get();<br>
+  }<br>
 };<br>
<br>
 } // end anonymous namespace<br>
@@ -323,6 +337,11 @@ const SISubtarget *GCNTargetMachine::get<br>
     SIGISelActualAccessor *GISel = new SIGISelActualAccessor();<br>
     GISel->CallLoweringInfo.<wbr>reset(<br>
       new AMDGPUCallLowering(*I->getTarg<wbr>etLowering()));<br>
+    GISel->Legalizer.reset(new AMDGPULegalizerInfo());<br>
+<br>
+    GISel->RegBankInfo.reset(new AMDGPURegisterBankInfo(*I->get<wbr>RegisterInfo()));<br>
+    GISel->InstSelector.reset(new AMDGPUInstructionSelector(*I,<br>
+                               *static_cast<AMDGPURegisterBa<wbr>nkInfo*>(GISel->RegBankInfo.<wbr>get())));<br>
 #endif<br>
<br>
     I->setGISelAccessor(*GISel);<br>
@@ -623,16 +642,20 @@ bool GCNPassConfig::addIRTranslator<wbr>() {<br>
 }<br>
<br>
 bool GCNPassConfig::addLegalizeMach<wbr>ineIR() {<br>
+  addPass(new Legalizer());<br>
   return false;<br>
 }<br>
<br>
 bool GCNPassConfig::addRegBankSelec<wbr>t() {<br>
+  addPass(new RegBankSelect());<br>
   return false;<br>
 }<br>
<br>
 bool GCNPassConfig::addGlobalInstru<wbr>ctionSelect() {<br>
+  addPass(new InstructionSelect());<br>
   return false;<br>
 }<br>
+<br>
 #endif<br>
<br>
 void GCNPassConfig::addPreRegAlloc(<wbr>) {<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/C<wbr>MakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/CMakeLists.txt?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/CMakeLists.txt?rev=293551<wbr>&r1=293550&r2=293551&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/C<wbr>MakeLists.txt (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/C<wbr>MakeLists.txt Mon Jan 30 15:56:46 2017<br>
@@ -12,11 +12,17 @@ tablegen(LLVM AMDGPUGenAsmWriter.inc -ge<br>
 tablegen(LLVM AMDGPUGenAsmMatcher.inc -gen-asm-matcher)<br>
 tablegen(LLVM AMDGPUGenDisassemblerTables.in<wbr>c -gen-disassembler)<br>
 tablegen(LLVM AMDGPUGenMCPseudoLowering.inc -gen-pseudo-lowering)<br>
+if(LLVM_BUILD_GLOBAL_ISEL)<br>
+  tablegen(LLVM AMDGPUGenRegisterBank.inc -gen-register-bank)<br>
+endif()<br>
 add_public_tablegen_target(AM<wbr>DGPUCommonTableGen)<br>
<br>
 # List of all GlobalISel files.<br>
 set(GLOBAL_ISEL_FILES<br>
   AMDGPUCallLowering.cpp<br>
+  AMDGPUInstructionSelector.cpp<br>
+  AMDGPULegalizerInfo.cpp<br>
+  AMDGPURegisterBankInfo.cpp<br>
   )<br>
<br>
 # Add GlobalISel files to the dependencies if the user wants to build it.<br>
<br>
Modified: llvm/trunk/lib/Target/AMDGPU/U<wbr>tils/AMDGPUBaseInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp?rev=293551&r1=293550&r2=293551&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Target/AM<wbr>DGPU/Utils/AMDGPUBaseInfo.cpp?<wbr>rev=293551&r1=293550&r2=293551<wbr>&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Target/AMDGPU/U<wbr>tils/AMDGPUBaseInfo.cpp (original)<br>
+++ llvm/trunk/lib/Target/AMDGPU/U<wbr>tils/AMDGPUBaseInfo.cpp Mon Jan 30 15:56:46 2017<br>
@@ -10,10 +10,10 @@<br>
 #include "AMDGPU.h"<br>
 #include "SIDefines.h"<br>
 #include "llvm/CodeGen/MachineMemOperan<wbr>d.h"<br>
-#include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/Constants.h"<br>
 #include "llvm/IR/Function.h"<br>
 #include "llvm/IR/GlobalValue.h"<br>
+#include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/MC/MCContext.h"<br>
 #include "llvm/MC/MCInstrInfo.h"<br>
 #include "llvm/MC/MCRegisterInfo.h"<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>flat.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/inst-select-load-flat.mir?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/inst-select-<wbr>load-flat.mir?rev=293551&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>flat.mir (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>flat.mir Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,27 @@<br>
+# RUN: llc -march=amdgcn -mcpu=hawaii -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN<br>
+# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN<br>
+<br>
+# REQUIRES: global-isel<br>
+<br>
+--- |<br>
+  define void @global_addrspace(i32 addrspace(1)* %global0) { ret void }<br>
+...<br>
+---<br>
+<br>
+name:            global_addrspace<br>
+legalized:       true<br>
+regBankSelected: true<br>
+<br>
+# GCN: global_addrspace<br>
+# GCN: [[PTR:%[0-9]+]] = COPY %vgpr0_vgpr1<br>
+# GCN: FLAT_LOAD_DWORD  [[PTR]], 0, 0, 0<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins:  %vgpr0_vgpr1<br>
+<br>
+    %0:vgpr(p1) = COPY %vgpr0_vgpr1<br>
+    %1:vgpr(s32) = G_LOAD %0 :: (load 4 from %ir.global0)<br>
+<br>
+...<br>
+---<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>smrd.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/inst-select-load-smrd.mir?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/inst-select-<wbr>load-smrd.mir?rev=293551&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>smrd.mir (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-load-<wbr>smrd.mir Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,143 @@<br>
+# RUN: llc -march=amdgcn -mcpu=tahiti -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN,SI,SICI,SI<wbr>VI<br>
+# RUN: llc -march=amdgcn -mcpu=hawaii -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN,CI,SICI<br>
+# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN,VI,SIVI<br>
+<br>
+# REQUIRES: global-isel<br>
+<br>
+--- |<br>
+  define void @smrd_imm(i32 addrspace(2)* %const0) { ret void }<br>
+...<br>
+---<br>
+<br>
+name:            smrd_imm<br>
+legalized:       true<br>
+regBankSelected: true<br>
+<br>
+# GCN: body:<br>
+# GCN: [[PTR:%[0-9]+]] = COPY %sgpr0_sgpr1<br>
+<br>
+# Immediate offset:<br>
+# SICI: S_LOAD_DWORD_IMM [[PTR]], 1, 0<br>
+# VI:   S_LOAD_DWORD_IMM [[PTR]], 4, 0<br>
+<br>
+# Max immediate offset for SI<br>
+# SICI: S_LOAD_DWORD_IMM [[PTR]], 255, 0<br>
+# VI:   S_LOAD_DWORD_IMM [[PTR]], 1020, 0<br>
+<br>
+# Immediate overflow for SI<br>
+# FIXME: The immediate gets selected twice, once into the<br>
+# S_LOAD_DWORD instruction and once just as a normal constat.<br>
+# SI: S_MOV_B32 1024<br>
+# SI: [[K1024:%[0-9]+]] = S_MOV_B32 1024<br>
+# SI: S_LOAD_DWORD_SGPR [[PTR]], [[K1024]], 0<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 256, 0<br>
+# VI: S_LOAD_DWORD_IMM [[PTR]], 1024, 0<br>
+<br>
+# Max immediate offset for VI<br>
+# SI: S_MOV_B32 1048572<br>
+# SI: [[K1048572:%[0-9]+]] = S_MOV_B32 1048572<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 262143<br>
+# VI: S_LOAD_DWORD_IMM [[PTR]], 1048572<br>
+<br>
+#<br>
+# Immediate overflow for VI<br>
+# FIXME: The immediate gets selected twice, once into the<br>
+# S_LOAD_DWORD instruction and once just as a normal constat.<br>
+# SIVI: S_MOV_B32 1048576<br>
+# SIVI: [[K1048576:%[0-9]+]] = S_MOV_B32 1048576<br>
+# SIVI: S_LOAD_DWORD_SGPR [[PTR]], [[K1048576]], 0<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 262144, 0<br>
+<br>
+# Max immediate for CI<br>
+# SIVI: [[K_LO:%[0-9]+]] = S_MOV_B32 4294967292<br>
+# SIVI: [[K_HI:%[0-9]+]] = S_MOV_B32 3<br>
+# SIVI: [[K:%[0-9]+]] = REG_SEQUENCE [[K_LO]], 1, [[K_HI]], 2<br>
+# SIVI: [[K_SUB0:%[0-9]+]] = COPY [[K]].sub0<br>
+# SIVI: [[PTR_LO:%[0-9]+]] = COPY [[PTR]].sub0<br>
+# SIVI: [[ADD_PTR_LO:%[0-9]+]] = S_ADD_U32 [[PTR_LO]], [[K_SUB0]]<br>
+# SIVI: [[K_SUB1:%[0-9]+]] = COPY [[K]].sub1<br>
+# SIVI: [[PTR_HI:%[0-9]+]] = COPY [[PTR]].sub1<br>
+# SIVI: [[ADD_PTR_HI:%[0-9]+]] = S_ADDC_U32 [[PTR_HI]], [[K_SUB1]]<br>
+# SIVI: [[ADD_PTR:%[0-9]+]] = REG_SEQUENCE [[ADD_PTR_LO]], 1, [[ADD_PTR_HI]], 2<br>
+# SIVI: S_LOAD_DWORD_IMM [[ADD_PTR]], 0, 0<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 4294967295, 0<br>
+<br>
+# Immediate overflow for CI<br>
+# GCN: [[K_LO:%[0-9]+]] = S_MOV_B32 0<br>
+# GCN: [[K_HI:%[0-9]+]] = S_MOV_B32 4<br>
+# GCN: [[K:%[0-9]+]] = REG_SEQUENCE [[K_LO]], 1, [[K_HI]], 2<br>
+# GCN: [[K_SUB0:%[0-9]+]] = COPY [[K]].sub0<br>
+# GCN: [[PTR_LO:%[0-9]+]] = COPY [[PTR]].sub0<br>
+# GCN: [[ADD_PTR_LO:%[0-9]+]] = S_ADD_U32 [[PTR_LO]], [[K_SUB0]]<br>
+# GCN: [[K_SUB1:%[0-9]+]] = COPY [[K]].sub1<br>
+# GCN: [[PTR_HI:%[0-9]+]] = COPY [[PTR]].sub1<br>
+# GCN: [[ADD_PTR_HI:%[0-9]+]] = S_ADDC_U32 [[PTR_HI]], [[K_SUB1]]<br>
+# GCN: [[ADD_PTR:%[0-9]+]] = REG_SEQUENCE [[ADD_PTR_LO]], 1, [[ADD_PTR_HI]], 2<br>
+# GCN: S_LOAD_DWORD_IMM [[ADD_PTR]], 0, 0<br>
+<br>
+# Max 32-bit byte offset<br>
+# FIXME: The immediate gets selected twice, once into the<br>
+# S_LOAD_DWORD instruction and once just as a normal constat.<br>
+# SIVI: S_MOV_B32 4294967292<br>
+# SIVI: [[K4294967292:%[0-9]+]] = S_MOV_B32 4294967292<br>
+# SIVI: S_LOAD_DWORD_SGPR [[PTR]], [[K4294967292]], 0<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 1073741823, 0<br>
+<br>
+# Overflow 32-bit byte offset<br>
+# SIVI: [[K_LO:%[0-9]+]] = S_MOV_B32 0<br>
+# SIVI: [[K_HI:%[0-9]+]] = S_MOV_B32 1<br>
+# SIVI: [[K:%[0-9]+]] = REG_SEQUENCE [[K_LO]], 1, [[K_HI]], 2<br>
+# SIVI: [[K_SUB0:%[0-9]+]] = COPY [[K]].sub0<br>
+# SIVI: [[PTR_LO:%[0-9]+]] = COPY [[PTR]].sub0<br>
+# SIVI: [[ADD_PTR_LO:%[0-9]+]] = S_ADD_U32 [[PTR_LO]], [[K_SUB0]]<br>
+# SIVI: [[K_SUB1:%[0-9]+]] = COPY [[K]].sub1<br>
+# SIVI: [[PTR_HI:%[0-9]+]] = COPY [[PTR]].sub1<br>
+# SIVI: [[ADD_PTR_HI:%[0-9]+]] = S_ADDC_U32 [[PTR_HI]], [[K_SUB1]]<br>
+# SIVI: [[ADD_PTR:%[0-9]+]] = REG_SEQUENCE [[ADD_PTR_LO]], 1, [[ADD_PTR_HI]], 2<br>
+# SIVI: S_LOAD_DWORD_IMM [[ADD_PTR]], 0, 0<br>
+# CI: S_LOAD_DWORD_IMM_ci [[PTR]], 1073741824, 0<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins: %sgpr0_sgpr1<br>
+<br>
+    %0:sgpr(p2) = COPY %sgpr0_sgpr1<br>
+<br>
+    %1:sgpr(s64) = G_CONSTANT i64 4<br>
+    %2:sgpr(p2) = G_GEP %0, %1<br>
+    %3:sgpr(s32) = G_LOAD %2 :: (load 4 from %ir.const0)<br>
+<br>
+    %4:sgpr(s64) = G_CONSTANT i64 1020<br>
+    %5:sgpr(p2) = G_GEP %0, %4<br>
+    %6:sgpr(s32) = G_LOAD %5 :: (load 4 from %ir.const0)<br>
+<br>
+    %7:sgpr(s64) = G_CONSTANT i64 1024<br>
+    %8:sgpr(p2) = G_GEP %0, %7<br>
+    %9:sgpr(s32) = G_LOAD %8 :: (load 4 from %ir.const0)<br>
+<br>
+    %10:sgpr(s64) = G_CONSTANT i64 1048572<br>
+    %11:sgpr(p2) = G_GEP %0, %10<br>
+    %12:sgpr(s32) = G_LOAD %11 :: (load 4 from %ir.const0)<br>
+<br>
+    %13:sgpr(s64) = G_CONSTANT i64 1048576<br>
+    %14:sgpr(p2) = G_GEP %0, %13<br>
+    %15:sgpr(s32) = G_LOAD %14 :: (load 4 from %ir.const0)<br>
+<br>
+    %16:sgpr(s64) = G_CONSTANT i64 <a href="tel:17179869180" value="+17179869180" target="_blank">17179869180</a><br>
+    %17:sgpr(p2) = G_GEP %0, %16<br>
+    %18:sgpr(s32) = G_LOAD %17 :: (load 4 from %ir.const0)<br>
+<br>
+    %19:sgpr(s64) = G_CONSTANT i64 <a href="tel:17179869184" value="+17179869184" target="_blank">17179869184</a><br>
+    %20:sgpr(p2) = G_GEP %0, %19<br>
+    %21:sgpr(s32) = G_LOAD %20 :: (load 4 from %ir.const0)<br>
+<br>
+    %22:sgpr(s64) = G_CONSTANT i64 4294967292<br>
+    %23:sgpr(p2) = G_GEP %0, %22<br>
+    %24:sgpr(s32) = G_LOAD %23 :: (load 4 from %ir.const0)<br>
+<br>
+    %25:sgpr(s64) = G_CONSTANT i64 4294967296<br>
+    %26:sgpr(p2) = G_GEP %0, %25<br>
+    %27:sgpr(s32) = G_LOAD %26 :: (load 4 from %ir.const0)<br>
+<br>
+...<br>
+---<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-store-<wbr>flat.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/inst-select-store-flat.mir?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/inst-select-<wbr>store-flat.mir?rev=293551&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-store-<wbr>flat.mir (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/inst-select-store-<wbr>flat.mir Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,29 @@<br>
+# RUN: llc -march=amdgcn -mcpu=hawaii -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN<br>
+# RUN: llc -march=amdgcn -mcpu=fiji -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s -check-prefixes=GCN<br>
+<br>
+# REQUIRES: global-isel<br>
+<br>
+--- |<br>
+  define void @global_addrspace(i32 addrspace(1)* %global0) { ret void }<br>
+...<br>
+---<br>
+<br>
+name:            global_addrspace<br>
+legalized:       true<br>
+regBankSelected: true<br>
+<br>
+# GCN: global_addrspace<br>
+# GCN: [[PTR:%[0-9]+]] = COPY %vgpr0_vgpr1<br>
+# GCN: [[VAL:%[0-9]+]] = COPY %vgpr2<br>
+# GCN: FLAT_STORE_DWORD [[PTR]], [[VAL]], 0, 0, 0<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins:  %vgpr0_vgpr1, %vgpr2<br>
+<br>
+    %0:vgpr(p1) = COPY %vgpr0_vgpr1<br>
+    %1:vgpr(s32) = COPY %vgpr2<br>
+    G_STORE %1, %0 :: (store 4 into %ir.global0)<br>
+<br>
+...<br>
+---<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/regbankselect.mir<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/regbankselect.mir?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/regbankselec<wbr>t.mir?rev=293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/regbankselect.mir (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/regbankselect.mir Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,69 @@<br>
+# RUN: llc -march=amdgcn -mcpu=hawaii -run-pass=regbankselect -global-isel %s -verify-machineinstrs -o - | FileCheck %s<br>
+<br>
+# REQUIRES: global-isel<br>
+<br>
+--- |<br>
+  define void @load_constant(i32 addrspace(2)* %ptr0) { ret void }<br>
+  define void @load_global_uniform(i32 addrspace(1)* %ptr1) {<br>
+    %tmp0 = load i32, i32 addrspace(1)* %ptr1<br>
+    ret void<br>
+  }<br>
+  define void @load_global_non_uniform(i32 addrspace(1)* %ptr2) {<br>
+    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0<br>
+    %tmp1 = getelementptr i32, i32 addrspace(1)* %ptr2, i32 %tmp0<br>
+    %tmp2 = load i32, i32 addrspace(1)* %tmp1<br>
+    ret void<br>
+  }<br>
+  declare i32 @llvm.amdgcn.workitem.id.x() #0<br>
+  attributes #0 = { nounwind readnone }<br>
+...<br>
+<br>
+---<br>
+name : load_constant<br>
+legalized: true<br>
+<br>
+# CHECK-LABEL: name: load_constant<br>
+# CHECK: registers:<br>
+# CHECK: - { id: 0, class: sgpr }<br>
+# CHECK: - { id: 1, class: sgpr }<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins: %sgpr0_sgpr1<br>
+    %0:_(p2) = COPY %sgpr0_sgpr1<br>
+    %1:_(s32) = G_LOAD %0 :: (load 4 from %ir.ptr0)<br>
+...<br>
+<br>
+---<br>
+name: load_global_uniform<br>
+legalized: true<br>
+<br>
+# CHECK-LABEL: name: load_global_uniform<br>
+# CHECK: registers:<br>
+# CHECK: - { id: 0, class: sgpr }<br>
+# CHECK: - { id: 1, class: sgpr }<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins: %sgpr0_sgpr1<br>
+    %0:_(p1) = COPY %sgpr0_sgpr1<br>
+    %1:_(s32) = G_LOAD %0 :: (load 4 from %ir.ptr1)<br>
+...<br>
+<br>
+---<br>
+name: load_global_non_uniform<br>
+legalized: true<br>
+<br>
+# CHECK-LABEL: name: load_global_non_uniform<br>
+# CHECK: registers:<br>
+# CHECK: - { id: 0, class: sgpr }<br>
+# CHECK: - { id: 1, class: vgpr }<br>
+# CHECK: - { id: 2, class: vgpr }<br>
+<br>
+<br>
+body: |<br>
+  bb.0:<br>
+    liveins: %sgpr0_sgpr1<br>
+    %0:_(p1) = COPY %sgpr0_sgpr1<br>
+    %1:_(s32) = G_LOAD %0 :: (load 4 from %ir.tmp1)<br>
+...<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/shader-epilogs.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/shader-epilogs.ll?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/shader-<wbr>epilogs.ll?rev=293551&view=<wbr>auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/shader-epilogs.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/shader-epilogs.ll Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,11 @@<br>
+; RUN: llc < %s -march=amdgcn -mcpu=tonga -show-mc-encoding -verify-machineinstrs -global-isel | FileCheck --check-prefix=GCN %s<br>
+<br>
+; REQUIRES: global-isel<br>
+<br>
+; GCN-LABEL: vs_epilog<br>
+; GCN: s_endpgm<br>
+<br>
+define amdgpu_vs void @vs_epilog() {<br>
+main_body:<br>
+  ret void<br>
+}<br>
<br>
Added: llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/smrd.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AMDGPU/GlobalISel/smrd.ll?rev=293551&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/test/CodeGen/<wbr>AMDGPU/GlobalISel/smrd.ll?rev=<wbr>293551&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/smrd.ll (added)<br>
+++ llvm/trunk/test/CodeGen/AMDGPU<wbr>/GlobalISel/smrd.ll Mon Jan 30 15:56:46 2017<br>
@@ -0,0 +1,89 @@<br>
+; FIXME: Need to add support for mubuf stores to enable this on SI.<br>
+; XUN: llc < %s -march=amdgcn -mcpu=SI -show-mc-encoding -verify-machineinstrs -global-isel | FileCheck --check-prefix=SI --check-prefix=GCN --check-prefix=SIVI %s</blockquote>
</blockquote></div><br></div>