llvm.org GIT mirror llvm / 9d48a0d
[ARM] Fix detection of duplicates when parsing reg list operands Differential Revision: https://reviews.llvm.org/D65957 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368712 91177308-0d34-0410-b5e6-96231b3b80d8 Momchil Velikov 11 months ago
2 changed file(s) with 109 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
35583558 Kind = k_SPRRegisterList;
35593559 }
35603560
3561 // Sort based on the register encoding values.
3562 array_pod_sort(Regs.begin(), Regs.end());
3563
35643561 if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
35653562 Kind = k_RegisterListWithAPSR;
35663563
3564 assert(std::is_sorted(Regs.begin(), Regs.end()) &&
3565 "Register list must be sorted by encoding");
3566
35673567 auto Op = make_unique(Kind);
3568 for (SmallVectorImpl>::const_iterator
3569 I = Regs.begin(), E = Regs.end(); I != E; ++I)
3570 Op->Registers.push_back(I->second);
3568 for (const auto &P : Regs)
3569 Op->Registers.push_back(P.second);
35713570
35723571 Op->StartLoc = StartLoc;
35733572 Op->EndLoc = EndLoc;
42684267 }
42694268 }
42704269
4270 // Insert an pair in an ordered vector. Return true on
4271 // success, or false, if duplicate encoding found.
4272 static bool
4273 insertNoDuplicates(SmallVectorImpl> &Regs,
4274 unsigned Enc, unsigned Reg) {
4275 Regs.emplace_back(Enc, Reg);
4276 for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
4277 if (J->first == Enc) {
4278 Regs.erase(J.base());
4279 return false;
4280 }
4281 if (J->first < Enc)
4282 break;
4283 std::swap(*I, *J);
4284 }
4285 return true;
4286 }
4287
42714288 /// Parse a register list.
42724289 bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
42734290 bool EnforceOrder) {
42934310 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
42944311 Reg = getDRegFromQReg(Reg);
42954312 EReg = MRI->getEncodingValue(Reg);
4296 Registers.push_back(std::pair(EReg, Reg));
4313 Registers.emplace_back(EReg, Reg);
42974314 ++Reg;
42984315 }
42994316 const MCRegisterClass *RC;
43104327
43114328 // Store the register.
43124329 EReg = MRI->getEncodingValue(Reg);
4313 Registers.push_back(std::pair(EReg, Reg));
4330 Registers.emplace_back(EReg, Reg);
43144331
43154332 // This starts immediately after the first register token in the list,
43164333 // so we can see either a comma or a minus (range separator) as a legal
43414358 while (Reg != EndReg) {
43424359 Reg = getNextRegister(Reg);
43434360 EReg = MRI->getEncodingValue(Reg);
4344 Registers.push_back(std::pair(EReg, Reg));
4361 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4362 Warning(AfterMinusLoc, StringRef("duplicated register (") +
4363 ARMInstPrinter::getRegisterName(Reg) +
4364 ") in register list");
4365 }
43454366 }
43464367 continue;
43474368 }
43654386 // subset of GPRRegClassId except it contains APSR as well.
43664387 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
43674388 }
4368 if (Reg == ARM::VPR && (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4369 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID])) {
4389 if (Reg == ARM::VPR &&
4390 (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
4391 RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
4392 RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
43704393 RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
43714394 EReg = MRI->getEncodingValue(Reg);
4372 Registers.push_back(std::pair(EReg, Reg));
4395 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4396 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4397 ") in register list");
4398 }
43734399 continue;
43744400 }
43754401 // The register must be in the same register class as the first.
43864412 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
43874413 return Error(RegLoc, "register list not in ascending order");
43884414 }
4389 if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
4390 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4391 ") in register list");
4392 continue;
4393 }
43944415 // VFP register lists must also be contiguous.
43954416 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
43964417 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
43974418 Reg != OldReg + 1)
43984419 return Error(RegLoc, "non-contiguous register range");
43994420 EReg = MRI->getEncodingValue(Reg);
4400 Registers.push_back(std::pair(EReg, Reg));
4421 if (!insertNoDuplicates(Registers, EReg, Reg)) {
4422 Warning(RegLoc, "duplicated register (" + RegTok.getString() +
4423 ") in register list");
4424 }
44014425 if (isQReg) {
44024426 EReg = MRI->getEncodingValue(++Reg);
4403 Registers.push_back(std::pair(EReg, Reg));
4427 Registers.emplace_back(EReg, Reg);
44044428 }
44054429 }
44064430
0 // RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -show-encoding < %s 2>&1 | FileCheck -strict-whitespace %s
1
2 clrm {r0, r0}
3 // CHECK: warning: duplicated register (r0) in register list
4 // CHECK-NEXT: {{^clrm {r0, r0}}}
5 // CHECK-NEXT: {{^ \^}}
6
7 clrm {r0, r0, r1}
8 // CHECK: warning: duplicated register (r0) in register list
9 // CHECK-NEXT: {{^clrm {r0, r0, r1}}}
10 // CHECK-NEXT: {{^ \^}}
11
12 clrm {r0, r1, r0}
13 // CHECK: warning: duplicated register (r0) in register list
14 // CHECK-NEXT: {{^clrm {r0, r1, r0}}}
15 // CHECK-NEXT: {{^ \^}}
16
17 clrm {r0, r1, r1}
18 // CHECK: warning: duplicated register (r1) in register list
19 // CHECK-NEXT: {{^clrm {r0, r1, r1}}}
20 // CHECK-NEXT: {{^ \^}}
21
22 clrm {r1, r0, r1}
23 // CHECK: warning: duplicated register (r1) in register list
24 // CHECK-NEXT: {{^clrm {r1, r0, r1}}}
25 // CHECK-NEXT: {{^ \^}}
26
27 clrm {r1, r1, r0}
28 // CHECK: warning: duplicated register (r1) in register list
29 // CHECK-NEXT: {{^clrm {r1, r1, r0}}}
30 // CHECK-NEXT: {{^ \^}}
31
32 clrm {r0-r3, r0}
33 // CHECK: warning: duplicated register (r0) in register list
34 // CHECK-NEXT: {{^clrm {r0-r3, r0}}}
35 // CHECK-NEXT: {{^ \^}}
36
37 clrm {r2, r0-r3}
38 // CHECK: warning: duplicated register (r2) in register list
39 // CHECK-NEXT: {{^clrm {r2, r0-r3}}}
40 // CHECK-NEXT: {{^ \^}}
41
42 vscclrm {s0, s0, s1, vpr}
43 // CHECK: error: non-contiguous register range
44 // CHECK: {{^vscclrm {s0, s0, s1, vpr}}}
45 // CHECK: {{^ \^}}
46
47 vscclrm {s0-s3, vpr, s4}
48 // CHECK: error: register list not in ascending order
49 // CHECK-NEXT: {{^vscclrm {s0-s3, vpr, s4}}}
50 // CHECK-NEXT: {{^ \^}}
51
52 vscclrm {s0-s3, vpr, vpr}
53 // CHECK: warning: duplicated register (vpr) in register list
54 // CHECK-NEXT: {{^vscclrm {s0-s3, vpr, vpr}}}
55 // CHECK-NEXT: {{^ \^}}
56
57 vscclrm {q2, d4, vpr}
58 // CHECK: error: register list not in ascending order
59 // CHECK-NEXT: {{^vscclrm {q2, d4, vpr}}}
60 // CHECK-NEXT: {{^ \^}}
61
62 vscclrm {q2, d5, vpr}
63 // CHECK: error: non-contiguous register range
64 // CHECK-NEXT: {{^vscclrm {q2, d5, vpr}}}
65 // CHECK-NEXT: {{^ \^}}