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 @@ -5831,34 +5831,40 @@ //===----------------------------------------------------------------------===// OperandMatchResultTy AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) { - if (!isToken(AsmToken::Identifier)) + StringRef Str; + SMLoc S = getLoc(); + + if (!parseId(Str)) return MatchOperand_NoMatch; - StringRef Str = getTokenStr(); int Slot = StringSwitch(Str) .Case("p10", 0) .Case("p20", 1) .Case("p0", 2) .Default(-1); - SMLoc S = getLoc(); - if (Slot == -1) + if (Slot == -1) { + Error(S, "invalid interpolation slot"); return MatchOperand_ParseFail; + } - Parser.Lex(); Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S, AMDGPUOperand::ImmTyInterpSlot)); return MatchOperand_Success; } OperandMatchResultTy AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) { - if (!isToken(AsmToken::Identifier)) - return MatchOperand_NoMatch; + StringRef Str; + SMLoc S = getLoc(); - StringRef Str = getTokenStr(); - if (!Str.startswith("attr")) + if (!parseId(Str)) return MatchOperand_NoMatch; + if (!Str.startswith("attr")) { + Error(S, "invalid interpolation attribute"); + return MatchOperand_ParseFail; + } + StringRef Chan = Str.take_back(2); int AttrChan = StringSwitch(Chan) .Case(".x", 0) @@ -5866,19 +5872,21 @@ .Case(".z", 2) .Case(".w", 3) .Default(-1); - if (AttrChan == -1) + if (AttrChan == -1) { + Error(S, "invalid or missing interpolation attribute channel"); return MatchOperand_ParseFail; + } Str = Str.drop_back(2).drop_front(4); uint8_t Attr; - if (Str.getAsInteger(10, Attr)) + if (Str.getAsInteger(10, Attr)) { + Error(S, "invalid or missing interpolation attribute number"); return MatchOperand_ParseFail; + } - SMLoc S = getLoc(); - Parser.Lex(); if (Attr > 63) { - Error(S, "out of bounds attr"); + Error(S, "out of bounds interpolation attribute number"); return MatchOperand_ParseFail; } 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 @@ -443,21 +443,6 @@ // CHECK-NEXT:{{^}}v_ceil_f16 v0, abs(neg(1)) // CHECK-NEXT:{{^}} ^ -v_interp_mov_f32 v11, invalid_param_3, attr0.y -// CHECK: error: failed parsing operand. -// CHECK-NEXT:{{^}}v_interp_mov_f32 v11, invalid_param_3, attr0.y -// CHECK-NEXT:{{^}} ^ - -v_interp_mov_f32 v8, foo, attr0.x -// CHECK: error: failed parsing operand. -// CHECK-NEXT:{{^}}v_interp_mov_f32 v8, foo, attr0.x -// CHECK-NEXT:{{^}} ^ - -v_interp_p2_f32 v0, v1, attr -// CHECK: error: failed parsing operand. -// CHECK-NEXT:{{^}}v_interp_p2_f32 v0, v1, attr -// CHECK-NEXT:{{^}} ^ - //============================================================================== // first register index should not exceed second index @@ -588,6 +573,22 @@ // CHECK-NEXT:{{^}}v_dot_f32_f16 v0, v1, v2 // CHECK-NEXT:{{^}}^ +//============================================================================== +// invalid interpolation attribute + +v_interp_p2_f32 v0, v1, att +// CHECK: error: invalid interpolation attribute +// CHECK-NEXT:{{^}}v_interp_p2_f32 v0, v1, att +// CHECK-NEXT:{{^}} ^ + +//============================================================================== +// invalid interpolation slot + +v_interp_mov_f32 v8, p1, attr0.x +// CHECK: error: invalid interpolation slot +// CHECK-NEXT:{{^}}v_interp_mov_f32 v8, p1, attr0.x +// CHECK-NEXT:{{^}} ^ + //============================================================================== // invalid mask @@ -625,6 +626,22 @@ // CHECK-NEXT:{{^}}v_cvt_f64_i32 v[5:6], s1 mul:3 // CHECK-NEXT:{{^}} ^ +//============================================================================== +// invalid or missing interpolation attribute channel + +v_interp_p2_f32 v0, v1, attr0.q +// CHECK: error: invalid or missing interpolation attribute channel +// CHECK-NEXT:{{^}}v_interp_p2_f32 v0, v1, attr0.q +// CHECK-NEXT:{{^}} ^ + +//============================================================================== +// invalid or missing interpolation attribute number + +v_interp_p2_f32 v7, v1, attr.x +// CHECK: error: invalid or missing interpolation attribute number +// CHECK-NEXT:{{^}}v_interp_p2_f32 v7, v1, attr.x +// CHECK-NEXT:{{^}} ^ + //============================================================================== // invalid op_sel operand @@ -870,10 +887,10 @@ // CHECK-NEXT:{{^}} ^ //============================================================================== -// out of bounds attr +// out of bounds interpolation attribute number v_interp_p1_f32 v0, v1, attr64.w -// CHECK: error: out of bounds attr +// CHECK: error: out of bounds interpolation attribute number // CHECK-NEXT:{{^}}v_interp_p1_f32 v0, v1, attr64.w // CHECK-NEXT:{{^}} ^ diff --git a/llvm/test/MC/AMDGPU/vintrp-err.s b/llvm/test/MC/AMDGPU/vintrp-err.s --- a/llvm/test/MC/AMDGPU/vintrp-err.s +++ b/llvm/test/MC/AMDGPU/vintrp-err.s @@ -1,45 +1,68 @@ // RUN: not llvm-mc -arch=amdgcn %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=SI --implicit-check-not=error: %s // RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI --implicit-check-not=error: %s +v_interp_p1_f32 v0, v1 +// GCN: error: too few operands for instruction + v_interp_p1_f32 v0, v1, attr64.w -// GCN: :25: error: out of bounds attr +// GCN: error: out of bounds interpolation attribute number v_interp_p1_f32 v0, v1, attr64.x -// GCN: :25: error: out of bounds attr +// GCN: error: out of bounds interpolation attribute number v_interp_p2_f32 v9, v1, attr64.x -// GCN: :25: error: out of bounds attr +// GCN: error: out of bounds interpolation attribute number v_interp_p2_f32 v0, v1, attr64.x -// GCN: :25: error: out of bounds attr +// GCN: error: out of bounds interpolation attribute number v_interp_p2_f32 v0, v1, attr0.q -// GCN: :25: error: failed parsing operand. +// GCN: error: invalid or missing interpolation attribute channel v_interp_p2_f32 v0, v1, attr0. -// GCN: :25: error: failed parsing operand. +// GCN: error: invalid or missing interpolation attribute channel v_interp_p2_f32 v0, v1, attr -// GCN: :25: error: failed parsing operand. +// GCN: error: invalid or missing interpolation attribute channel -// XXX - Why does this one parse? v_interp_p2_f32 v0, v1, att -// GCN: :25: error: invalid operand for instruction +// GCN: error: invalid interpolation attribute v_interp_p2_f32 v0, v1, attrq -// GCN: :25: error: failed parsing operand. +// GCN: error: invalid or missing interpolation attribute channel + +v_interp_p2_f32 v7, v1, attr.x +// GCN: error: invalid or missing interpolation attribute number + +v_interp_p2_f32 v7, v1, attr-1.x +// GCN: error: invalid or missing interpolation attribute channel + +v_interp_p2_f32 v7, v1, attrA.x +// GCN: error: invalid or missing interpolation attribute number v_interp_mov_f32 v11, invalid_param_3, attr0.y -// GCN: :23: error: failed parsing operand. +// GCN: error: invalid interpolation slot v_interp_mov_f32 v12, invalid_param_10, attr0.x -// GCN: :23: error: failed parsing operand. +// GCN: error: invalid interpolation slot v_interp_mov_f32 v3, invalid_param_3, attr0.x -// GCN: :22: error: failed parsing operand. +// GCN: error: invalid interpolation slot v_interp_mov_f32 v8, invalid_param_8, attr0.x -// GCN: :22: error: failed parsing operand. +// GCN: error: invalid interpolation slot v_interp_mov_f32 v8, foo, attr0.x -// GCN: :22: error: failed parsing operand. +// GCN: error: invalid interpolation slot + +v_interp_mov_f32 v8, 0, attr0.x +// GCN: error: invalid operand for instruction + +v_interp_mov_f32 v8, -1, attr0.x +// GCN: error: invalid operand for instruction + +v_interp_mov_f32 v8, p-1, attr0.x +// GCN: error: invalid interpolation slot + +v_interp_mov_f32 v8, p1, attr0.x +// GCN: error: invalid interpolation slot