diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1594,7 +1594,7 @@ bool validateMIMGAtomicDMask(const MCInst &Inst); bool validateMIMGGatherDMask(const MCInst &Inst); bool validateMovrels(const MCInst &Inst, const OperandVector &Operands); - bool validateMIMGDataSize(const MCInst &Inst); + Optional validateMIMGDataSize(const MCInst &Inst); bool validateMIMGAddrSize(const MCInst &Inst); bool validateMIMGD16(const MCInst &Inst); bool validateMIMGDim(const MCInst &Inst); @@ -3490,13 +3490,13 @@ return true; } -bool AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst) { +Optional AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst) { const unsigned Opc = Inst.getOpcode(); const MCInstrDesc &Desc = MII.get(Opc); if ((Desc.TSFlags & SIInstrFlags::MIMG) == 0) - return true; + return None; int VDataIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata); int DMaskIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask); @@ -3505,7 +3505,7 @@ assert(VDataIdx != -1); if (DMaskIdx == -1 || TFEIdx == -1) // intersect_ray - return true; + return None; unsigned VDataSize = AMDGPU::getRegOperandSize(getMRI(), Desc, VDataIdx); unsigned TFESize = (TFEIdx != -1 && Inst.getOperand(TFEIdx).getImm()) ? 1 : 0; @@ -3513,15 +3513,22 @@ if (DMask == 0) DMask = 1; + bool isPackedD16 = false; unsigned DataSize = (Desc.TSFlags & SIInstrFlags::Gather4) ? 4 : countPopulation(DMask); if (hasPackedD16()) { int D16Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::d16); - if (D16Idx >= 0 && Inst.getOperand(D16Idx).getImm()) + isPackedD16 = D16Idx >= 0; + if (isPackedD16 && Inst.getOperand(D16Idx).getImm()) DataSize = (DataSize + 1) / 2; } - return (VDataSize / 4) == DataSize + TFESize; + if ((VDataSize / 4) == DataSize + TFESize) + return None; + + return StringRef(isPackedD16 + ? "image data size does not match dmask, d16 and tfe" + : "image data size does not match dmask and tfe"); } bool AMDGPUAsmParser::validateMIMGAddrSize(const MCInst &Inst) { @@ -4446,9 +4453,8 @@ "invalid dim; must be MSAA type"); return false; } - if (!validateMIMGDataSize(Inst)) { - Error(IDLoc, - "image data size does not match dmask and tfe"); + if (auto ErrMsg = validateMIMGDataSize(Inst)) { + Error(IDLoc, *ErrMsg); return false; } if (!validateMIMGAddrSize(Inst)) { diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1618,7 +1618,8 @@ } bool hasPackedD16(const MCSubtargetInfo &STI) { - return !STI.getFeatureBits()[AMDGPU::FeatureUnpackedD16VMem]; + return !STI.getFeatureBits()[AMDGPU::FeatureUnpackedD16VMem] && !isCI(STI) && + !isSI(STI); } bool isSI(const MCSubtargetInfo &STI) { diff --git a/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s b/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s --- a/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s +++ b/llvm/test/MC/AMDGPU/gfx10_asm_mimg_err.s @@ -11,7 +11,7 @@ // NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction image_load v[0:1], v0, s[0:7] dmask:0xf dim:SQ_RSRC_IMG_1D -// NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: image data size does not match dmask and tfe +// NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: image data size does not match dmask, d16 and tfe image_load v[0:3], v[0:1], s[0:7] dmask:0xf dim:SQ_RSRC_IMG_1D // NOGFX10: :[[@LINE-1]]:{{[0-9]+}}: error: image address size does not match dim and a16 diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -604,10 +604,10 @@ // CHECK-NEXT:{{^}}^ //============================================================================== -// image data size does not match dmask and tfe +// image data size does not match dmask, d16 and tfe image_load v[0:1], v0, s[0:7] dmask:0xf dim:SQ_RSRC_IMG_1D -// CHECK: error: image data size does not match dmask and tfe +// CHECK: error: image data size does not match dmask, d16 and tfe // CHECK-NEXT:{{^}}image_load v[0:1], v0, s[0:7] dmask:0xf dim:SQ_RSRC_IMG_1D // CHECK-NEXT:{{^}}^ diff --git a/llvm/test/MC/AMDGPU/mimg.s b/llvm/test/MC/AMDGPU/mimg.s --- a/llvm/test/MC/AMDGPU/mimg.s +++ b/llvm/test/MC/AMDGPU/mimg.s @@ -90,32 +90,32 @@ image_load v[5:6], v[1:4], s[8:15] dmask:0x3 d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_load v[5:6], v[1:4], s[8:15] dmask:0x3 d16 ; encoding: [0x00,0x03,0x00,0xf0,0x01,0x05,0x02,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_load v[5:7], v[1:4], s[8:15] dmask:0x7 d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_load v[5:7], v[1:4], s[8:15] dmask:0x7 d16 ; encoding: [0x00,0x07,0x00,0xf0,0x01,0x05,0x02,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_load v[5:8], v[1:4], s[8:15] dmask:0xf d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_load v[5:8], v[1:4], s[8:15] dmask:0xf d16 ; encoding: [0x00,0x0f,0x00,0xf0,0x01,0x05,0x02,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_load v[5:7], v[1:4], s[8:15] dmask:0x3 tfe d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_load v[5:7], v[1:4], s[8:15] dmask:0x3 tfe d16 ; encoding: [0x00,0x03,0x01,0xf0,0x01,0x05,0x02,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_load v[5:8], v[1:4], s[8:15] dmask:0x7 tfe d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_load v[5:8], v[1:4], s[8:15] dmask:0x7 tfe d16 ; encoding: [0x00,0x07,0x01,0xf0,0x01,0x05,0x02,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe //===----------------------------------------------------------------------===// // Image Load/Store: d16 packed @@ -342,8 +342,8 @@ image_sample v[193:195], v[237:240], s[28:35], s[4:7] dmask:0x7 d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_sample v[193:195], v[237:240], s[28:35], s[4:7] dmask:0x7 d16 ; encoding: [0x00,0x07,0x80,0xf0,0xed,0xc1,0x27,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe //===----------------------------------------------------------------------===// // Image Sample: d16 unpacked @@ -470,8 +470,8 @@ image_gather4 v[5:8], v1, s[8:15], s[12:15] dmask:0x1 d16 // NOSICI: error: d16 modifier is not supported on this GPU // GFX8_0: image_gather4 v[5:8], v1, s[8:15], s[12:15] dmask:0x1 d16 ; encoding: [0x00,0x01,0x00,0xf1,0x01,0x05,0x62,0x80] -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_gather4 v[5:6], v1, s[8:15], s[12:15] dmask:0x1 d16 // NOSICI: error: d16 modifier is not supported on this GPU @@ -482,8 +482,8 @@ image_gather4 v[5:6], v1, s[8:15], s[12:15] dmask:0x1 // NOSICI: error: image data size does not match dmask and tfe // NOGFX8_0: error: image data size does not match dmask and tfe -// NOGFX8_1: error: image data size does not match dmask and tfe -// NOGFX9: error: image data size does not match dmask and tfe +// NOGFX8_1: error: image data size does not match dmask, d16 and tfe +// NOGFX9: error: image data size does not match dmask, d16 and tfe image_gather4 v[5:8], v1, s[8:15], s[12:15] dmask:0x1 a16 // GFX9: image_gather4 v[5:8], v1, s[8:15], s[12:15] dmask:0x1 a16 ; encoding: [0x00,0x81,0x00,0xf1,0x01,0x05,0x62,0x00]