AMDGPU: Fix asserts on invalid register ranges
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 3 Nov 2015 22:50:32 +0000 (22:50 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 3 Nov 2015 22:50:32 +0000 (22:50 +0000)
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

lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
test/MC/AMDGPU/out-of-range-registers.s
test/MC/AMDGPU/smrd.s
test/MC/AMDGPU/sop1.s

index a2420ad20700315a42c8b00ee05313d9d731f13c..3e3ceaa06b7008d51909afe87b60f716d68d47dc 100644 (file)
@@ -447,10 +447,10 @@ struct OptionalOperand {
 
 }
 
 
 }
 
-static unsigned getRegClass(bool IsVgpr, unsigned RegWidth) {
+static int getRegClass(bool IsVgpr, unsigned RegWidth) {
   if (IsVgpr) {
     switch (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;
       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) {
   }
 
   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;
     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;
     } 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 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;
 
   if (RegIndexInClass >= RC.getNumRegs())
     return true;
 
index 312c78e73efb65ee2e4cc7f0572b6529f72edf72..947c64d3e642eda1ca44ababfb0d88ebc519c50c 100644 (file)
@@ -12,3 +12,51 @@ v_add_i32 v256, v0, v1
 
 v_add_i32 v257, v0, v1
 // CHECK: error: invalid operand for instruction
 
 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
index 9b8471b19d29a4d66d88225bf50bb487b2d1bdf4..56841914c6f0f1a38c9e8761da1e678d06590ddf 100644 (file)
@@ -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[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[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[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]
 
 s_dcache_inv
 // GCN: s_dcache_inv ; encoding: [0x00,0x00,0xc0,0xc7]
 
index a99bc9ab1cd642c51b71dc4f0d47b6f8c3e3b17c..5f63f9930747dc61e3d2edc89bf781ccd8cdbe81 100644 (file)
@@ -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[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]
 
 s_cmov_b32 s1, 200
 // CHECK: s_cmov_b32 s1, 0xc8 ; encoding: [0xff,0x05,0x81,0xbe,0xc8,0x00,0x00,0x00]