diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 1885b5958e8..9e2957e9c1a 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1053,6 +1053,7 @@ private: bool validateEarlyClobberLimitations(const MCInst &Inst); bool validateIntClampSupported(const MCInst &Inst); bool validateMIMGAtomicDMask(const MCInst &Inst); + bool validateMIMGGatherDMask(const MCInst &Inst); bool validateMIMGDataSize(const MCInst &Inst); bool validateMIMGR128(const MCInst &Inst); bool validateMIMGD16(const MCInst &Inst); @@ -2299,7 +2300,7 @@ bool AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst) { if ((Desc.TSFlags & SIInstrFlags::MIMG) == 0) return true; - // Gather4 instructions seem to have special rules not described in spec. + // Gather4 instructions do not need validation: dst size is hardcoded. if (Desc.TSFlags & SIInstrFlags::Gather4) return true; @@ -2345,6 +2346,25 @@ bool AMDGPUAsmParser::validateMIMGAtomicDMask(const MCInst &Inst) { return DMask == 0x1 || DMask == 0x3 || DMask == 0xf; } +bool AMDGPUAsmParser::validateMIMGGatherDMask(const MCInst &Inst) { + + const unsigned Opc = Inst.getOpcode(); + const MCInstrDesc &Desc = MII.get(Opc); + + if ((Desc.TSFlags & SIInstrFlags::Gather4) == 0) + return true; + + int DMaskIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask); + unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf; + + // GATHER4 instructions use dmask in a different fashion compared to + // other MIMG instructions. The only useful DMASK values are + // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns + // (red,red,red,red) etc.) The ISA document doesn't mention + // this. + return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8; +} + bool AMDGPUAsmParser::validateMIMGR128(const MCInst &Inst) { const unsigned Opc = Inst.getOpcode(); @@ -2412,6 +2432,11 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, "invalid atomic image dmask"); return false; } + if (!validateMIMGGatherDMask(Inst)) { + Error(IDLoc, + "invalid image_gather dmask: only one bit must be set"); + return false; + } return true; } |