Index: lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp +++ lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp @@ -1106,6 +1106,7 @@ MIRBuilder.setInstr(MI); + const LLT S32 = LLT::scalar(32); Register Dst = MI.getOperand(0).getReg(); Register Src = MI.getOperand(1).getReg(); @@ -1128,6 +1129,13 @@ } if (SrcAS == AMDGPUAS::FLAT_ADDRESS) { + if (DestAS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) { + // Truncate. + MIRBuilder.buildExtract(Dst, Src, 0); + MI.eraseFromParent(); + return true; + } + assert(DestAS == AMDGPUAS::LOCAL_ADDRESS || DestAS == AMDGPUAS::PRIVATE_ADDRESS); unsigned NullVal = TM.getNullPointerValue(DestAS); @@ -1148,8 +1156,21 @@ return true; } - assert(SrcAS == AMDGPUAS::LOCAL_ADDRESS || - SrcAS == AMDGPUAS::PRIVATE_ADDRESS); + if (SrcAS == AMDGPUAS::CONSTANT_ADDRESS_32BIT) { + // This is a simple zero extend. + // + // FIXME: This is a bit ugly due to creating a merge of 2 pointers to + // another. Merge operands are required to be the same type, but creating an + // extra ptrtoint would be kind of pointless. + auto Zero = MIRBuilder.buildConstant( + LLT::pointer(AMDGPUAS::CONSTANT_ADDRESS_32BIT, 32), 0); + MIRBuilder.buildMerge(Dst, {Src, Zero.getReg(0)}); + MI.eraseFromParent(); + return true; + } + + if (SrcAS != AMDGPUAS::LOCAL_ADDRESS && SrcAS != AMDGPUAS::PRIVATE_ADDRESS) + return false; auto SegmentNull = MIRBuilder.buildConstant(SrcTy, TM.getNullPointerValue(SrcAS)); @@ -1164,7 +1185,7 @@ Register BuildPtr = MRI.createGenericVirtualRegister(DstTy); // Coerce the type of the low half of the result so we can use merge_values. - Register SrcAsInt = MRI.createGenericVirtualRegister(LLT::scalar(32)); + Register SrcAsInt = MRI.createGenericVirtualRegister(S32); MIRBuilder.buildInstr(TargetOpcode::G_PTRTOINT) .addDef(SrcAsInt) .addUse(Src); Index: test/CodeGen/AMDGPU/GlobalISel/legalize-addrspacecast.mir =================================================================== --- test/CodeGen/AMDGPU/GlobalISel/legalize-addrspacecast.mir +++ test/CodeGen/AMDGPU/GlobalISel/legalize-addrspacecast.mir @@ -381,3 +381,83 @@ %1:_(<2 x p0>) = G_ADDRSPACE_CAST %0 $vgpr0_vgpr1_vgpr2_vgpr3 = COPY %1 ... + +--- +name: test_addrspacecast_p4_to_p6 +body: | + bb.0: + liveins: $vgpr0_vgpr1 + + ; VI-LABEL: name: test_addrspacecast_p4_to_p6 + ; VI: [[COPY:%[0-9]+]]:_(p4) = COPY $vgpr0_vgpr1 + ; VI: [[ADDRSPACE_CAST:%[0-9]+]]:_(p6) = G_ADDRSPACE_CAST [[COPY]](p4) + ; VI: $vgpr0 = COPY [[ADDRSPACE_CAST]](p6) + ; GFX9-LABEL: name: test_addrspacecast_p4_to_p6 + ; GFX9: [[COPY:%[0-9]+]]:_(p4) = COPY $vgpr0_vgpr1 + ; GFX9: [[ADDRSPACE_CAST:%[0-9]+]]:_(p6) = G_ADDRSPACE_CAST [[COPY]](p4) + ; GFX9: $vgpr0 = COPY [[ADDRSPACE_CAST]](p6) + %0:_(p4) = COPY $vgpr0_vgpr1 + %1:_(p6) = G_ADDRSPACE_CAST %0 + $vgpr0 = COPY %1 +... + +--- +name: test_addrspacecast_p6_to_p4 +body: | + bb.0: + liveins: $vgpr0 + + ; VI-LABEL: name: test_addrspacecast_p6_to_p4 + ; VI: [[COPY:%[0-9]+]]:_(p6) = COPY $vgpr0 + ; VI: [[C:%[0-9]+]]:_(p6) = G_CONSTANT i32 0 + ; VI: [[MV:%[0-9]+]]:_(p4) = G_MERGE_VALUES [[COPY]](p6), [[C]](p6) + ; VI: $vgpr0_vgpr1 = COPY [[MV]](p4) + ; GFX9-LABEL: name: test_addrspacecast_p6_to_p4 + ; GFX9: [[COPY:%[0-9]+]]:_(p6) = COPY $vgpr0 + ; GFX9: [[C:%[0-9]+]]:_(p6) = G_CONSTANT i32 0 + ; GFX9: [[MV:%[0-9]+]]:_(p4) = G_MERGE_VALUES [[COPY]](p6), [[C]](p6) + ; GFX9: $vgpr0_vgpr1 = COPY [[MV]](p4) + %0:_(p6) = COPY $vgpr0 + %1:_(p4) = G_ADDRSPACE_CAST %0 + $vgpr0_vgpr1 = COPY %1 +... + +--- +name: test_addrspacecast_p0_to_p6 +body: | + bb.0: + liveins: $vgpr0_vgpr1 + + ; VI-LABEL: name: test_addrspacecast_p0_to_p6 + ; VI: [[COPY:%[0-9]+]]:_(p0) = COPY $vgpr0_vgpr1 + ; VI: [[EXTRACT:%[0-9]+]]:_(p6) = G_EXTRACT [[COPY]](p0), 0 + ; VI: $vgpr0 = COPY [[EXTRACT]](p6) + ; GFX9-LABEL: name: test_addrspacecast_p0_to_p6 + ; GFX9: [[COPY:%[0-9]+]]:_(p0) = COPY $vgpr0_vgpr1 + ; GFX9: [[EXTRACT:%[0-9]+]]:_(p6) = G_EXTRACT [[COPY]](p0), 0 + ; GFX9: $vgpr0 = COPY [[EXTRACT]](p6) + %0:_(p0) = COPY $vgpr0_vgpr1 + %1:_(p6) = G_ADDRSPACE_CAST %0 + $vgpr0 = COPY %1 +... + +--- +name: test_addrspacecast_p6_to_p0 +body: | + bb.0: + liveins: $vgpr0 + + ; VI-LABEL: name: test_addrspacecast_p6_to_p0 + ; VI: [[COPY:%[0-9]+]]:_(p6) = COPY $vgpr0 + ; VI: [[C:%[0-9]+]]:_(p6) = G_CONSTANT i32 0 + ; VI: [[MV:%[0-9]+]]:_(p0) = G_MERGE_VALUES [[COPY]](p6), [[C]](p6) + ; VI: $vgpr0_vgpr1 = COPY [[MV]](p0) + ; GFX9-LABEL: name: test_addrspacecast_p6_to_p0 + ; GFX9: [[COPY:%[0-9]+]]:_(p6) = COPY $vgpr0 + ; GFX9: [[C:%[0-9]+]]:_(p6) = G_CONSTANT i32 0 + ; GFX9: [[MV:%[0-9]+]]:_(p0) = G_MERGE_VALUES [[COPY]](p6), [[C]](p6) + ; GFX9: $vgpr0_vgpr1 = COPY [[MV]](p0) + %0:_(p6) = COPY $vgpr0 + %1:_(p0) = G_ADDRSPACE_CAST %0 + $vgpr0_vgpr1 = COPY %1 +...