summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll')
-rw-r--r--llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll470
1 files changed, 0 insertions, 470 deletions
diff --git a/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll b/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
deleted file mode 100644
index f2e0114a2a3..00000000000
--- a/llvm/test/Transforms/SimplifyCFG/empty-cleanuppad.ll
+++ /dev/null
@@ -1,470 +0,0 @@
-; RUN: opt < %s -simplifycfg -S | FileCheck %s
-
-; ModuleID = 'cppeh-simplify.cpp'
-target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc18.0.0"
-
-
-; This case arises when two objects with empty destructors are cleaned up.
-;
-; void f1() {
-; S a;
-; S b;
-; g();
-; }
-;
-; In this case, both cleanup pads can be eliminated and the invoke can be
-; converted to a call.
-;
-; CHECK: define void @f1()
-; CHECK: entry:
-; CHECK: call void @g()
-; CHECK: ret void
-; CHECK-NOT: cleanuppad
-; CHECK: }
-;
-define void @f1() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @g() to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- ret void
-
-ehcleanup: ; preds = %entry
- %0 = cleanuppad within none []
- cleanupret from %0 unwind label %ehcleanup.1
-
-ehcleanup.1: ; preds = %ehcleanup
- %1 = cleanuppad within none []
- cleanupret from %1 unwind to caller
-}
-
-
-; This case arises when an object with an empty destructor must be cleaned up
-; outside of a try-block and an object with a non-empty destructor must be
-; cleaned up within the try-block.
-;
-; void f2() {
-; S a;
-; try {
-; S2 b;
-; g();
-; } catch (...) {}
-; }
-;
-; In this case, the outermost cleanup pad can be eliminated and the catch block
-; should unwind to the caller (that is, exception handling continues with the
-; parent frame of the caller).
-;
-; CHECK: define void @f2()
-; CHECK: entry:
-; CHECK: invoke void @g()
-; CHECK: ehcleanup:
-; CHECK: cleanuppad within none
-; CHECK: call void @"\01??1S2@@QEAA@XZ"(%struct.S2* %b)
-; CHECK: cleanupret from %0 unwind label %catch.dispatch
-; CHECK: catch.dispatch:
-; CHECK: catchswitch within none [label %catch] unwind to caller
-; CHECK: catch:
-; CHECK: catchpad
-; CHECK: catchret
-; CHECK-NOT: cleanuppad
-; CHECK: }
-;
-define void @f2() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- %b = alloca %struct.S2, align 1
- invoke void @g() to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- br label %try.cont
-
-ehcleanup: ; preds = %entry
- %0 = cleanuppad within none []
- call void @"\01??1S2@@QEAA@XZ"(%struct.S2* %b)
- cleanupret from %0 unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %ehcleanup
- %cs1 = catchswitch within none [label %catch] unwind label %ehcleanup.1
-
-catch: ; preds = %catch.dispatch
- %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- catchret from %1 to label %catchret.dest
-
-catchret.dest: ; preds = %catch
- br label %try.cont
-
-try.cont: ; preds = %catchret.dest, %invoke.cont
- ret void
-
-ehcleanup.1:
- %2 = cleanuppad within none []
- cleanupret from %2 unwind to caller
-}
-
-
-; This case arises when an object with a non-empty destructor must be cleaned up
-; outside of a try-block and an object with an empty destructor must be cleaned
-; within the try-block.
-;
-; void f3() {
-; S2 a;
-; try {
-; S b;
-; g();
-; } catch (...) {}
-; }
-;
-; In this case the inner cleanup pad should be eliminated and the invoke of g()
-; should unwind directly to the catchpad.
-;
-; CHECK-LABEL: define void @f3()
-; CHECK: entry:
-; CHECK: invoke void @g()
-; CHECK: to label %try.cont unwind label %catch.dispatch
-; CHECK: catch.dispatch:
-; CHECK-NEXT: catchswitch within none [label %catch] unwind label %ehcleanup.1
-; CHECK: catch:
-; CHECK: catchpad within %cs1 [i8* null, i32 64, i8* null]
-; CHECK: catchret
-; CHECK: ehcleanup.1:
-; CHECK: cleanuppad
-; CHECK: call void @"\01??1S2@@QEAA@XZ"(%struct.S2* %a)
-; CHECK: cleanupret from %cp3 unwind to caller
-; CHECK: }
-;
-define void @f3() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- %a = alloca %struct.S2, align 1
- invoke void @g() to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- br label %try.cont
-
-ehcleanup: ; preds = %entry
- %0 = cleanuppad within none []
- cleanupret from %0 unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %ehcleanup
- %cs1 = catchswitch within none [label %catch] unwind label %ehcleanup.1
-
-catch: ; preds = %catch.dispatch
- %cp2 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- catchret from %cp2 to label %catchret.dest
-
-catchret.dest: ; preds = %catch
- br label %try.cont
-
-try.cont: ; preds = %catchret.dest, %invoke.cont
- ret void
-
-ehcleanup.1:
- %cp3 = cleanuppad within none []
- call void @"\01??1S2@@QEAA@XZ"(%struct.S2* %a)
- cleanupret from %cp3 unwind to caller
-}
-
-
-; This case arises when an object with an empty destructor may require cleanup
-; from either inside or outside of a try-block.
-;
-; void f4() {
-; S a;
-; g();
-; try {
-; g();
-; } catch (...) {}
-; }
-;
-; In this case, the cleanuppad should be eliminated, the invoke outside of the
-; catch block should be converted to a call (that is, that is, exception
-; handling continues with the parent frame of the caller).)
-;
-; CHECK-LABEL: define void @f4()
-; CHECK: entry:
-; CHECK: call void @g
-; Note: The cleanuppad simplification will insert an unconditional branch here
-; but it will be eliminated, placing the following invoke in the entry BB.
-; CHECK: invoke void @g()
-; CHECK: to label %try.cont unwind label %catch.dispatch
-; CHECK: catch.dispatch:
-; CHECK: catchswitch within none [label %catch] unwind to caller
-; CHECK: catch:
-; CHECK: catchpad
-; CHECK: catchret
-; CHECK-NOT: cleanuppad
-; CHECK: }
-;
-define void @f4() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @g()
- to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- invoke void @g()
- to label %try.cont unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %invoke.cont
- %cs1 = catchswitch within none [label %catch] unwind label %ehcleanup
-
-catch: ; preds = %catch.dispatch
- %0 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- catchret from %0 to label %try.cont
-
-try.cont: ; preds = %catch, %invoke.cont
- ret void
-
-ehcleanup:
- %cp2 = cleanuppad within none []
- cleanupret from %cp2 unwind to caller
-}
-
-; This case tests simplification of an otherwise empty cleanup pad that contains
-; a PHI node.
-;
-; int f6() {
-; int state = 1;
-; try {
-; S a;
-; g();
-; state = 2;
-; g();
-; } catch (...) {
-; return state;
-; }
-; return 0;
-; }
-;
-; In this case, the cleanup pad should be eliminated and the PHI node in the
-; cleanup pad should be sunk into the catch dispatch block.
-;
-; CHECK-LABEL: define i32 @f6()
-; CHECK: entry:
-; CHECK: invoke void @g()
-; CHECK: invoke.cont:
-; CHECK: invoke void @g()
-; CHECK-NOT: ehcleanup:
-; CHECK-NOT: cleanuppad
-; CHECK: catch.dispatch:
-; CHECK: %state.0 = phi i32 [ 2, %invoke.cont ], [ 1, %entry ]
-; CHECK: }
-define i32 @f6() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @g()
- to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- invoke void @g()
- to label %return unwind label %ehcleanup
-
-ehcleanup: ; preds = %invoke.cont, %entry
- %state.0 = phi i32 [ 2, %invoke.cont ], [ 1, %entry ]
- %0 = cleanuppad within none []
- cleanupret from %0 unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %ehcleanup
- %cs1 = catchswitch within none [label %catch] unwind to caller
-
-catch: ; preds = %catch.dispatch
- %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- catchret from %1 to label %return
-
-return: ; preds = %invoke.cont, %catch
- %retval.0 = phi i32 [ %state.0, %catch ], [ 0, %invoke.cont ]
- ret i32 %retval.0
-}
-
-; This case tests another variation of simplification of an otherwise empty
-; cleanup pad that contains a PHI node.
-;
-; int f7() {
-; int state = 1;
-; try {
-; g();
-; state = 2;
-; S a;
-; g();
-; state = 3;
-; g();
-; } catch (...) {
-; return state;
-; }
-; return 0;
-; }
-;
-; In this case, the cleanup pad should be eliminated and the PHI node in the
-; cleanup pad should be merged with the PHI node in the catch dispatch block.
-;
-; CHECK-LABEL: define i32 @f7()
-; CHECK: entry:
-; CHECK: invoke void @g()
-; CHECK: invoke.cont:
-; CHECK: invoke void @g()
-; CHECK: invoke.cont.1:
-; CHECK: invoke void @g()
-; CHECK-NOT: ehcleanup:
-; CHECK-NOT: cleanuppad
-; CHECK: catch.dispatch:
-; CHECK: %state.1 = phi i32 [ 1, %entry ], [ 3, %invoke.cont.1 ], [ 2, %invoke.cont ]
-; CHECK: }
-define i32 @f7() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @g()
- to label %invoke.cont unwind label %catch.dispatch
-
-invoke.cont: ; preds = %entry
- invoke void @g()
- to label %invoke.cont.1 unwind label %ehcleanup
-
-invoke.cont.1: ; preds = %invoke.cont
- invoke void @g()
- to label %return unwind label %ehcleanup
-
-ehcleanup: ; preds = %invoke.cont.1, %invoke.cont
- %state.0 = phi i32 [ 3, %invoke.cont.1 ], [ 2, %invoke.cont ]
- %0 = cleanuppad within none []
- cleanupret from %0 unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %ehcleanup, %entry
- %state.1 = phi i32 [ %state.0, %ehcleanup ], [ 1, %entry ]
- %cs1 = catchswitch within none [label %catch] unwind to caller
-
-catch: ; preds = %catch.dispatch
- %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- catchret from %1 to label %return
-
-return: ; preds = %invoke.cont.1, %catch
- %retval.0 = phi i32 [ %state.1, %catch ], [ 0, %invoke.cont.1 ]
- ret i32 %retval.0
-}
-
-; This case tests a scenario where an empty cleanup pad is not dominated by all
-; of the predecessors of its successor, but the successor references a PHI node
-; in the empty cleanup pad.
-;
-; Conceptually, the case being modeled is something like this:
-;
-; int f8() {
-; int x = 1;
-; try {
-; S a;
-; g();
-; x = 2;
-; retry:
-; g();
-; return
-; } catch (...) {
-; use_x(x);
-; }
-; goto retry;
-; }
-;
-; While that C++ syntax isn't legal, the IR below is.
-;
-; In this case, the PHI node that is sunk from ehcleanup to catch.dispatch
-; should have an incoming value entry for path from 'foo' that references the
-; PHI node itself.
-;
-; CHECK-LABEL: define void @f8()
-; CHECK: entry:
-; CHECK: invoke void @g()
-; CHECK: invoke.cont:
-; CHECK: invoke void @g()
-; CHECK-NOT: ehcleanup:
-; CHECK-NOT: cleanuppad
-; CHECK: catch.dispatch:
-; CHECK: %x = phi i32 [ 2, %invoke.cont ], [ 1, %entry ], [ %x, %catch.cont ]
-; CHECK: }
-define void @f8() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @g()
- to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- invoke void @g()
- to label %return unwind label %ehcleanup
-
-ehcleanup: ; preds = %invoke.cont, %entry
- %x = phi i32 [ 2, %invoke.cont ], [ 1, %entry ]
- %0 = cleanuppad within none []
- cleanupret from %0 unwind label %catch.dispatch
-
-catch.dispatch: ; preds = %ehcleanup, %catch.cont
- %cs1 = catchswitch within none [label %catch] unwind to caller
-
-catch: ; preds = %catch.dispatch
- %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
- call void @use_x(i32 %x)
- catchret from %1 to label %catch.cont
-
-catch.cont: ; preds = %catch
- invoke void @g()
- to label %return unwind label %catch.dispatch
-
-return: ; preds = %invoke.cont, %catch.cont
- ret void
-}
-; CHECK-LABEL: define i32 @f9()
-; CHECK: entry:
-; CHECK: invoke void @"\01??1S2@@QEAA@XZ"(
-; CHECK-NOT: cleanuppad
-; CHECK: catch.dispatch:
-; CHECK: }
-define i32 @f9() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
- %s = alloca i8, align 1
- call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %s)
- %bc = bitcast i8* %s to %struct.S2*
- invoke void @"\01??1S2@@QEAA@XZ"(%struct.S2* %bc)
- to label %try.cont unwind label %ehcleanup
-
-ehcleanup:
- %cleanup.pad = cleanuppad within none []
- call void @llvm.lifetime.end.p0i8(i64 1, i8* nonnull %s)
- cleanupret from %cleanup.pad unwind label %catch.dispatch
-
-catch.dispatch:
- %catch.switch = catchswitch within none [label %catch] unwind to caller
-
-catch:
- %catch.pad = catchpad within %catch.switch [i8* null, i32 0, i8* null]
- catchret from %catch.pad to label %try.cont
-
-try.cont:
- ret i32 0
-}
-
-; CHECK-LABEL: define void @f10(
-define void @f10(i32 %V) personality i32 (...)* @__CxxFrameHandler3 {
-entry:
- invoke void @g()
- to label %unreachable unwind label %cleanup
-; CHECK: call void @g()
-; CHECK-NEXT: unreachable
-
-unreachable:
- unreachable
-
-cleanup:
- %cp = cleanuppad within none []
- switch i32 %V, label %cleanupret1 [
- i32 0, label %cleanupret2
- ]
-
-cleanupret1:
- cleanupret from %cp unwind to caller
-
-cleanupret2:
- cleanupret from %cp unwind to caller
-}
-
-%struct.S = type { i8 }
-%struct.S2 = type { i8 }
-declare void @"\01??1S2@@QEAA@XZ"(%struct.S2*)
-declare void @g()
-declare void @use_x(i32 %x)
-
-declare i32 @__CxxFrameHandler3(...)
-
-declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
-declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
OpenPOWER on IntegriCloud