OSDN Git Service

BranchFolder: Fix invalid undef flags after merge.
authorMatthias Braun <matze@braunis.de>
Tue, 20 Sep 2016 01:14:42 +0000 (01:14 +0000)
committerMatthias Braun <matze@braunis.de>
Tue, 20 Sep 2016 01:14:42 +0000 (01:14 +0000)
It is legal to merge instructions with different undef flags; However we
must drop the undef flag from the merged instruction if it isn't present
everywhere.

This fixes http://llvm.org/PR30199

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

lib/CodeGen/BranchFolding.cpp
test/CodeGen/X86/branchfolding-undef.mir [new file with mode: 0644]

index f0c603f..ec736a0 100644 (file)
@@ -801,9 +801,8 @@ bool BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB,
 }
 
 static void
-mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
-                              MachineBasicBlock &MBBCommon) {
-  // Merge MMOs from memory operations in the common block.
+mergeOperations(MachineBasicBlock::iterator MBBIStartPos,
+                MachineBasicBlock &MBBCommon) {
   MachineBasicBlock *MBB = MBBIStartPos->getParent();
   // Note CommonTailLen does not necessarily matches the size of
   // the common BB nor all its instructions because of debug
@@ -833,8 +832,18 @@ mergeMMOsFromMemoryOperations(MachineBasicBlock::iterator MBBIStartPos,
            "Reached BB end within common tail length!");
     assert(MBBICommon->isIdenticalTo(*MBBI) && "Expected matching MIIs!");
 
+    // Merge MMOs from memory operations in the common block.
     if (MBBICommon->mayLoad() || MBBICommon->mayStore())
       MBBICommon->setMemRefs(MBBICommon->mergeMemRefsWith(*MBBI));
+    // Drop undef flags if they aren't present in all merged instructions.
+    for (unsigned I = 0, E = MBBICommon->getNumOperands(); I != E; ++I) {
+      MachineOperand &MO = MBBICommon->getOperand(I);
+      if (MO.isReg() && MO.isUndef()) {
+        const MachineOperand &OtherMO = MBBI->getOperand(I);
+        if (!OtherMO.isUndef())
+          MO.setIsUndef(false);
+      }
+    }
 
     ++MBBI;
     ++MBBICommon;
@@ -952,8 +961,8 @@ bool BranchFolder::TryTailMergeBlocks(MachineBasicBlock *SuccBB,
         continue;
       DEBUG(dbgs() << "BB#" << SameTails[i].getBlock()->getNumber()
                    << (i == e-1 ? "" : ", "));
-      // Merge MMOs from memory operations as needed.
-      mergeMMOsFromMemoryOperations(SameTails[i].getTailStartPos(), *MBB);
+      // Merge operations (MMOs, undef flags)
+      mergeOperations(SameTails[i].getTailStartPos(), *MBB);
       // Hack the end off BB i, making it jump to BB commonTailIndex instead.
       ReplaceTailWithBranchTo(SameTails[i].getTailStartPos(), MBB);
       // BB i is no longer a predecessor of SuccBB; remove it from the worklist.
diff --git a/test/CodeGen/X86/branchfolding-undef.mir b/test/CodeGen/X86/branchfolding-undef.mir
new file mode 100644 (file)
index 0000000..0da167b
--- /dev/null
@@ -0,0 +1,29 @@
+# RUN: llc -o - %s -march=x86 -run-pass branch-folder | FileCheck %s
+# Test that tail merging drops undef flags that aren't present on all
+# instructions to be merged.
+--- |
+  define void @func() { ret void }
+...
+---
+# CHECK-LABEL: name: func
+# CHECK: bb.1:
+# CHECK: %eax = MOV32ri 2
+# CHECK-NOT: RET
+# CHECK: bb.2:
+# CHECK-NOT: RET 0, undef %eax
+# CHECK: RET 0, %eax
+name: func
+tracksRegLiveness: true
+body: |
+  bb.0:
+    successors: %bb.1, %bb.2
+    JE_1 %bb.1, implicit undef %eflags
+    JMP_1 %bb.2
+
+  bb.1:
+    %eax = MOV32ri 2
+    RET 0, %eax
+
+  bb.2:
+    RET 0, undef %eax
+...