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 @@ -1354,6 +1354,11 @@ SMLoc getFlatOffsetLoc(const OperandVector &Operands) const; SMLoc getSMEMOffsetLoc(const OperandVector &Operands) const; + SMLoc getOperandLoc(std::function Test, + const OperandVector &Operands) const; + SMLoc getImmLoc(AMDGPUOperand::ImmTy Type, const OperandVector &Operands) const; + SMLoc getRegLoc(unsigned Reg, const OperandVector &Operands) const; + bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc, const OperandVector &Operands); bool validateFlatOffset(const MCInst &Inst, const OperandVector &Operands); bool validateSMEMOffset(const MCInst &Inst, const OperandVector &Operands); @@ -3339,7 +3344,6 @@ if (Inst.getOperand(AMDGPU::getNamedOperandIdx(Inst.getOpcode(), Name)) .getImm() & SISrcMods::ABS) { - Error(getLoc(), "ABS not allowed in VOP3B instructions"); return false; } } @@ -3598,7 +3602,8 @@ } SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(const OperandVector &Operands) const { - for (unsigned i = 1, e = Operands.size(); i != e; ++i) { + // Start with second operand because SMEM Offset cannot be dst or src0. + for (unsigned i = 2, e = Operands.size(); i != e; ++i) { AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); if (Op.isSMEMOffset()) return Op.getStartLoc(); @@ -3760,7 +3765,7 @@ const SMLoc &IDLoc, const OperandVector &Operands) { if (!validateLdsDirect(Inst)) { - Error(IDLoc, + Error(getRegLoc(AMDGPU::LDS_DIRECT, Operands), "invalid use of lds_direct"); return false; } @@ -3785,18 +3790,18 @@ return false; } if (!validateIntClampSupported(Inst)) { - Error(IDLoc, + Error(getImmLoc(AMDGPUOperand::ImmTyClampSI, Operands), "integer clamping is not supported on this GPU"); return false; } if (!validateOpSel(Inst)) { - Error(IDLoc, + Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands), "invalid op_sel operand"); return false; } // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate. if (!validateMIMGD16(Inst)) { - Error(IDLoc, + Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands), "d16 modifier is not supported on this GPU"); return false; } @@ -3815,12 +3820,12 @@ return false; } if (!validateMIMGAtomicDMask(Inst)) { - Error(IDLoc, + Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands), "invalid atomic image dmask"); return false; } if (!validateMIMGGatherDMask(Inst)) { - Error(IDLoc, + Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands), "invalid image_gather dmask: only one bit must be set"); return false; } @@ -3838,6 +3843,7 @@ return false; } if (!validateDivScale(Inst)) { + Error(IDLoc, "ABS not allowed in VOP3B instructions"); return false; } if (!validateCoherencyBits(Inst, Operands, IDLoc)) { @@ -6079,6 +6085,33 @@ Parser.Lex(); } +SMLoc +AMDGPUAsmParser::getOperandLoc(std::function Test, + const OperandVector &Operands) const { + for (unsigned i = Operands.size() - 1; i > 0; --i) { + AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]); + if (Test(Op)) + return Op.getStartLoc(); + } + return ((AMDGPUOperand &)*Operands[0]).getStartLoc(); +} + +SMLoc +AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy Type, + const OperandVector &Operands) const { + auto Test = [=](const AMDGPUOperand& Op) { return Op.isImmTy(Type); }; + return getOperandLoc(Test, Operands); +} + +SMLoc +AMDGPUAsmParser::getRegLoc(unsigned Reg, + const OperandVector &Operands) const { + auto Test = [=](const AMDGPUOperand& Op) { + return Op.isRegKind() && Op.getReg() == Reg; + }; + return getOperandLoc(Test, Operands); +} + //===----------------------------------------------------------------------===// // swizzle //===----------------------------------------------------------------------===// 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 @@ -75,12 +75,12 @@ s_atc_probe_buffer 0x1, s[8:11], -1 // CHECK: error: expected a 20-bit unsigned offset // CHECK-NEXT:{{^}}s_atc_probe_buffer 0x1, s[8:11], -1 -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ s_atc_probe_buffer 0x1, s[8:11], 0xFFFFFFFFFFF00000 // CHECK: error: expected a 20-bit unsigned offset // CHECK-NEXT:{{^}}s_atc_probe_buffer 0x1, s[8:11], 0xFFFFFFFFFFF00000 -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ s_buffer_atomic_swap s5, s[4:7], 0x1FFFFF // CHECK: error: expected a 20-bit unsigned offset @@ -93,7 +93,7 @@ s_atc_probe 0x7, s[4:5], 0x1FFFFF // CHECK: error: expected a 21-bit signed offset // CHECK-NEXT:{{^}}s_atc_probe 0x7, s[4:5], 0x1FFFFF -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ s_atomic_swap s5, s[2:3], 0x1FFFFF // CHECK: error: expected a 21-bit signed offset @@ -606,7 +606,7 @@ v_permlane16_b32 v5, v1, s2, s3 op_sel:[0, 0, 0, 1] // CHECK: error: invalid op_sel operand // CHECK-NEXT:{{^}}v_permlane16_b32 v5, v1, s2, s3 op_sel:[0, 0, 0, 1] -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid op_sel value. @@ -711,7 +711,7 @@ v_ashrrev_i16 v0, lds_direct, v0 // CHECK: error: invalid use of lds_direct // CHECK-NEXT:{{^}}v_ashrrev_i16 v0, lds_direct, v0 -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // lane id must be in the interval [0,group size - 1] diff --git a/llvm/test/MC/AMDGPU/gfx7_err_pos.s b/llvm/test/MC/AMDGPU/gfx7_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx7_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx7_err_pos.s @@ -6,7 +6,7 @@ image_gather4 v[5:6], v1, s[8:15], s[12:15] dmask:0x1 d16 // CHECK: error: d16 modifier is not supported on this GPU // CHECK-NEXT:{{^}}image_gather4 v[5:6], v1, s[8:15], s[12:15] dmask:0x1 d16 -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // integer clamping is not supported on this GPU @@ -14,7 +14,7 @@ v_add_co_u32 v84, s[4:5], v13, v31 clamp // CHECK: error: integer clamping is not supported on this GPU // CHECK-NEXT:{{^}}v_add_co_u32 v84, s[4:5], v13, v31 clamp -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid literal operand diff --git a/llvm/test/MC/AMDGPU/gfx8_err_pos.s b/llvm/test/MC/AMDGPU/gfx8_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx8_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx8_err_pos.s @@ -14,7 +14,7 @@ s_atc_probe 0x7, s[4:5], -1 // CHECK: error: expected a 20-bit unsigned offset // CHECK-NEXT:{{^}}s_atc_probe 0x7, s[4:5], -1 -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ s_store_dword s1, s[2:3], 0xFFFFFFFFFFF00000 // CHECK: error: expected a 20-bit unsigned offset diff --git a/llvm/test/MC/AMDGPU/gfx9_err_pos.s b/llvm/test/MC/AMDGPU/gfx9_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx9_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx9_err_pos.s @@ -8,6 +8,14 @@ // CHECK-NEXT:{{^}}s_add_u32 null, null, null // CHECK-NEXT:{{^}} ^ +//============================================================================== +// ABS not allowed in VOP3B instructions + +v_div_scale_f64 v[24:25], vcc, -|v[22:23]|, v[22:23], v[20:21] +// CHECK: error: ABS not allowed in VOP3B instructions +// CHECK-NEXT:{{^}}v_div_scale_f64 v[24:25], vcc, -|v[22:23]|, v[22:23], v[20:21] +// CHECK-NEXT:{{^}}^ + //============================================================================== // duplicate VGPR index mode @@ -90,7 +98,7 @@ image_atomic_cmpswap v[4:7], v[192:195], s[28:35] dmask:0xe tfe // CHECK: error: invalid atomic image dmask // CHECK-NEXT:{{^}}image_atomic_cmpswap v[4:7], v[192:195], s[28:35] dmask:0xe tfe -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid image_gather dmask: only one bit must be set @@ -98,7 +106,7 @@ image_gather4_cl v[5:8], v[1:4], s[8:15], s[12:15] dmask:0x3 // CHECK: error: invalid image_gather dmask: only one bit must be set // CHECK-NEXT:{{^}}image_gather4_cl v[5:8], v[1:4], s[8:15], s[12:15] dmask:0x3 -// CHECK-NEXT:{{^}}^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid immediate: only 4-bit values are legal