[WinEH] Set NoModuleLevelChanges in clone flags
authorJoseph Tremoulet <jotrem@microsoft.com>
Wed, 7 Oct 2015 19:29:56 +0000 (19:29 +0000)
committerJoseph Tremoulet <jotrem@microsoft.com>
Wed, 7 Oct 2015 19:29:56 +0000 (19:29 +0000)
Summary:
This is necessary to keep the cloner from making bogus copies of debug
metadata attached to the IR it is cloning.
Also, avoid running RemapInstruction over all instructions in the common
case that no cloning was performed.

Reviewers: rnk, andrew.w.kaylor, majnemer

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13514

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

lib/CodeGen/WinEHPrepare.cpp
test/CodeGen/WinEH/wineh-cloning.ll

index 3f930c892e2874ede5e3215becf6aa437cb0bae2..ddbe000241126041b5c083da21cd258c531146dd 100644 (file)
@@ -3222,6 +3222,10 @@ void WinEHPrepare::cloneCommonBlocks(
       Orig2Clone[BB] = CBB;
     }
 
+    // If nothing was cloned, we're done cloning in this funclet.
+    if (Orig2Clone.empty())
+      continue;
+
     // Update our color mappings to reflect that one block has lost a color and
     // another has gained a color.
     for (auto &BBMapping : Orig2Clone) {
@@ -3235,12 +3239,13 @@ void WinEHPrepare::cloneCommonBlocks(
       BlockColors[OldBlock].erase(FuncletPadBB);
     }
 
-    // Loop over all of the instructions in the function, fixing up operand
+    // Loop over all of the instructions in this funclet, fixing up operand
     // references as we go.  This uses VMap to do all the hard work.
     for (BasicBlock *BB : BlocksInFunclet)
       // Loop over all instructions, fixing each one as we find it...
       for (Instruction &I : *BB)
-        RemapInstruction(&I, VMap, RF_IgnoreMissingEntries);
+        RemapInstruction(&I, VMap,
+                         RF_IgnoreMissingEntries | RF_NoModuleLevelChanges);
 
     // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
     // the PHI nodes for NewBB now.
index 1ed71ef8375e7f37ed6116dd5b75411f3b179e29..72bbeaf55f728774684688b16ebc21df8185b577 100644 (file)
@@ -452,3 +452,44 @@ exit:
 ; CHECK:      %inner = cleanuppad []
 ; CHECK-NEXT: call void @f()
 ; CHECK-NEXT: unreachable
+
+define void @test12() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @f()
+    to label %cont unwind label %left, !dbg !8
+cont:
+  invoke void @f()
+    to label %exit unwind label %right
+left:
+  cleanuppad []
+  br label %join
+right:
+  cleanuppad []
+  br label %join
+join:
+  ; This call will get cloned; make sure we can handle cloning
+  ; instructions with debug metadata attached.
+  call void @f(), !dbg !9
+  unreachable
+exit:
+  ret void
+}
+
+; Make sure the DISubprogram doesn't get cloned
+; CHECK-LABEL: !llvm.module.flags
+; CHECK-NOT: !DISubprogram
+; CHECK: !{{[0-9]+}} = distinct !DISubprogram(name: "test12"
+; CHECK-NOT: !DISubprogram
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "compiler", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !3, subprograms: !4)
+!2 = !DIFile(filename: "test.cpp", directory: ".")
+!3 = !{}
+!4 = !{!5}
+!5 = distinct !DISubprogram(name: "test12", scope: !2, file: !2, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, function: void ()* @test12, variables: !3)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !DILocation(line: 1, scope: !5)
+!9 = !DILocation(line: 2, scope: !5)