[llvm] r316654 - [mips] Fix PR35071

Simon Dardis via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 26 03:58:36 PDT 2017


Author: sdardis
Date: Thu Oct 26 03:58:36 2017
New Revision: 316654

URL: http://llvm.org/viewvc/llvm-project?rev=316654&view=rev
Log:
[mips] Fix PR35071

PR35071 exposed the fact that MipsInstrInfo::removeBranch did not walk past
debug instructions when removing branches for the control flow optimizer, which
lead to duplicated conditional branches. If the target of the branch was a
removable block, only the conditional branch in the terminating position would
have it's MBB operands updated, leaving the first branch with a dangling MBB
operand. The MIPS long branch pass would then trigger an assertion when
attempting to examine the instruction with dangling MBB operand.

This resolves PR35071.

Thanks to Alex Richardson for reporting the issue!

Reviewers: atanasyan

Differential Revision: https://reviews.llvm.org/D39288

Added:
    llvm/trunk/test/CodeGen/Mips/pr35071.ll
Modified:
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=316654&r1=316653&r2=316654&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Thu Oct 26 03:58:36 2017
@@ -157,24 +157,23 @@ unsigned MipsInstrInfo::removeBranch(Mac
   assert(!BytesRemoved && "code size not handled");
 
   MachineBasicBlock::reverse_iterator I = MBB.rbegin(), REnd = MBB.rend();
-  unsigned removed;
-
-  // Skip all the debug instructions.
-  while (I != REnd && I->isDebugValue())
-    ++I;
-
-  if (I == REnd)
-    return 0;
-
-  MachineBasicBlock::iterator FirstBr = ++I.getReverse();
+  unsigned removed = 0;
 
   // Up to 2 branches are removed.
   // Note that indirect branches are not removed.
-  for (removed = 0; I != REnd && removed < 2; ++I, ++removed)
+  while (I != REnd && removed < 2) {
+    // Skip past debug instructions.
+    if (I->isDebugValue()) {
+      ++I;
+      continue;
+    }
     if (!getAnalyzableBrOpc(I->getOpcode()))
       break;
-
-  MBB.erase((--I).getReverse(), FirstBr);
+    // Remove the branch.
+    I->eraseFromParent();
+    I = MBB.rbegin();
+    ++removed;
+  }
 
   return removed;
 }

Added: llvm/trunk/test/CodeGen/Mips/pr35071.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/pr35071.ll?rev=316654&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/pr35071.ll (added)
+++ llvm/trunk/test/CodeGen/Mips/pr35071.ll Thu Oct 26 03:58:36 2017
@@ -0,0 +1,73 @@
+; RUN: llc -mtriple mips64-unknown-freebsd12.0 -relocation-model pic -mcpu=mips4 -target-abi n64 -O2 -o - %s
+
+; Test that the long branch pass does not crash due to the control flow
+; optimizer producing malformed basic block operands due to the backend
+; failing to handle debug information around branch instructions.
+
+define void @f() !dbg !5 {
+entry:
+  %cmp = icmp eq i32 undef, 0, !dbg !16
+  %conv = zext i1 %cmp to i32, !dbg !16
+  tail call void @llvm.dbg.value(metadata i32 %conv, metadata !11, metadata !DIExpression()), !dbg !17
+  %tobool = icmp eq i32 undef, 0, !dbg !18
+  br i1 %tobool, label %if.end, label %cleanup7.critedge, !dbg !21
+
+if.end:                                           ; preds = %entry
+  %call6 = call i32 bitcast (i32 (...)* @j to i32 (i32)*)(i32 signext %conv)
+#4, !dbg !22
+  br label %cleanup7, !dbg !23
+
+cleanup7.critedge:                                ; preds = %entry
+  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull undef) #4, !dbg !24
+  br label %cleanup7
+
+cleanup7:                                         ; preds = %cleanup7.critedge,
+  ret void
+}
+
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+declare i32 @j(...)
+
+declare void @llvm.dbg.value(metadata, metadata, metadata) #3
+attributes #1 = { argmemonly nounwind }
+attributes #3 = { nounwind readnone speculatable }
+attributes #4 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang
+version 6.0.0", isOptimized: true, runtimeVersion:
+0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename:
+"/tmp//<stdin>", directory:
+"/tmp/")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 7, !"PIC Level", i32 2}
+!5 = distinct !DISubprogram(name: "f", scope: !6, file: !6, line: 8, type: !7,
+isLocal: false, isDefinition: true, scopeLine: 8, isOptimized: true, unit: !0,
+variables: !10)
+!6 = !DIFile(filename:
+"/tmp/test.c",
+directory: "/tmp")
+!7 = !DISubroutineType(types: !8)
+!8 = !{!9}
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{!11, !12, !14}
+!11 = !DILocalVariable(name: "e", scope: !5, file: !6, line: 9, type: !9)
+!12 = !DILocalVariable(name: "g", scope: !13, file: !6, line: 11, type: !9)
+!13 = distinct !DILexicalBlock(scope: !5, file: !6, line: 10, column: 3)
+!14 = !DILocalVariable(name: "d", scope: !13, file: !6, line: 12, type: !15)
+!15 = !DIDerivedType(tag: DW_TAG_typedef, name: "a", file: !6, line: 2,
+baseType: !9)
+!16 = !DILocation(line: 9, column: 15, scope: !5)
+!17 = !DILocation(line: 9, column: 7, scope: !5)
+!18 = !DILocation(line: 12, column: 5, scope: !19)
+!19 = distinct !DILexicalBlock(scope: !20, file: !6, line: 12, column: 5)
+!20 = distinct !DILexicalBlock(scope: !5, file: !6, line: 10, column: 3)
+!21 = !DILocation(line: 12, column: 5, scope: !20)
+!22 = !DILocation(line: 16, column: 3, scope: !5)
+!23 = !DILocation(line: 17, column: 1, scope: !5)
+!24 = !DILocation(line: 15, column: 3, scope: !5)




More information about the llvm-commits mailing list