diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index dc8323013bbd4..5bb0e3648d2ec 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -5139,13 +5139,45 @@ bool AMDGPUAsmParser::validateAGPRLdSt(const MCInst &Inst) const { bool AMDGPUAsmParser::validateVGPRAlign(const MCInst &Inst) const { auto FB = getFeatureBits(); + if (!FB[AMDGPU::FeatureGFX90AInsts] && !FB[AMDGPU::FeatureGFX1250Insts]) + return true; + unsigned Opc = Inst.getOpcode(); + const MCRegisterInfo *MRI = getMRI(); // DS_READ_B96_TR_B6 is the only DS instruction in GFX950, that allows // unaligned VGPR. All others only allow even aligned VGPRs. - if (!(FB[AMDGPU::FeatureGFX90AInsts]) || Opc == AMDGPU::DS_READ_B96_TR_B6_vi) + if (FB[AMDGPU::FeatureGFX90AInsts] && Opc == AMDGPU::DS_READ_B96_TR_B6_vi) return true; - const MCRegisterInfo *MRI = getMRI(); + if (FB[AMDGPU::FeatureGFX1250Insts]) { + switch (Opc) { + default: + break; + case AMDGPU::DS_LOAD_TR6_B96: + case AMDGPU::DS_LOAD_TR6_B96_gfx12: + // DS_LOAD_TR6_B96 is the only DS instruction in GFX1250, that + // allows unaligned VGPR. All others only allow even aligned VGPRs. + return true; + case AMDGPU::GLOBAL_LOAD_TR6_B96: + case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: { + // GLOBAL_LOAD_TR6_B96 is the only GLOBAL instruction in GFX1250, that + // allows unaligned VGPR for vdst, but other operands still only allow + // even aligned VGPRs. + int VAddrIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vaddr); + if (VAddrIdx != -1) { + const MCOperand &Op = Inst.getOperand(VAddrIdx); + MCRegister Sub = MRI->getSubReg(Op.getReg(), AMDGPU::sub0); + if ((Sub - AMDGPU::VGPR0) & 1) + return false; + } + return true; + } + case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR: + case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250: + return true; + } + } + const MCRegisterClass &VGPR32 = MRI->getRegClass(AMDGPU::VGPR_32RegClassID); const MCRegisterClass &AGPR32 = MRI->getRegClass(AMDGPU::AGPR_32RegClassID); for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) { diff --git a/llvm/test/MC/AMDGPU/gfx1250_asm_vflat_err.s b/llvm/test/MC/AMDGPU/gfx1250_asm_vflat_err.s new file mode 100644 index 0000000000000..86a63bcb4be89 --- /dev/null +++ b/llvm/test/MC/AMDGPU/gfx1250_asm_vflat_err.s @@ -0,0 +1,4 @@ +// RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s + +global_load_b96 v[1:3], v[0:1], off +// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid register class: vgpr tuples must be 64 bit aligned diff --git a/llvm/test/MC/AMDGPU/gfx1250_asm_vop2_err.s b/llvm/test/MC/AMDGPU/gfx1250_asm_vop2_err.s index b68306d60cf8c..f67ad88b5ae83 100644 --- a/llvm/test/MC/AMDGPU/gfx1250_asm_vop2_err.s +++ b/llvm/test/MC/AMDGPU/gfx1250_asm_vop2_err.s @@ -1,5 +1,8 @@ // RUN: not llvm-mc -triple=amdgcn -mcpu=gfx1250 -show-encoding %s 2>&1 | FileCheck --check-prefix=GFX1250-ERR --implicit-check-not=error: --strict-whitespace %s +v_add_f64 v[1:2], v[1:2], v[1:2] +// GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: invalid register class: vgpr tuples must be 64 bit aligned + v_fmaak_f32 v4, v2, v6, 3 row_share:1 // GFX1250-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: not a valid operand. // GFX1250-ERR-NEXT:{{^}}v_fmaak_f32 v4, v2, v6, 3 row_share:1