Index: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1279,6 +1279,10 @@ return true; } +static bool isSafeTruncation(int64_t Val, unsigned Size) { + return isUIntN(Size, Val) || isIntN(Size, Val); +} + bool AMDGPUOperand::isInlinableImm(MVT type) const { // This is a hack to enable named inline values like @@ -1327,6 +1331,10 @@ AsmParser->hasInv2PiInlineImm()); } + if (!isSafeTruncation(Imm.Val, type.getScalarSizeInBits())) { + return false; + } + if (type.getScalarSizeInBits() == 16) { return AMDGPU::isInlinableLiteral16( static_cast(Literal.getLoBits(16).getSExtValue()), @@ -1360,7 +1368,7 @@ // FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP // types. - return isUIntN(Size, Imm.Val) || isIntN(Size, Imm.Val); + return isSafeTruncation(Imm.Val, Size); } // We got fp literal token @@ -1501,11 +1509,6 @@ // checked earlier in isLiteralImm() uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue(); - if (OpTy == AMDGPU::OPERAND_REG_INLINE_C_V2INT16 || - OpTy == AMDGPU::OPERAND_REG_INLINE_C_V2FP16) { - ImmVal |= (ImmVal << 16); - } - Inst.addOperand(MCOperand::createImm(ImmVal)); return; } @@ -1516,15 +1519,14 @@ return; } - // We got int literal token. + // We got int literal token. // Only sign extend inline immediates. - // FIXME: No errors on truncation switch (OpTy) { case AMDGPU::OPERAND_REG_IMM_INT32: case AMDGPU::OPERAND_REG_IMM_FP32: case AMDGPU::OPERAND_REG_INLINE_C_INT32: case AMDGPU::OPERAND_REG_INLINE_C_FP32: - if (isInt<32>(Val) && + if (isSafeTruncation(Val, 32) && AMDGPU::isInlinableLiteral32(static_cast(Val), AsmParser->hasInv2PiInlineImm())) { Inst.addOperand(MCOperand::createImm(Val)); @@ -1550,7 +1552,7 @@ case AMDGPU::OPERAND_REG_IMM_FP16: case AMDGPU::OPERAND_REG_INLINE_C_INT16: case AMDGPU::OPERAND_REG_INLINE_C_FP16: - if (isInt<16>(Val) && + if (isSafeTruncation(Val, 16) && AMDGPU::isInlinableLiteral16(static_cast(Val), AsmParser->hasInv2PiInlineImm())) { Inst.addOperand(MCOperand::createImm(Val)); @@ -1562,13 +1564,11 @@ case AMDGPU::OPERAND_REG_INLINE_C_V2INT16: case AMDGPU::OPERAND_REG_INLINE_C_V2FP16: { - auto LiteralVal = static_cast(Literal.getLoBits(16).getZExtValue()); - assert(AMDGPU::isInlinableLiteral16(LiteralVal, + assert(isSafeTruncation(Val, 16)); + assert(AMDGPU::isInlinableLiteral16(static_cast(Val), AsmParser->hasInv2PiInlineImm())); - uint32_t ImmVal = static_cast(LiteralVal) << 16 | - static_cast(LiteralVal); - Inst.addOperand(MCOperand::createImm(ImmVal)); + Inst.addOperand(MCOperand::createImm(Val)); return; } default: Index: llvm/trunk/test/MC/AMDGPU/literal16-err.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/literal16-err.s +++ llvm/trunk/test/MC/AMDGPU/literal16-err.s @@ -1,21 +1,28 @@ -// XFAIL: * // RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck -check-prefix=NOVI %s v_add_f16 v1, 0xfffff, v2 -// NOVI: 19: error: invalid operand for instruction +// NOVI: error: invalid operand for instruction v_add_f16 v1, 0x10000, v2 -// NOVI: 19: error: invalid operand for instruction +// NOVI: error: invalid operand for instruction -v_add_f16 v1, v2, -0.0 -v_add_f16 v1, v2, 1 +v_add_f16 v1, 0xffffffffffff000f, v2 +// NOVI: error: invalid operand for instruction +v_add_f16 v1, 0x1000ffff, v2 +// NOVI: error: invalid operand for instruction - -// FIXME: Should give truncate error v_add_f16 v1, -32769, v2 +// NOVI: error: invalid operand for instruction + v_add_f16 v1, 65536, v2 +// NOVI: error: invalid operand for instruction v_add_f32 v1, 4294967296, v2 +// NOVI: error: invalid operand for instruction + v_add_f32 v1, 0x0000000100000000, v2 +// NOVI: error: invalid operand for instruction + v_and_b32 v1, 0x0000000100000000, v2 +// NOVI: error: invalid operand for instruction Index: llvm/trunk/test/MC/AMDGPU/literals.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/literals.s +++ llvm/trunk/test/MC/AMDGPU/literals.s @@ -4,11 +4,11 @@ // RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=CIVI --check-prefix=GFX89 // RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s | FileCheck %s --check-prefix=GCN --check-prefix=CIVI --check-prefix=GFX89 --check-prefix=GFX9 -// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSI --check-prefix=NOSICI --check-prefix=NOSICIVI -// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSI --check-prefix=NOSICI --check-prefix=NOSICIVI -// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSICI --check-prefix=NOCIVI --check-prefix=NOSICIVI -// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSICIVI -check-prefix=NOVI -check-prefix=NOGFX89 -// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck %s -check-prefix=NOGFX89 -check-prefix=NOGFX9 +// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGCN --check-prefix=NOSI --check-prefix=NOSICI --check-prefix=NOSICIVI +// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGCN --check-prefix=NOSI --check-prefix=NOSICI --check-prefix=NOSICIVI +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGCN --check-prefix=NOSICI --check-prefix=NOCIVI --check-prefix=NOSICIVI +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGCN --check-prefix=NOSICIVI --check-prefix=NOVI --check-prefix=NOGFX89 +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGCN --check-prefix=NOGFX89 --check-prefix=NOGFX9 //---------------------------------------------------------------------------// // fp literal, expected fp operand @@ -479,6 +479,46 @@ v_trunc_f32 v0, 0.159154943091895317852646485335 //---------------------------------------------------------------------------// +// integer literal truncation checks +//---------------------------------------------------------------------------// + +// NOGCN: error: invalid operand for instruction +s_mov_b32 s0, 0x101ffffffff + +// NOGCN: error: invalid operand for instruction +s_mov_b32 s0, 0x1000000001 + +// NOGCN: error: invalid operand for instruction +s_mov_b32 s0, 0x1000000fff + +// NOGCN: error: invalid operand for instruction +v_trunc_f32 v0, 0x1fffffffff0 + +// NOGCN: error: invalid operand for instruction +v_trunc_f32 v0, 0x100000001 + +// NOGCN: error: invalid operand for instruction +v_trunc_f32 v0, 0x1fffffff000 + +// NOGCN: error: invalid operand for instruction +s_mov_b64 s[0:1], 0x101ffffffff + +// NOGCN: error: invalid operand for instruction +s_mov_b64 s[0:1], 0x1000000001 + +// NOGCN: error: invalid operand for instruction +s_mov_b64 s[0:1], 0x1000000fff + +// NOGCN: error: invalid operand for instruction +v_trunc_f64 v[0:1], 0x1fffffffff0 + +// NOGCN: error: invalid operand for instruction +v_trunc_f64 v[0:1], 0x100000001 + +// NOGCN: error: invalid operand for instruction +v_trunc_f64 v[0:1], 0x1fffffff000 + +//---------------------------------------------------------------------------// // named inline values like shared_base //---------------------------------------------------------------------------// Index: llvm/trunk/test/MC/AMDGPU/literalv216-err.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/literalv216-err.s +++ llvm/trunk/test/MC/AMDGPU/literalv216-err.s @@ -1,22 +1,28 @@ // RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck -check-prefix=GFX9 %s v_pk_add_f16 v1, -17, v2 -// GFX9: :19: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, 65, v2 -// GFX9: :18: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, 64.0, v2 -// GFX9: :18: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, -0.15915494, v2 -// GFX9: :19: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, -0.0, v2 -// GFX9: :19: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, -32768, v2 -// GFX9: :19: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction v_pk_add_f16 v1, 32767, v2 -// GFX9: :18: error: invalid operand for instruction +// GFX9: error: invalid operand for instruction + +v_pk_add_f16 v1, 0xffffffffffff000f, v2 +// GFX9: error: invalid operand for instruction + +v_pk_add_f16 v1, 0x1000ffff, v2 +// GFX9: error: invalid operand for instruction