[llvm] r368712 - [ARM] Fix detection of duplicates when parsing reg list operands
Momchil Velikov via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 13 09:13:00 PDT 2019
Author: chill
Date: Tue Aug 13 09:13:00 2019
New Revision: 368712
URL: http://llvm.org/viewvc/llvm-project?rev=368712&view=rev
Log:
[ARM] Fix detection of duplicates when parsing reg list operands
Differential Revision: https://reviews.llvm.org/D65957
Added:
llvm/trunk/test/MC/ARM/register-list-dup.s
Modified:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=368712&r1=368711&r2=368712&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Aug 13 09:13:00 2019
@@ -3559,16 +3559,15 @@ public:
Kind = k_SPRRegisterList;
}
- // Sort based on the register encoding values.
- array_pod_sort(Regs.begin(), Regs.end());
-
if (Kind == k_RegisterList && Regs.back().second == ARM::APSR)
Kind = k_RegisterListWithAPSR;
+ assert(std::is_sorted(Regs.begin(), Regs.end()) &&
+ "Register list must be sorted by encoding");
+
auto Op = make_unique<ARMOperand>(Kind);
- for (SmallVectorImpl<std::pair<unsigned, unsigned>>::const_iterator
- I = Regs.begin(), E = Regs.end(); I != E; ++I)
- Op->Registers.push_back(I->second);
+ for (const auto &P : Regs)
+ Op->Registers.push_back(P.second);
Op->StartLoc = StartLoc;
Op->EndLoc = EndLoc;
@@ -4269,6 +4268,24 @@ static unsigned getNextRegister(unsigned
}
}
+// Insert an <Encoding, Register> pair in an ordered vector. Return true on
+// success, or false, if duplicate encoding found.
+static bool
+insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, unsigned>> &Regs,
+ unsigned Enc, unsigned Reg) {
+ Regs.emplace_back(Enc, Reg);
+ for (auto I = Regs.rbegin(), J = I + 1, E = Regs.rend(); J != E; ++I, ++J) {
+ if (J->first == Enc) {
+ Regs.erase(J.base());
+ return false;
+ }
+ if (J->first < Enc)
+ break;
+ std::swap(*I, *J);
+ }
+ return true;
+}
+
/// Parse a register list.
bool ARMAsmParser::parseRegisterList(OperandVector &Operands,
bool EnforceOrder) {
@@ -4294,7 +4311,7 @@ bool ARMAsmParser::parseRegisterList(Ope
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
Reg = getDRegFromQReg(Reg);
EReg = MRI->getEncodingValue(Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ Registers.emplace_back(EReg, Reg);
++Reg;
}
const MCRegisterClass *RC;
@@ -4311,7 +4328,7 @@ bool ARMAsmParser::parseRegisterList(Ope
// Store the register.
EReg = MRI->getEncodingValue(Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ Registers.emplace_back(EReg, Reg);
// This starts immediately after the first register token in the list,
// so we can see either a comma or a minus (range separator) as a legal
@@ -4342,7 +4359,11 @@ bool ARMAsmParser::parseRegisterList(Ope
while (Reg != EndReg) {
Reg = getNextRegister(Reg);
EReg = MRI->getEncodingValue(Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
+ Warning(AfterMinusLoc, StringRef("duplicated register (") +
+ ARMInstPrinter::getRegisterName(Reg) +
+ ") in register list");
+ }
}
continue;
}
@@ -4366,11 +4387,16 @@ bool ARMAsmParser::parseRegisterList(Ope
// subset of GPRRegClassId except it contains APSR as well.
RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
}
- if (Reg == ARM::VPR && (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
- RC == &ARMMCRegisterClasses[ARM::DPRRegClassID])) {
+ if (Reg == ARM::VPR &&
+ (RC == &ARMMCRegisterClasses[ARM::SPRRegClassID] ||
+ RC == &ARMMCRegisterClasses[ARM::DPRRegClassID] ||
+ RC == &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID])) {
RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
EReg = MRI->getEncodingValue(Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
+ Warning(RegLoc, "duplicated register (" + RegTok.getString() +
+ ") in register list");
+ }
continue;
}
// The register must be in the same register class as the first.
@@ -4387,21 +4413,19 @@ bool ARMAsmParser::parseRegisterList(Ope
else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains(Reg))
return Error(RegLoc, "register list not in ascending order");
}
- if (MRI->getEncodingValue(Reg) == MRI->getEncodingValue(OldReg)) {
- Warning(RegLoc, "duplicated register (" + RegTok.getString() +
- ") in register list");
- continue;
- }
// VFP register lists must also be contiguous.
if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
Reg != OldReg + 1)
return Error(RegLoc, "non-contiguous register range");
EReg = MRI->getEncodingValue(Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ if (!insertNoDuplicates(Registers, EReg, Reg)) {
+ Warning(RegLoc, "duplicated register (" + RegTok.getString() +
+ ") in register list");
+ }
if (isQReg) {
EReg = MRI->getEncodingValue(++Reg);
- Registers.push_back(std::pair<unsigned, unsigned>(EReg, Reg));
+ Registers.emplace_back(EReg, Reg);
}
}
Added: llvm/trunk/test/MC/ARM/register-list-dup.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/register-list-dup.s?rev=368712&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/register-list-dup.s (added)
+++ llvm/trunk/test/MC/ARM/register-list-dup.s Tue Aug 13 09:13:00 2019
@@ -0,0 +1,66 @@
+// RUN: not llvm-mc -triple=thumbv8.1m.main-none-eabi -show-encoding < %s 2>&1 | FileCheck -strict-whitespace %s
+
+clrm {r0, r0}
+// CHECK: warning: duplicated register (r0) in register list
+// CHECK-NEXT: {{^clrm {r0, r0}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r0, r0, r1}
+// CHECK: warning: duplicated register (r0) in register list
+// CHECK-NEXT: {{^clrm {r0, r0, r1}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r0, r1, r0}
+// CHECK: warning: duplicated register (r0) in register list
+// CHECK-NEXT: {{^clrm {r0, r1, r0}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r0, r1, r1}
+// CHECK: warning: duplicated register (r1) in register list
+// CHECK-NEXT: {{^clrm {r0, r1, r1}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r1, r0, r1}
+// CHECK: warning: duplicated register (r1) in register list
+// CHECK-NEXT: {{^clrm {r1, r0, r1}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r1, r1, r0}
+// CHECK: warning: duplicated register (r1) in register list
+// CHECK-NEXT: {{^clrm {r1, r1, r0}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r0-r3, r0}
+// CHECK: warning: duplicated register (r0) in register list
+// CHECK-NEXT: {{^clrm {r0-r3, r0}}}
+// CHECK-NEXT: {{^ \^}}
+
+clrm {r2, r0-r3}
+// CHECK: warning: duplicated register (r2) in register list
+// CHECK-NEXT: {{^clrm {r2, r0-r3}}}
+// CHECK-NEXT: {{^ \^}}
+
+vscclrm {s0, s0, s1, vpr}
+// CHECK: error: non-contiguous register range
+// CHECK: {{^vscclrm {s0, s0, s1, vpr}}}
+// CHECK: {{^ \^}}
+
+vscclrm {s0-s3, vpr, s4}
+// CHECK: error: register list not in ascending order
+// CHECK-NEXT: {{^vscclrm {s0-s3, vpr, s4}}}
+// CHECK-NEXT: {{^ \^}}
+
+vscclrm {s0-s3, vpr, vpr}
+// CHECK: warning: duplicated register (vpr) in register list
+// CHECK-NEXT: {{^vscclrm {s0-s3, vpr, vpr}}}
+// CHECK-NEXT: {{^ \^}}
+
+vscclrm {q2, d4, vpr}
+// CHECK: error: register list not in ascending order
+// CHECK-NEXT: {{^vscclrm {q2, d4, vpr}}}
+// CHECK-NEXT: {{^ \^}}
+
+vscclrm {q2, d5, vpr}
+// CHECK: error: non-contiguous register range
+// CHECK-NEXT: {{^vscclrm {q2, d5, vpr}}}
+// CHECK-NEXT: {{^ \^}}
More information about the llvm-commits
mailing list