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 @@ -3378,7 +3378,8 @@ unsigned OpIdx) const { const MCInstrDesc &Desc = MII.get(Inst.getOpcode()); - if (!AMDGPU::isSISrcOperand(Desc, OpIdx)) { + if (!AMDGPU::isSISrcOperand(Desc, OpIdx) || + AMDGPU::isKImmOperand(Desc, OpIdx)) { return false; } diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h --- a/llvm/lib/Target/AMDGPU/SIDefines.h +++ b/llvm/lib/Target/AMDGPU/SIDefines.h @@ -203,6 +203,9 @@ OPERAND_SRC_FIRST = OPERAND_REG_IMM_INT32, OPERAND_SRC_LAST = OPERAND_REG_INLINE_C_LAST, + OPERAND_KIMM_FIRST = OPERAND_KIMM32, + OPERAND_KIMM_LAST = OPERAND_KIMM16, + // Operand for source modifiers for VOP instructions OPERAND_INPUT_MODS, diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -1126,9 +1126,13 @@ LLVM_READNONE unsigned mc2PseudoReg(unsigned Reg); -/// Can this operand also contain immediate values? +/// Is this an AMDGPU specific source operand? These include registers, +/// inline constants, literals and mandatory literals (KImm). bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo); +/// Is this a KImm operand? +bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo); + /// Is this floating-point operand? bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo); 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 @@ -2083,6 +2083,13 @@ OpType <= AMDGPU::OPERAND_SRC_LAST; } +bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo) { + assert(OpNo < Desc.NumOperands); + unsigned OpType = Desc.OpInfo[OpNo].OperandType; + return OpType >= AMDGPU::OPERAND_KIMM_FIRST && + OpType <= AMDGPU::OPERAND_KIMM_LAST; +} + bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo) { assert(OpNo < Desc.NumOperands); unsigned OpType = Desc.OpInfo[OpNo].OperandType; diff --git a/llvm/test/MC/AMDGPU/gfx10_asm_err.s b/llvm/test/MC/AMDGPU/gfx10_asm_err.s --- a/llvm/test/MC/AMDGPU/gfx10_asm_err.s +++ b/llvm/test/MC/AMDGPU/gfx10_asm_err.s @@ -294,6 +294,22 @@ // GFX6-9: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU // GFX10: :[[@LINE-2]]:{{[0-9]+}}: error: only one unique literal operand is allowed +v_fmaak_f32 v0, 0xff32, v0, 0 +// GFX6-9: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +// GFX10: :[[@LINE-2]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmaak_f16 v0, 0xff32, v0, 0 +// GFX6-9: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +// GFX10: :[[@LINE-2]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmamk_f32 v0, 0xff32, 1, v0 +// GFX6-9: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +// GFX10: :[[@LINE-2]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmamk_f16 v0, 0xff32, 1, v0 +// GFX6-9: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +// GFX10: :[[@LINE-2]]:{{[0-9]+}}: error: only one unique literal operand is allowed + //===----------------------------------------------------------------------===// // VOP2 E64. //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AMDGPU/gfx11_asm_vop2_err.s b/llvm/test/MC/AMDGPU/gfx11_asm_vop2_err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AMDGPU/gfx11_asm_vop2_err.s @@ -0,0 +1,13 @@ +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1100 %s 2>&1 | FileCheck --check-prefix=GFX11 --implicit-check-not=error: %s + +v_fmaak_f32 v0, 0xff32, v0, 0 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmaak_f16 v0, 0xff32, v0, 0 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmamk_f32 v0, 0xff32, 1, v0 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed + +v_fmamk_f16 v0, 0xff32, 1, v0 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed diff --git a/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s b/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s --- a/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s +++ b/llvm/test/MC/AMDGPU/gfx11_asm_vopd_err.s @@ -39,6 +39,31 @@ // GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 0xdeadbeef, v161 :: v_dual_fmamk_f32 v123, s0, 0x1234, v162 // GFX11-NEXT:{{^}} ^ +//===----------------------------------------------------------------------===// +// Check that KImm operands are counted as literals +// even if they look like inline constants. +//===----------------------------------------------------------------------===// + +v_dual_fmamk_f32 v122, v74, 0, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, v74, 0, v161 :: v_dual_lshlrev_b32 v247, 0xbabe, v99 +// GFX11-NEXT:{{^}} ^ + +v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 1.0 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +// GFX11-NEXT:{{^}}v_dual_add_f32 v5, 0xaf123456, v2 :: v_dual_fmaak_f32 v6, v3, v1, 1.0 +// GFX11-NEXT:{{^}} ^ + +v_dual_fmamk_f32 v122, 0xdeadbeef, 2, v161 :: v_dual_fmamk_f32 v123, s0, 1, v162 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, 0xdeadbeef, 2, v161 :: v_dual_fmamk_f32 v123, s0, 1, v162 +// GFX11-NEXT:{{^}} ^ + +v_dual_fmamk_f32 v122, v1, 2, v161 :: v_dual_fmamk_f32 v123, s0, 1, v162 +// GFX11: :[[@LINE-1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +// GFX11-NEXT:{{^}}v_dual_fmamk_f32 v122, v1, 2, v161 :: v_dual_fmamk_f32 v123, s0, 1, v162 +// GFX11-NEXT:{{^}} ^ + //===----------------------------------------------------------------------===// // Check that assembler detects a different literal regardless of its location. //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AMDGPU/literals.s b/llvm/test/MC/AMDGPU/literals.s --- a/llvm/test/MC/AMDGPU/literals.s +++ b/llvm/test/MC/AMDGPU/literals.s @@ -846,17 +846,31 @@ // NOGCN: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed v_madak_f32 v0, 0xff32ff, v0, 0x11213141 +// NOGCN: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +v_madak_f32 v0, 0xff32ff, v0, 1 + // NOGCN: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed v_madmk_f32 v0, 0xff32ff, 0x11213141, v0 +// NOGCN: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +v_madmk_f32 v0, 0xff32ff, -1, v0 + // NOSICI: :[[@LINE+2]]:{{[0-9]+}}: error: instruction not supported on this GPU // NOGFX89: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed v_madak_f16 v0, 0xff32, v0, 0x1122 +// NOSICI: :[[@LINE+2]]:{{[0-9]+}}: error: instruction not supported on this GPU +// NOGFX89: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +v_madak_f16 v0, 0xff32, v0, 0 + // NOSICI: :[[@LINE+2]]:{{[0-9]+}}: error: instruction not supported on this GPU // NOGFX89: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed v_madmk_f16 v0, 0xff32, 0x1122, v0 +// NOSICI: :[[@LINE+2]]:{{[0-9]+}}: error: instruction not supported on this GPU +// NOGFX89: :[[@LINE+1]]:{{[0-9]+}}: error: only one unique literal operand is allowed +v_madmk_f16 v0, 0xff32, 1, v0 + // NOSICIVI: :[[@LINE+2]]:{{[0-9]+}}: error: register not available on this GPU // NOGFX9: :[[@LINE+1]]:{{[0-9]+}}: error: invalid operand (violates constant bus restrictions) v_cmp_eq_f32 s[0:1], private_base, private_limit