Fix PR 24724 - The implicit register verifier shouldn't assume certain operand
authorAlex Lorenz <arphaman@gmail.com>
Thu, 10 Sep 2015 14:04:34 +0000 (14:04 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Thu, 10 Sep 2015 14:04:34 +0000 (14:04 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247283 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MIRParser/MIParser.cpp
test/CodeGen/MIR/PowerPC/lit.local.cfg [new file with mode: 0644]
test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir [new file with mode: 0644]
test/CodeGen/MIR/X86/expected-different-implicit-operand.mir
test/CodeGen/MIR/X86/expected-different-implicit-register-flag.mir

index c09f279a25f362cff8f096a63500f7c944486506..5a8e96df7603abdcb4ffd28475d30a5eae453792 100644 (file)
@@ -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/test/CodeGen/MIR/PowerPC/lit.local.cfg b/test/CodeGen/MIR/PowerPC/lit.local.cfg
new file mode 100644 (file)
index 0000000..0913324
--- /dev/null
@@ -0,0 +1,2 @@
+if not 'PowerPC' in config.root.targets:
+    config.unsupported = True
diff --git a/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir b/test/CodeGen/MIR/PowerPC/unordered-implicit-registers.mir
new file mode 100644 (file)
index 0000000..39d14e7
--- /dev/null
@@ -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
+...
index d2c55bdc7b85ba0cf4b53ab1f686001941b2e9ba..601551a7720a56403c5a31d525bb09a019bc5f0a 100644 (file)
@@ -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:
index 6a7201193a039c86bcfff9a3285cbdadd63aa21d..6494960d3264df5dbce14436b08a54a31f956d4d 100644 (file)
@@ -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: