From 8ad4a20d3e8e24617d3c95b9d963af7132471453 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 3 Nov 2015 22:50:32 +0000 Subject: [PATCH] AMDGPU: Fix asserts on invalid register ranges If the requested SGPR was not actually aligned, it was accepted and rounded down instead of rejected. Also fix an assert if the range is an invalid size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252009 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 18 +++++-- test/MC/AMDGPU/out-of-range-registers.s | 48 +++++++++++++++++++ test/MC/AMDGPU/smrd.s | 9 ++++ test/MC/AMDGPU/sop1.s | 3 ++ 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index a2420ad2070..3e3ceaa06b7 100644 --- a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -447,10 +447,10 @@ struct OptionalOperand { } -static unsigned getRegClass(bool IsVgpr, unsigned RegWidth) { +static int getRegClass(bool IsVgpr, unsigned RegWidth) { if (IsVgpr) { switch (RegWidth) { - default: llvm_unreachable("Unknown register width"); + default: return -1; case 1: return AMDGPU::VGPR_32RegClassID; case 2: return AMDGPU::VReg_64RegClassID; case 3: return AMDGPU::VReg_96RegClassID; @@ -461,7 +461,7 @@ static unsigned getRegClass(bool IsVgpr, unsigned RegWidth) { } switch (RegWidth) { - default: llvm_unreachable("Unknown register width"); + default: return -1; case 1: return AMDGPU::SGPR_32RegClassID; case 2: return AMDGPU::SGPR_64RegClassID; case 4: return AMDGPU::SReg_128RegClassID; @@ -541,12 +541,20 @@ bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &End RegIndexInClass = RegLo; } else { // SGPR registers are aligned. Max alignment is 4 dwords. - RegIndexInClass = RegLo / std::min(RegWidth, 4u); + unsigned Size = std::min(RegWidth, 4u); + if (RegLo % Size != 0) + return true; + + RegIndexInClass = RegLo / Size; } } const MCRegisterInfo *TRI = getContext().getRegisterInfo(); - const MCRegisterClass RC = TRI->getRegClass(getRegClass(IsVgpr, RegWidth)); + int RCID = getRegClass(IsVgpr, RegWidth); + if (RCID == -1) + return true; + + const MCRegisterClass RC = TRI->getRegClass(RCID); if (RegIndexInClass >= RC.getNumRegs()) return true; diff --git a/test/MC/AMDGPU/out-of-range-registers.s b/test/MC/AMDGPU/out-of-range-registers.s index 312c78e73ef..947c64d3e64 100644 --- a/test/MC/AMDGPU/out-of-range-registers.s +++ b/test/MC/AMDGPU/out-of-range-registers.s @@ -12,3 +12,51 @@ v_add_i32 v256, v0, v1 v_add_i32 v257, v0, v1 // CHECK: error: invalid operand for instruction + +s_mov_b64 s[0:17], -1 +// CHECK: error: invalid operand for instruction + +s_mov_b64 s[103:104], -1 +// CHECK: error: invalid operand for instruction + +s_mov_b64 s[104:105], -1 +// CHECK: error: invalid operand for instruction + +s_load_dwordx4 s[102:105], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx4 s[104:108], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx4 s[108:112], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx4 s[1:4], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx4 s[1:4], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx8 s[104:111], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx8 s[100:107], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx8 s[108:115], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx16 s[92:107], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx16 s[96:111], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx16 s[100:115], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx16 s[104:119], s[2:3], s4 +// CHECK: error: invalid operand for instruction + +s_load_dwordx16 s[108:123], s[2:3], s4 +// CHECK: error: invalid operand for instruction diff --git a/test/MC/AMDGPU/smrd.s b/test/MC/AMDGPU/smrd.s index 9b8471b19d2..56841914c6f 100644 --- a/test/MC/AMDGPU/smrd.s +++ b/test/MC/AMDGPU/smrd.s @@ -40,18 +40,27 @@ s_load_dwordx4 s[4:7], s[2:3], 1 s_load_dwordx4 s[4:7], s[2:3], s4 // GCN: s_load_dwordx4 s[4:7], s[2:3], s4 ; encoding: [0x04,0x02,0x82,0xc0] +s_load_dwordx4 s[100:103], s[2:3], s4 +// GCN: s_load_dwordx4 s[100:103], s[2:3], s4 ; encoding: [0x04,0x02,0xb2,0xc0] + s_load_dwordx8 s[8:15], s[2:3], 1 // GCN: s_load_dwordx8 s[8:15], s[2:3], 0x1 ; encoding: [0x01,0x03,0xc4,0xc0] s_load_dwordx8 s[8:15], s[2:3], s4 // GCN: s_load_dwordx8 s[8:15], s[2:3], s4 ; encoding: [0x04,0x02,0xc4,0xc0] +s_load_dwordx8 s[96:103], s[2:3], s4 +// GCN: s_load_dwordx8 s[96:103], s[2:3], s4 ; encoding: [0x04,0x02,0xf0,0xc0] + s_load_dwordx16 s[16:31], s[2:3], 1 // GCN: s_load_dwordx16 s[16:31], s[2:3], 0x1 ; encoding: [0x01,0x03,0x08,0xc1] s_load_dwordx16 s[16:31], s[2:3], s4 // GCN: s_load_dwordx16 s[16:31], s[2:3], s4 ; encoding: [0x04,0x02,0x08,0xc1] +s_load_dwordx16 s[88:103], s[2:3], s4 +// GCN: s_load_dwordx16 s[88:103], s[2:3], s4 ; encoding: [0x04,0x02,0x2c,0xc1] + s_dcache_inv // GCN: s_dcache_inv ; encoding: [0x00,0x00,0xc0,0xc7] diff --git a/test/MC/AMDGPU/sop1.s b/test/MC/AMDGPU/sop1.s index a99bc9ab1cd..5f63f993074 100644 --- a/test/MC/AMDGPU/sop1.s +++ b/test/MC/AMDGPU/sop1.s @@ -30,6 +30,9 @@ s_mov_b64 s[2:3], 0xffffffff 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_mov_b64 s[102:103], -1 +// CHECK: s_mov_b64 s[102:103], -1 ; encoding: [0xc1,0x04,0xe6,0xbe] + s_cmov_b32 s1, 200 // CHECK: s_cmov_b32 s1, 0xc8 ; encoding: [0xff,0x05,0x81,0xbe,0xc8,0x00,0x00,0x00] -- 2.34.1