aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/BranchFolding.cpp17
-rw-r--r--llvm/test/CodeGen/X86/branchfolding-landingpad-cfg.mir2
-rw-r--r--llvm/test/CodeGen/X86/windows-seh-EHa-PreserveCFG.ll80
3 files changed, 99 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp
index 0801296..599b7c7 100644
--- a/llvm/lib/CodeGen/BranchFolding.cpp
+++ b/llvm/lib/CodeGen/BranchFolding.cpp
@@ -1363,6 +1363,14 @@ ReoptimizeBlock:
MachineBasicBlock *Pred = *(MBB->pred_end()-1);
Pred->ReplaceUsesOfBlockWith(MBB, &*FallThrough);
}
+ // Add rest successors of MBB to successors of FallThrough. Those
+ // successors are not directly reachable via MBB, so it should be
+ // landing-pad.
+ for (auto SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE; ++SI)
+ if (*SI != &*FallThrough && !FallThrough->isSuccessor(*SI)) {
+ assert((*SI)->isEHPad() && "Bad CFG");
+ FallThrough->copySuccessor(MBB, SI);
+ }
// If MBB was the target of a jump table, update jump tables to go to the
// fallthrough instead.
if (MachineJumpTableInfo *MJTI = MF.getJumpTableInfo())
@@ -1624,6 +1632,15 @@ ReoptimizeBlock:
} else {
DidChange = true;
PMBB->ReplaceUsesOfBlockWith(MBB, CurTBB);
+ // Add rest successors of MBB to successors of CurTBB. Those
+ // successors are not directly reachable via MBB, so it should be
+ // landing-pad.
+ for (auto SI = MBB->succ_begin(), SE = MBB->succ_end(); SI != SE;
+ ++SI)
+ if (*SI != CurTBB && !CurTBB->isSuccessor(*SI)) {
+ assert((*SI)->isEHPad() && "Bad CFG");
+ CurTBB->copySuccessor(MBB, SI);
+ }
// If this change resulted in PMBB ending in a conditional
// branch where both conditions go to the same destination,
// change this to an unconditional branch.
diff --git a/llvm/test/CodeGen/X86/branchfolding-landingpad-cfg.mir b/llvm/test/CodeGen/X86/branchfolding-landingpad-cfg.mir
index a494701..8eef545 100644
--- a/llvm/test/CodeGen/X86/branchfolding-landingpad-cfg.mir
+++ b/llvm/test/CodeGen/X86/branchfolding-landingpad-cfg.mir
@@ -9,6 +9,8 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x00000800)
+ ; CHECK-NEXT: {{ $}}
; CHECK-NEXT: RET 0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2 (machine-block-address-taken, landing-pad, ehfunclet-entry):
diff --git a/llvm/test/CodeGen/X86/windows-seh-EHa-PreserveCFG.ll b/llvm/test/CodeGen/X86/windows-seh-EHa-PreserveCFG.ll
new file mode 100644
index 0000000..38461dc
--- /dev/null
+++ b/llvm/test/CodeGen/X86/windows-seh-EHa-PreserveCFG.ll
@@ -0,0 +1,80 @@
+; RUN: llc -mtriple=x86_64-pc-windows-msvc %s
+define dso_local void @main(ptr %addr, ptr %src, ptr %dst) personality ptr @__CxxFrameHandler3 !dbg !11 {
+entry:
+ %tmp0 = load float, ptr %src
+ %src1 = getelementptr inbounds float, ptr %src, i64 1
+ %tmp1 = load float, ptr %src1
+ %src2 = getelementptr inbounds float, ptr %src, i64 2
+ %tmp2 = load float, ptr %src2
+ %src3 = getelementptr inbounds float, ptr %src, i64 3
+ %tmp3 = load float, ptr %src3
+ %src4 = getelementptr inbounds float, ptr %src, i64 4
+ %tmp4 = load float, ptr %src4
+ %src5 = getelementptr inbounds float, ptr %src, i64 5
+ %tmp5 = load float, ptr %src5
+ %src6 = getelementptr inbounds float, ptr %src, i64 6
+ %tmp6 = load float, ptr %src6
+ invoke void @foo(ptr %addr)
+ to label %scope_begin unwind label %ehcleanup1, !dbg !13
+
+scope_begin:
+ invoke void @llvm.seh.scope.begin()
+ to label %scope_end unwind label %ehcleanup, !dbg !13
+
+scope_end:
+ invoke void @llvm.seh.scope.end()
+ to label %finish unwind label %ehcleanup, !dbg !13
+
+ehcleanup:
+ %0 = cleanuppad within none [], !dbg !13
+ call void @llvm.dbg.value(metadata ptr %addr, metadata !12, metadata !DIExpression()), !dbg !13
+ call void @foo(ptr %addr) [ "funclet"(token %0) ], !dbg !13
+ cleanupret from %0 unwind label %ehcleanup1, !dbg !13
+
+ehcleanup1:
+ %1 = cleanuppad within none [], !dbg !13
+ call void @foo(ptr %addr) [ "funclet"(token %1) ], !dbg !13
+ cleanupret from %1 unwind to caller, !dbg !13
+
+finish:
+ store float %tmp0, ptr %dst
+ %dst1 = getelementptr inbounds float, ptr %dst, i64 1
+ store float %tmp1, ptr %dst1
+ %dst2 = getelementptr inbounds float, ptr %dst, i64 2
+ store float %tmp2, ptr %dst2
+ %dst3 = getelementptr inbounds float, ptr %dst, i64 3
+ store float %tmp3, ptr %dst3
+ %dst4 = getelementptr inbounds float, ptr %dst, i64 4
+ store float %tmp4, ptr %dst4
+ %dst5 = getelementptr inbounds float, ptr %dst, i64 5
+ store float %tmp5, ptr %dst5
+ %dst6 = getelementptr inbounds float, ptr %dst, i64 6
+ store float %tmp6, ptr %dst6
+ ret void
+}
+
+declare dso_local void @llvm.seh.scope.begin()
+declare dso_local void @llvm.seh.scope.end()
+declare dso_local i32 @__CxxFrameHandler3(...)
+declare dso_local void @foo(ptr %addr)
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+!llvm.dbg.cu = !{!14}
+
+!0 = !{i32 2, !"eh-asynch", i32 1}
+!1 = !{i32 2, !"CodeView", i32 1}
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !{i32 7, !"uwtable", i32 2}
+
+!4 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !4, size: 64)
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !7, !5, !5}
+!10 = !DIFile(filename: "c:/main.cpp", directory: "")
+!11 = distinct !DISubprogram(name: "main", scope: !10, file: !10, line: 5, type: !8, scopeLine: 11, unit: !14)
+!12 = !DILocalVariable(name: "addr", scope: !11, file: !10, line: 5, type: !7)
+!13 = !DILocation(line: 7, scope: !11)
+!14 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !10, isOptimized: true, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)