From 382557ec72958959a0503a0ef0cb332cac934917 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Fri, 23 Oct 2015 18:07:58 +0000 Subject: [PATCH] AMDGPU: Fix parsing of 32-bit literals with sign bit set llvm-svn: 251132 --- .../Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 4 +--- .../AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp | 9 +++++++-- llvm/test/MC/AMDGPU/sop1-err.s | 9 +++++++++ llvm/test/MC/AMDGPU/sop1.s | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index ad50003213d7..7a2951686459 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -987,13 +987,11 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { int64_t IntVal; if (getParser().parseAbsoluteExpression(IntVal)) return MatchOperand_ParseFail; - APInt IntVal32(32, IntVal); - if (IntVal32.getSExtValue() != IntVal) { + if (!isInt<32>(IntVal) && !isUInt<32>(IntVal)) { Error(S, "invalid immediate: only 32-bit values are legal"); return MatchOperand_ParseFail; } - IntVal = IntVal32.getSExtValue(); if (Negate) IntVal *= -1; Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S)); diff --git a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp index d64ac3f6265c..870b632c3062 100644 --- a/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp @@ -283,8 +283,13 @@ void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) { O << "4.0"; else if (Imm == DoubleToBits(-4.0)) O << "-4.0"; - else - llvm_unreachable("64-bit literal constants not supported"); + else { + assert(isUInt<32>(Imm)); + + // In rare situations, we will have a 32-bit literal in a 64-bit + // operand. This is technically allowed for the encoding of s_mov_b64. + O << formatHex(static_cast(Imm)); + } } void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, diff --git a/llvm/test/MC/AMDGPU/sop1-err.s b/llvm/test/MC/AMDGPU/sop1-err.s index f892356b623d..c54b357791a4 100644 --- a/llvm/test/MC/AMDGPU/sop1-err.s +++ b/llvm/test/MC/AMDGPU/sop1-err.s @@ -33,5 +33,14 @@ s_mov_b32 s1, 0xfffffffff s_mov_b64 s[0:1], 0xfffffffff // CHECK: error: invalid immediate: only 32-bit values are legal +s_mov_b64 s[0:1], 0xfffffffff +// CHECK: error: invalid immediate: only 32-bit values are legal + +s_mov_b64 s[0:1], 0xfffffffff +// CHECK: error: invalid immediate: only 32-bit values are legal + +s_mov_b64 s[0:1], 0x0000000200000000 +// CHECK: error: invalid immediate: only 32-bit values are legal + // Out of range register s_mov_b32 s diff --git a/llvm/test/MC/AMDGPU/sop1.s b/llvm/test/MC/AMDGPU/sop1.s index 92ca73f25004..a99bc9ab1cd6 100644 --- a/llvm/test/MC/AMDGPU/sop1.s +++ b/llvm/test/MC/AMDGPU/sop1.s @@ -10,12 +10,26 @@ s_mov_b32 s1, 1 s_mov_b32 s1, 100 // CHECK: s_mov_b32 s1, 0x64 ; encoding: [0xff,0x03,0x81,0xbe,0x64,0x00,0x00,0x00] +// Literal constant sign bit +s_mov_b32 s1, 0x80000000 +// CHECK: s_mov_b32 s1, 0x80000000 ; encoding: [0xff,0x03,0x81,0xbe,0x00,0x00,0x00,0x80] + +// Negative 32-bit constant +s_mov_b32 s0, 0xfe5163ab +// CHECK: s_mov_b32 s0, 0xfe5163ab ; encoding: [0xff,0x03,0x80,0xbe,0xab,0x63,0x51,0xfe] + s_mov_b64 s[2:3], s[4:5] // CHECK: s_mov_b64 s[2:3], s[4:5] ; encoding: [0x04,0x04,0x82,0xbe] s_mov_b64 s[2:3], 0xffffffffffffffff // CHECK: s_mov_b64 s[2:3], -1 ; encoding: [0xc1,0x04,0x82,0xbe] +s_mov_b64 s[2:3], 0xffffffff +// CHECK: s_mov_b64 s[2:3], 0xffffffff ; encoding: [0xff,0x04,0x82,0xbe,0xff,0xff,0xff,0xff] + +s_mov_b64 s[0:1], 0x80000000 +// CHECK: s_mov_b64 s[0:1], 0x80000000 ; encoding: [0xff,0x04,0x80,0xbe,0x00,0x00,0x00,0x80] + s_cmov_b32 s1, 200 // CHECK: s_cmov_b32 s1, 0xc8 ; encoding: [0xff,0x05,0x81,0xbe,0xc8,0x00,0x00,0x00]