Index: lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -447,10 +447,10 @@ } -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 @@ } 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 @@ 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; Index: test/MC/AMDGPU/out-of-range-registers.s =================================================================== --- test/MC/AMDGPU/out-of-range-registers.s +++ test/MC/AMDGPU/out-of-range-registers.s @@ -12,3 +12,12 @@ 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