summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2015-09-10 14:04:34 +0000
committerAlex Lorenz <arphaman@gmail.com>2015-09-10 14:04:34 +0000
commit0153e59935cb14302e01e5546afc00a2575ecbf8 (patch)
treeaf334c15d80c3b39bf1ca1868fa1bfd90c349f08
parent3285f1b850b736f507772b64b1a16e55fe2c1afc (diff)
downloadbcm5719-llvm-0153e59935cb14302e01e5546afc00a2575ecbf8.tar.gz
bcm5719-llvm-0153e59935cb14302e01e5546afc00a2575ecbf8.zip
Fix PR 24724 - The implicit register verifier shouldn't assume certain operand
order. The implicit register verifier in the MIR parser should only check if the instruction's default implicit operands are present in the instruction. It should not check the order in which they occur. llvm-svn: 247283
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp55
-rw-r--r--llvm/test/CodeGen/MIR/PowerPC/lit.local.cfg2
-rw-r--r--llvm/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir45
-rw-r--r--llvm/test/CodeGen/MIR/X86/expected-different-implicit-operand.mir2
-rw-r--r--llvm/test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir2
5 files changed, 65 insertions, 41 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index c09f279a25f..5a8e96df760 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -724,6 +724,16 @@ static std::string getRegisterName(const TargetRegisterInfo *TRI,
return StringRef(TRI->getName(Reg)).lower();
}
+/// Return true if the parsed machine operands contain a given machine operand.
+static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand,
+ ArrayRef<ParsedMachineOperand> Operands) {
+ for (const auto &I : Operands) {
+ if (ImplicitOperand.isIdenticalTo(I.Operand))
+ return true;
+ }
+ return false;
+}
+
bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
const MCInstrDesc &MCID) {
if (MCID.isCall())
@@ -744,46 +754,13 @@ bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
const auto *TRI = MF.getSubtarget().getRegisterInfo();
assert(TRI && "Expected target register info");
- size_t I = ImplicitOperands.size(), J = Operands.size();
- while (I) {
- --I;
- if (J) {
- --J;
- const auto &ImplicitOperand = ImplicitOperands[I];
- const auto &Operand = Operands[J].Operand;
- if (ImplicitOperand.isIdenticalTo(Operand))
- continue;
- if (Operand.isReg() && Operand.isImplicit()) {
- // Check if this implicit register is a subregister of an explicit
- // register operand.
- bool IsImplicitSubRegister = false;
- for (size_t K = 0, E = Operands.size(); K < E; ++K) {
- const auto &Op = Operands[K].Operand;
- if (Op.isReg() && !Op.isImplicit() &&
- TRI->isSubRegister(Op.getReg(), Operand.getReg())) {
- IsImplicitSubRegister = true;
- break;
- }
- }
- if (IsImplicitSubRegister)
- continue;
- return error(Operands[J].Begin,
- Twine("expected an implicit register operand '") +
- printImplicitRegisterFlag(ImplicitOperand) + " %" +
- getRegisterName(TRI, ImplicitOperand.getReg()) + "'");
- }
- }
- // TODO: Fix source location when Operands[J].end is right before '=', i.e:
- // insead of reporting an error at this location:
- // %eax = MOV32r0
- // ^
- // report the error at the following location:
- // %eax = MOV32r0
- // ^
- return error(J < Operands.size() ? Operands[J].End : Token.location(),
+ for (const auto &I : ImplicitOperands) {
+ if (isImplicitOperandIn(I, Operands))
+ continue;
+ return error(Operands.empty() ? Token.location() : Operands.back().End,
Twine("missing implicit register operand '") +
- printImplicitRegisterFlag(ImplicitOperands[I]) + " %" +
- getRegisterName(TRI, ImplicitOperands[I].getReg()) + "'");
+ printImplicitRegisterFlag(I) + " %" +
+ getRegisterName(TRI, I.getReg()) + "'");
}
return false;
}
diff --git a/llvm/test/CodeGen/MIR/PowerPC/lit.local.cfg b/llvm/test/CodeGen/MIR/PowerPC/lit.local.cfg
new file mode 100644
index 00000000000..091332439b1
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/PowerPC/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'PowerPC' in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir b/llvm/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir
new file mode 100644
index 00000000000..39d14e72ffe
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir
@@ -0,0 +1,45 @@
+# RUN: llc -mtriple=powerpc64-unknown-linux-gnu -start-after machine-combiner -stop-after machine-combiner -o /dev/null %s | FileCheck %s
+# PR24724
+
+--- |
+ define signext i32 @main(i32* %p) #0 {
+ entry:
+ %0 = load i32, i32* %p, align 4
+ %or = or i32 0, %0
+ store i32 %or, i32* %p, align 4
+ %lnot.1 = icmp eq i32 undef, 0
+ %lnot.ext.1 = zext i1 %lnot.1 to i32
+ %shr.i.1 = lshr i32 2072, %lnot.ext.1
+ %call.lobit.1 = lshr i32 %shr.i.1, 7
+ %1 = and i32 %call.lobit.1, 1
+ %or.1 = or i32 %1, %or
+ ret i32 %or.1
+ }
+
+ attributes #0 = { nounwind "target-cpu"="ppc64" }
+...
+---
+name: main
+isSSA: true
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: g8rc_and_g8rc_nox0 }
+ - { id: 1, class: gprc }
+ - { id: 2, class: gprc }
+ - { id: 3, class: gprc }
+ - { id: 4, class: g8rc }
+liveins:
+ - { reg: '%x3', virtual-reg: '%0' }
+body: |
+ bb.0.entry:
+ liveins: %x3
+
+ %0 = COPY %x3
+ %1 = LWZ 0, %0 :: (load 4 from %ir.p)
+ %2 = LI 0
+ %3 = RLWIMI %2, killed %1, 0, 0, 31
+ %4 = EXTSW_32_64 killed %3
+ %x3 = COPY %4
+ ; CHECK: BLR8 implicit %lr8, implicit %rm, implicit %x3
+ BLR8 implicit %lr8, implicit %rm, implicit %x3
+...
diff --git a/llvm/test/CodeGen/MIR/X86/expected-different-implicit-operand.mir b/llvm/test/CodeGen/MIR/X86/expected-different-implicit-operand.mir
index d2c55bdc7b8..601551a7720 100644
--- a/llvm/test/CodeGen/MIR/X86/expected-different-implicit-operand.mir
+++ b/llvm/test/CodeGen/MIR/X86/expected-different-implicit-operand.mir
@@ -23,7 +23,7 @@ body: |
bb.0.entry:
%eax = MOV32rm %rdi, 1, _, 0, _
CMP32ri8 %eax, 10, implicit-def %eflags
- ; CHECK: [[@LINE+1]]:22: expected an implicit register operand 'implicit %eflags'
+ ; CHECK: [[@LINE+1]]:35: missing implicit register operand 'implicit %eflags'
JG_1 %bb.2.exit, implicit %eax
bb.1.less:
diff --git a/llvm/test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir b/llvm/test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir
index 6a7201193a0..6494960d326 100644
--- a/llvm/test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir
+++ b/llvm/test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir
@@ -23,7 +23,7 @@ body: |
bb.0.entry:
%eax = MOV32rm %rdi, 1, _, 0, _
CMP32ri8 %eax, 10, implicit-def %eflags
- ; CHECK: [[@LINE+1]]:22: expected an implicit register operand 'implicit %eflags'
+ ; CHECK: [[@LINE+1]]:42: missing implicit register operand 'implicit %eflags'
JG_1 %bb.2.exit, implicit-def %eflags
bb.1.less:
OpenPOWER on IntegriCloud