Index: lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -84,12 +84,12 @@ const LLT CodePtr = FlatPtr; - const LLT AddrSpaces[] = { - GlobalPtr, - ConstantPtr, - LocalPtr, - FlatPtr, - PrivatePtr + const std::initializer_list AddrSpaces64 = { + GlobalPtr, ConstantPtr, FlatPtr + }; + + const std::initializer_list AddrSpaces32 = { + LocalPtr, PrivatePtr }; setAction({G_BRCOND, S1}, Legal); @@ -182,19 +182,11 @@ getActionDefinitionsBuilder({G_INTRINSIC_TRUNC, G_INTRINSIC_ROUND}) .legalFor({S32, S64}); - for (LLT PtrTy : AddrSpaces) { - LLT IdxTy = LLT::scalar(PtrTy.getSizeInBits()); - setAction({G_GEP, PtrTy}, Legal); - setAction({G_GEP, 1, IdxTy}, Legal); - } - // FIXME: When RegBankSelect inserts copies, it will only create new registers - // with scalar types. This means we can end up with G_LOAD/G_STORE/G_GEP - // instruction with scalar types for their pointer operands. In assert builds, - // the instruction selector will assert if it sees a generic instruction which - // isn't legal, so we need to tell it that scalar types are legal for pointer - // operands - setAction({G_GEP, S64}, Legal); + getActionDefinitionsBuilder(G_GEP) + .legalForCartesianProduct(AddrSpaces64, {S64}) + .legalForCartesianProduct(AddrSpaces32, {S32}) + .scalarize(0); setAction({G_BLOCK_ADDR, CodePtr}, Legal); @@ -251,8 +243,8 @@ getActionDefinitionsBuilder(G_INTTOPTR) // List the common cases - .legalForCartesianProduct({GlobalPtr, ConstantPtr, FlatPtr}, {S64}) - .legalForCartesianProduct({LocalPtr, PrivatePtr}, {S32}) + .legalForCartesianProduct(AddrSpaces64, {S64}) + .legalForCartesianProduct(AddrSpaces32, {S32}) .scalarize(0) // Accept any address space as long as the size matches .legalIf(sameSize(0, 1)) @@ -267,8 +259,8 @@ getActionDefinitionsBuilder(G_PTRTOINT) // List the common cases - .legalForCartesianProduct({GlobalPtr, ConstantPtr, FlatPtr}, {S64}) - .legalForCartesianProduct({LocalPtr, PrivatePtr}, {S32}) + .legalForCartesianProduct(AddrSpaces64, {S64}) + .legalForCartesianProduct(AddrSpaces32, {S32}) .scalarize(0) // Accept any address space as long as the size matches .legalIf(sameSize(0, 1)) Index: lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp +++ lib/Target/AMDGPU/AMDGPURegisterBankInfo.cpp @@ -572,6 +572,7 @@ LLVM_FALLTHROUGH; } + case AMDGPU::G_GEP: case AMDGPU::G_ADD: case AMDGPU::G_SUB: case AMDGPU::G_MUL: @@ -710,16 +711,6 @@ OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); break; } - case AMDGPU::G_GEP: { - for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { - if (!MI.getOperand(i).isReg()) - continue; - - unsigned Size = MRI.getType(MI.getOperand(i).getReg()).getSizeInBits(); - OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); - } - break; - } case AMDGPU::G_STORE: { assert(MI.getOperand(0).isReg()); unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); Index: test/CodeGen/AMDGPU/GlobalISel/regbankselect-gep.mir =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/GlobalISel/regbankselect-gep.mir @@ -0,0 +1,90 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +# RUN: llc -march=amdgcn -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-fast | FileCheck %s +# RUN: llc -march=amdgcn -run-pass=regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s + +--- +name: gep_p1_s_k +legalized: true + +body: | + bb.0: + liveins: $sgpr0_sgpr1 + + ; CHECK-LABEL: name: gep_p1_s_k + ; CHECK: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1 + ; CHECK: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 1 + ; CHECK: [[GEP:%[0-9]+]]:sgpr(p1) = G_GEP [[COPY]], [[C]](s64) + %0:_(p1) = COPY $sgpr0_sgpr1 + %1:_(s64) = G_CONSTANT i64 1 + %2:_(p1) = G_GEP %0, %1 +... + +--- +name: gep_p1_s_s +legalized: true + +body: | + bb.0: + liveins: $sgpr0_sgpr1, $sgpr2_sgpr3 + + ; CHECK-LABEL: name: gep_p1_s_s + ; CHECK: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s64) = COPY $sgpr2_sgpr3 + ; CHECK: [[GEP:%[0-9]+]]:sgpr(p1) = G_GEP [[COPY]], [[COPY1]](s64) + %0:_(p1) = COPY $sgpr0_sgpr1 + %1:_(s64) = COPY $sgpr2_sgpr3 + %2:_(p1) = G_GEP %0, %1 +... + +--- +name: gep_p1_v_k +legalized: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1 + + ; CHECK-LABEL: name: gep_p1_v_k + ; CHECK: [[COPY:%[0-9]+]]:vgpr(p1) = COPY $vgpr0_vgpr1 + ; CHECK: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY [[C]](s64) + ; CHECK: [[GEP:%[0-9]+]]:vgpr(p1) = G_GEP [[COPY]], [[COPY1]](s64) + %0:_(p1) = COPY $vgpr0_vgpr1 + %1:_(s64) = G_CONSTANT i64 1 + %2:_(p1) = G_GEP %0, %1 +... + +--- +name: gep_p1_v_s +legalized: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $sgpr0_sgpr1 + + ; CHECK-LABEL: name: gep_p1_v_s + ; CHECK: [[COPY:%[0-9]+]]:vgpr(p1) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:sgpr(s64) = COPY $sgpr0_sgpr1 + ; CHECK: [[COPY2:%[0-9]+]]:vgpr(s64) = COPY [[COPY1]](s64) + ; CHECK: [[GEP:%[0-9]+]]:vgpr(p1) = G_GEP [[COPY]], [[COPY2]](s64) + %0:_(p1) = COPY $vgpr0_vgpr1 + %1:_(s64) = COPY $sgpr0_sgpr1 + %2:_(p1) = G_GEP %0, %1 +... + +--- +name: gep_p1_v_v +legalized: true + +body: | + bb.0: + liveins: $vgpr0_vgpr1, $vgpr2_vgpr3 + + ; CHECK-LABEL: name: gep_p1_v_v + ; CHECK: [[COPY:%[0-9]+]]:vgpr(p1) = COPY $vgpr0_vgpr1 + ; CHECK: [[COPY1:%[0-9]+]]:vgpr(s64) = COPY $vgpr2_vgpr3 + ; CHECK: [[GEP:%[0-9]+]]:vgpr(p1) = G_GEP [[COPY]], [[COPY1]](s64) + %0:_(p1) = COPY $vgpr0_vgpr1 + %1:_(s64) = COPY $vgpr2_vgpr3 + %2:_(p1) = G_GEP %0, %1 +...