Replace llvm.frameallocate with llvm.frameescape
Turns out it's pretty straightforward and simplifies the implementation.
Reviewers: andrew.w.kaylor
Differential Revision: http://reviews.llvm.org/D8051
llvm-svn: 231386
diff --git a/llvm/test/CodeGen/WinEH/cppeh-catch-all.ll b/llvm/test/CodeGen/WinEH/cppeh-catch-all.ll
index 0958d74..d1141e3 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-catch-all.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-catch-all.ll
@@ -54,8 +54,6 @@
; CHECK: define internal i8* @_Z4testv.catch(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %struct._Z4testv.ehdata*
; CHECK: call void @_Z16handle_exceptionv()
; CHECK: ret i8* blockaddress(@_Z4testv, %try.cont)
; CHECK: }
diff --git a/llvm/test/CodeGen/WinEH/cppeh-catch-scalar.ll b/llvm/test/CodeGen/WinEH/cppeh-catch-scalar.ll
index 7ed846e..0b1d177 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-catch-scalar.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-catch-scalar.ll
@@ -18,20 +18,17 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
-; This is the structure that will get created for the frame allocation.
-; CHECK: %struct._Z4testv.ehdata = type { i32, i8*, i32 }
-
@_ZTIi = external constant i8*
; The function entry will be rewritten like this.
; CHECK: define void @_Z4testv() #0 {
; CHECK: entry:
-; CHECK: %frame.alloc = call i8* @llvm.frameallocate(i32 24)
-; CHECK: %eh.data = bitcast i8* %frame.alloc to %struct._Z4testv.ehdata*
; CHECK: %exn.slot = alloca i8*
; CHECK: %ehselector.slot = alloca i32
-; CHECK-NOT: %i = alloca i32, align 4
-; CHECK: %i = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2
+; CHECK: %i = alloca i32, align 4
+; CHECK: call void (...)* @llvm.frameescape(i32* %i)
+; CHECK: invoke void @_Z9may_throwv()
+; CHECK: to label %invoke.cont unwind label %lpad
; Function Attrs: uwtable
define void @_Z4testv() #0 {
@@ -85,9 +82,8 @@
; CHECK: define internal i8* @_Z4testv.catch(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %struct._Z4testv.ehdata*
-; CHECK: %i = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2
+; CHECK: %i.i81 = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
+; CHECK: %i = bitcast i8* %i.i81 to i32*
; CHECK: %tmp7 = load i32, i32* %i, align 4
; CHECK: call void @_Z10handle_inti(i32 %tmp7)
; CHECK: ret i8* blockaddress(@_Z4testv, %try.cont)
diff --git a/llvm/test/CodeGen/WinEH/cppeh-frame-vars.ll b/llvm/test/CodeGen/WinEH/cppeh-frame-vars.ll
index 4aafad0..3d3f5f6 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-frame-vars.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-frame-vars.ll
@@ -41,9 +41,6 @@
%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
%struct.SomeData = type { i32, i32 }
-; This structure should be declared for the frame allocation block.
-; CHECK: %"struct.\01?test@@YAXXZ.ehdata" = type { i32, i8*, i32, i32, [10 x i32], i32, %struct.SomeData }
-
$"\01??_R0H@8" = comdat any
@"\01??_7type_info@@6B@" = external constant i8*
@@ -52,19 +49,19 @@
; The function entry should be rewritten like this.
; CHECK: define void @"\01?test@@YAXXZ"() #0 {
; CHECK: entry:
-; CHECK: %frame.alloc = call i8* @llvm.frameallocate(i32 80)
-; CHECK: %eh.data = bitcast i8* %frame.alloc to %"struct.\01?test@@YAXXZ.ehdata"*
-; CHECK-NOT: %NumExceptions = alloca i32, align 4
-; CHECK: %NumExceptions = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 3
-; CHECK-NOT: %ExceptionVal = alloca [10 x i32], align 16
-; CHECK: %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
-; CHECK-NOT: %Data = alloca %struct.SomeData, align 4
-; CHECK: %Data = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6
-; CHECK: %i = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 5
+; CHECK: %NumExceptions = alloca i32, align 4
+; CHECK: %ExceptionVal = alloca [10 x i32], align 16
+; CHECK: %Data = alloca %struct.SomeData, align 4
+; CHECK: %i = alloca i32, align 4
; CHECK: %exn.slot = alloca i8*
; CHECK: %ehselector.slot = alloca i32
-; CHECK-NOT: %e = alloca i32, align 4
-; CHECK: %e = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 2
+; CHECK: %e = alloca i32, align 4
+; CHECK: store i32 0, i32* %NumExceptions, align 4
+; CHECK: %tmp = bitcast %struct.SomeData* %Data to i8*
+; CHECK: call void @llvm.memset(i8* %tmp, i8 0, i64 8, i32 4, i1 false)
+; CHECK: store i32 0, i32* %i, align 4
+; CHECK: call void (...)* @llvm.frameescape(i32* %e, i32* %NumExceptions, [10 x i32]* %ExceptionVal, i32* %i, %struct.SomeData* %Data)
+; CHECK: br label %for.cond
; Function Attrs: uwtable
define void @"\01?test@@YAXXZ"() #0 {
@@ -179,13 +176,16 @@
; The following catch handler should be outlined.
; CHECK-LABEL: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %"struct.\01?test@@YAXXZ.ehdata"*
-; CHECK: %e = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 2
-; CHECK: %NumExceptions = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 3
-; CHECK: %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
-; CHECK: %i = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 5
-; CHECK: %Data = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6
+; CHECK: %e.i81 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
+; CHECK: %e = bitcast i8* %e.i81 to i32*
+; CHECK: %NumExceptions.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
+; CHECK: %NumExceptions = bitcast i8* %NumExceptions.i8 to i32*
+; CHECK: %ExceptionVal.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
+; CHECK: %ExceptionVal = bitcast i8* %ExceptionVal.i8 to [10 x i32]*
+; CHECK: %i.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
+; CHECK: %i = bitcast i8* %i.i8 to i32*
+; CHECK: %Data.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
+; CHECK: %Data = bitcast i8* %Data.i8 to %struct.SomeData*
; CHECK: %tmp11 = load i32, i32* %e, align 4
; CHECK: %tmp12 = load i32, i32* %NumExceptions, align 4
; CHECK: %idxprom = sext i32 %tmp12 to i64
diff --git a/llvm/test/CodeGen/WinEH/cppeh-inalloca.ll b/llvm/test/CodeGen/WinEH/cppeh-inalloca.ll
index 13f3e6c..5595b0c 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-inalloca.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-inalloca.ll
@@ -38,18 +38,15 @@
; The function entry should be rewritten like this.
; CHECK: define i32 @"\01?test@@YAHUA@@@Z"(<{ %struct.A }>* inalloca) #0 {
; CHECK: entry:
-; CHECK: %frame.alloc = call i8* @llvm.frameallocate(i32 24)
-; CHECK: %eh.data = bitcast i8* %frame.alloc to %"struct.\01?test@@YAHUA@@@Z.ehdata"*
-; CHECK: %.tmp.reg2mem = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 3
+; CHECK: %.tmp.reg2mem = alloca <{ %struct.A }>*
; CHECK: %.tmp = select i1 true, <{ %struct.A }>* %0, <{ %struct.A }>* undef
; CHECK: store <{ %struct.A }>* %.tmp, <{ %struct.A }>** %.tmp.reg2mem
-; CHECK-NOT: %retval = alloca i32, align 4
-; CHECK: %retval = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 4
+; CHECK: %retval = alloca i32, align 4
; CHECK: %exn.slot = alloca i8*
; CHECK: %ehselector.slot = alloca i32
-; CHECK-NOT: %e = alloca i32, align 4
-; CHECK: %e = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 2
-; CHECK: %cleanup.dest.slot = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 5
+; CHECK: %e = alloca i32, align 4
+; CHECK: %cleanup.dest.slot = alloca i32
+; CHECK: call void (...)* @llvm.frameescape(i32* %e, <{ %struct.A }>** %.tmp.reg2mem, i32* %retval, i32* %cleanup.dest.slot)
; CHECK: invoke void @"\01?may_throw@@YAXXZ"()
; CHECK: to label %invoke.cont unwind label %lpad
@@ -132,13 +129,16 @@
; The following catch handler should be outlined.
; CHECK: define internal i8* @"\01?test@@YAHUA@@@Z.catch"(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %"struct.\01?test@@YAHUA@@@Z.ehdata"*
-; CHECK: %e = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 2
-; CHECK: %eh.temp.alloca = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 3
+; CHECK: %e.i81 = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 0)
+; CHECK: %e = bitcast i8* %e.i81 to i32*
+; CHECK: %eh.temp.alloca.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 1)
+; CHECK: %eh.temp.alloca = bitcast i8* %eh.temp.alloca.i8 to <{ %struct.A }>**
; CHECK: %.reload = load <{ %struct.A }>*, <{ %struct.A }>** %eh.temp.alloca
-; CHECK: %retval = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 4
-; CHECK: %cleanup.dest.slot = getelementptr inbounds %"struct.\01?test@@YAHUA@@@Z.ehdata", %"struct.\01?test@@YAHUA@@@Z.ehdata"* %eh.data, i32 0, i32 5
+; CHECK: %retval.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 2)
+; CHECK: %retval = bitcast i8* %retval.i8 to i32*
+; CHECK: %cleanup.dest.slot.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 (<{ %struct.A }>*)* @"\01?test@@YAHUA@@@Z" to i8*), i8* %1, i32 3)
+; CHECK: %cleanup.dest.slot = bitcast i8* %cleanup.dest.slot.i8 to i32*
+; CHECK: %e.i8 = bitcast i32* %e to i8*
; CHECK: %a = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %.reload, i32 0, i32 0
; CHECK: %a1 = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
; CHECK: %tmp8 = load i32, i32* %a1, align 4
@@ -149,7 +149,6 @@
; CHECK: ret i8* blockaddress(@"\01?test@@YAHUA@@@Z", %cleanup)
; CHECK: }
-
declare void @"\01?may_throw@@YAXXZ"() #0
declare i32 @__CxxFrameHandler3(...)
diff --git a/llvm/test/CodeGen/WinEH/cppeh-min-unwind.ll b/llvm/test/CodeGen/WinEH/cppeh-min-unwind.ll
index a7b9738..abdbc382 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-min-unwind.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-min-unwind.ll
@@ -18,18 +18,16 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
-; This structure should be created for the frame allocation.
-; CHECK: %struct._Z4testv.ehdata = type { i32, i8*, %class.SomeClass }
-
%class.SomeClass = type { [28 x i32] }
; The function entry should be rewritten like this.
; CHECK: define void @_Z4testv() #0 {
; CHECK: entry:
-; CHECK: %frame.alloc = call i8* @llvm.frameallocate(i32 128)
-; CHECK: %eh.data = bitcast i8* %frame.alloc to %struct._Z4testv.ehdata*
-; CHECK-NOT: %obj = alloca %class.SomeClass, align 4
-; CHECK: %obj = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2
+; CHECK: %obj = alloca %class.SomeClass, align 4
+; CHECK: call void @_ZN9SomeClassC1Ev(%class.SomeClass* %obj)
+; CHECK: call void (...)* @llvm.frameescape(%class.SomeClass* %obj)
+; CHECK: invoke void @_Z9may_throwv()
+; CHECK: to label %invoke.cont unwind label %lpad
; Function Attrs: uwtable
define void @_Z4testv() #0 {
@@ -66,9 +64,8 @@
; This cleanup handler should be outlined.
; CHECK: define internal void @_Z4testv.cleanup(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %struct._Z4testv.ehdata*
-; CHECK: %obj = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2
+; CHECK: %obj.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @_Z4testv to i8*), i8* %1, i32 0)
+; CHECK: %obj = bitcast i8* %obj.i8 to %class.SomeClass*
; CHECK: call void @_ZN9SomeClassD1Ev(%class.SomeClass* %obj)
; CHECK: ret void
; CHECK: }
diff --git a/llvm/test/CodeGen/WinEH/cppeh-nonalloca-frame-values.ll b/llvm/test/CodeGen/WinEH/cppeh-nonalloca-frame-values.ll
index 354f409..0fa0fd0 100644
--- a/llvm/test/CodeGen/WinEH/cppeh-nonalloca-frame-values.ll
+++ b/llvm/test/CodeGen/WinEH/cppeh-nonalloca-frame-values.ll
@@ -50,32 +50,28 @@
@"\01??_7type_info@@6B@" = external constant i8*
@"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
-; This structure should be declared for the frame allocation block.
-; CHECK: %"struct.\01?test@@YAXXZ.ehdata" = type { i32, i8*, i32, i32, [10 x i32], i32, i32*, i32* }
-
; The function entry should be rewritten like this.
; CHECK: define void @"\01?test@@YAXXZ"() #0 {
; CHECK: entry:
-; CHECK: %frame.alloc = call i8* @llvm.frameallocate(i32 88)
-; CHECK: %eh.data = bitcast i8* %frame.alloc to %"struct.\01?test@@YAXXZ.ehdata"*
-; CHECK-NOT: %ExceptionVal = alloca [10 x i32], align 16
-; CHECK: %NumExceptions.020.reg2mem = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 3
-; CHECK: %i.019.reg2mem = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 5
-; CHECK: %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
-; CHECK: %Data = alloca i64, align 8
-; CHECK: %tmpcast = bitcast i64* %Data to %struct.SomeData*
-; CHECK: %0 = bitcast [10 x i32]* %ExceptionVal to i8*
-; CHECK: call void @llvm.lifetime.start(i64 40, i8* %0) #1
-; CHECK: store i64 0, i64* %Data, align 8
-; CHECK: %a.reg2mem = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6
-; CHECK: %a = bitcast i64* %Data to i32*
-; CHECK: store i32* %a, i32** %a.reg2mem
-; CHECK: %b.reg2mem = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 7
-; CHECK: %b = getelementptr inbounds %struct.SomeData, %struct.SomeData* %tmpcast, i64 0, i32 1
-; CHECK: store i32* %b, i32** %b.reg2mem
-; CHECK: store i32 0, i32* %NumExceptions.020.reg2mem
-; CHECK: store i32 0, i32* %i.019.reg2mem
-; CHECK: br label %for.body
+; CHECK: %NumExceptions.020.reg2mem = alloca i32
+; CHECK: %i.019.reg2mem = alloca i32
+; CHECK: %e = alloca i32, align 4
+; CHECK: %ExceptionVal = alloca [10 x i32], align 16
+; CHECK: %Data = alloca i64, align 8
+; CHECK: %tmpcast = bitcast i64* %Data to %struct.SomeData*
+; CHECK: %0 = bitcast [10 x i32]* %ExceptionVal to i8*
+; CHECK: call void @llvm.lifetime.start(i64 40, i8* %0) #1
+; CHECK: store i64 0, i64* %Data, align 8
+; CHECK: %a.reg2mem = alloca i32*
+; CHECK: %a = bitcast i64* %Data to i32*
+; CHECK: store i32* %a, i32** %a.reg2mem
+; CHECK: %b.reg2mem = alloca i32*
+; CHECK: %b = getelementptr inbounds %struct.SomeData, %struct.SomeData* %tmpcast, i64 0, i32 1
+; CHECK: store i32* %b, i32** %b.reg2mem
+; CHECK: store i32 0, i32* %NumExceptions.020.reg2mem
+; CHECK: store i32 0, i32* %i.019.reg2mem
+; CHECK: call void (...)* @llvm.frameescape(i32* %e, i32* %NumExceptions.020.reg2mem, [10 x i32]* %ExceptionVal, i32* %i.019.reg2mem, i32** %a.reg2mem, i32** %b.reg2mem)
+; CHECK: br label %for.body
; Function Attrs: uwtable
define void @"\01?test@@YAXXZ"() #0 {
@@ -187,17 +183,21 @@
; The following catch handler should be outlined.
; CHECK: define internal i8* @"\01?test@@YAXXZ.catch"(i8*, i8*) {
; CHECK: entry:
-; CHECK: %eh.alloc = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1)
-; CHECK: %eh.data = bitcast i8* %eh.alloc to %"struct.\01?test@@YAXXZ.ehdata"*
-; CHECK: %e = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 2
-; CHECK: %eh.temp.alloca = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 3
+; CHECK: %e.i84 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 0)
+; CHECK: %e = bitcast i8* %e.i84 to i32*
+; CHECK: %eh.temp.alloca.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 1)
+; CHECK: %eh.temp.alloca = bitcast i8* %eh.temp.alloca.i8 to i32*
; CHECK: %NumExceptions.020.reload = load i32, i32* %eh.temp.alloca
-; CHECK: %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
-; CHECK: %eh.temp.alloca1 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 5
+; CHECK: %ExceptionVal.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 2)
+; CHECK: %ExceptionVal = bitcast i8* %ExceptionVal.i8 to [10 x i32]*
+; CHECK: %eh.temp.alloca1.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 3)
+; CHECK: %eh.temp.alloca1 = bitcast i8* %eh.temp.alloca1.i8 to i32*
; CHECK: %i.019.reload = load i32, i32* %eh.temp.alloca1
-; CHECK: %eh.temp.alloca2 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6
+; CHECK: %eh.temp.alloca2.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 4)
+; CHECK: %eh.temp.alloca2 = bitcast i8* %eh.temp.alloca2.i8 to i32**
; CHECK: %a.reload = load i32*, i32** %eh.temp.alloca2
-; CHECK: %eh.temp.alloca3 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 7
+; CHECK: %eh.temp.alloca3.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?test@@YAXXZ" to i8*), i8* %1, i32 5)
+; CHECK: %eh.temp.alloca3 = bitcast i8* %eh.temp.alloca3.i8 to i32**
; CHECK: %b.reload = load i32*, i32** %eh.temp.alloca3
; CHECK: %e.i8 = bitcast i32* %e to i8*
; CHECK: %tmp8 = load i32, i32* %e, align 4, !tbaa !7
diff --git a/llvm/test/CodeGen/X86/frameallocate.ll b/llvm/test/CodeGen/X86/frameallocate.ll
deleted file mode 100644
index 2172ac0..0000000
--- a/llvm/test/CodeGen/X86/frameallocate.ll
+++ /dev/null
@@ -1,43 +0,0 @@
-; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
-
-declare i8* @llvm.frameallocate(i32)
-declare i8* @llvm.frameaddress(i32)
-declare i8* @llvm.framerecover(i8*, i8*)
-declare i32 @printf(i8*, ...)
-
-@str = internal constant [10 x i8] c"asdf: %d\0A\00"
-
-define void @print_framealloc_from_fp(i8* %fp) {
- %alloc = call i8* @llvm.framerecover(i8* bitcast (void(i32*, i32*)* @alloc_func to i8*), i8* %fp)
- %alloc_i32 = bitcast i8* %alloc to i32*
- %r = load i32, i32* %alloc_i32
- call i32 (i8*, ...)* @printf(i8* getelementptr ([10 x i8]* @str, i32 0, i32 0), i32 %r)
- ret void
-}
-
-; CHECK-LABEL: print_framealloc_from_fp:
-; CHECK: movabsq $.Lframeallocation_alloc_func, %[[offs:[a-z]+]]
-; CHECK: movl (%rcx,%[[offs]]), %edx
-; CHECK: leaq {{.*}}(%rip), %rcx
-; CHECK: callq printf
-; CHECK: retq
-
-define void @alloc_func(i32* %s, i32* %d) {
- %alloc = call i8* @llvm.frameallocate(i32 16)
- %alloc_i32 = bitcast i8* %alloc to i32*
- store i32 42, i32* %alloc_i32
- %fp = call i8* @llvm.frameaddress(i32 0)
- call void @print_framealloc_from_fp(i8* %fp)
- ret void
-}
-
-; CHECK-LABEL: alloc_func:
-; CHECK: subq $48, %rsp
-; CHECK: .seh_stackalloc 48
-; CHECK: leaq 48(%rsp), %rbp
-; CHECK: .seh_setframe 5, 48
-; CHECK: .Lframeallocation_alloc_func = -[[offs:[0-9]+]]
-; CHECK: movl $42, -[[offs]](%rbp)
-; CHECK: leaq -48(%rbp), %rcx
-; CHECK: callq print_framealloc_from_fp
-; CHECK: retq
diff --git a/llvm/test/CodeGen/X86/frameescape.ll b/llvm/test/CodeGen/X86/frameescape.ll
new file mode 100644
index 0000000..621dbe2
--- /dev/null
+++ b/llvm/test/CodeGen/X86/frameescape.ll
@@ -0,0 +1,63 @@
+; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
+
+declare void @llvm.frameescape(...)
+declare i8* @llvm.frameaddress(i32)
+declare i8* @llvm.framerecover(i8*, i8*, i32)
+declare i32 @printf(i8*, ...)
+
+@str = internal constant [10 x i8] c"asdf: %d\0A\00"
+
+define void @print_framealloc_from_fp(i8* %fp) {
+ %a.i8 = call i8* @llvm.framerecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 0)
+ %a = bitcast i8* %a.i8 to i32*
+ %a.val = load i32, i32* %a
+ call i32 (i8*, ...)* @printf(i8* getelementptr ([10 x i8]* @str, i32 0, i32 0), i32 %a.val)
+ %b.i8 = call i8* @llvm.framerecover(i8* bitcast (void()* @alloc_func to i8*), i8* %fp, i32 1)
+ %b = bitcast i8* %b.i8 to i32*
+ %b.val = load i32, i32* %b
+ call i32 (i8*, ...)* @printf(i8* getelementptr ([10 x i8]* @str, i32 0, i32 0), i32 %b.val)
+ ret void
+}
+
+; CHECK-LABEL: print_framealloc_from_fp:
+; CHECK: movq %rcx, %[[parent_fp:[a-z]+]]
+; CHECK: movabsq $.Lalloc_func$frame_escape_0, %[[offs:[a-z]+]]
+; CHECK: movl (%[[parent_fp]],%[[offs]]), %edx
+; CHECK: leaq {{.*}}(%rip), %[[str:[a-z]+]]
+; CHECK: movq %[[str]], %rcx
+; CHECK: callq printf
+; CHECK: movabsq $.Lalloc_func$frame_escape_1, %[[offs:[a-z]+]]
+; CHECK: movl (%[[parent_fp]],%[[offs]]), %edx
+; CHECK: movq %[[str]], %rcx
+; CHECK: callq printf
+; CHECK: retq
+
+define void @alloc_func() {
+ %a = alloca i32
+ %b = alloca i32
+ call void (...)* @llvm.frameescape(i32* %a, i32* %b)
+ store i32 42, i32* %a
+ store i32 13, i32* %b
+ %fp = call i8* @llvm.frameaddress(i32 0)
+ call void @print_framealloc_from_fp(i8* %fp)
+ ret void
+}
+
+; CHECK-LABEL: alloc_func:
+; CHECK: subq $48, %rsp
+; CHECK: .seh_stackalloc 48
+; CHECK: leaq 48(%rsp), %rbp
+; CHECK: .seh_setframe 5, 48
+; CHECK: .Lalloc_func$frame_escape_0 = 44
+; CHECK: .Lalloc_func$frame_escape_1 = 40
+; CHECK: movl $42, -4(%rbp)
+; CHECK: movl $13, -8(%rbp)
+; CHECK: leaq -48(%rbp), %rcx
+; CHECK: callq print_framealloc_from_fp
+; CHECK: retq
+
+; Helper to make this a complete program so it can be compiled and tested.
+define i32 @main() {
+ call void @alloc_func()
+ ret i32 0
+}
diff --git a/llvm/test/Verifier/frameallocate.ll b/llvm/test/Verifier/frameallocate.ll
deleted file mode 100644
index e3018db..0000000
--- a/llvm/test/Verifier/frameallocate.ll
+++ /dev/null
@@ -1,48 +0,0 @@
-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
-
-declare i8* @llvm.frameallocate(i32)
-declare i8* @llvm.framerecover(i8*, i8*)
-
-define internal void @f() {
- call i8* @llvm.frameallocate(i32 4)
- call i8* @llvm.frameallocate(i32 4)
- ret void
-}
-; CHECK: multiple calls to llvm.frameallocate in one function
-
-define internal void @f_a(i32 %n) {
- call i8* @llvm.frameallocate(i32 %n)
- ret void
-}
-; CHECK: llvm.frameallocate argument must be constant integer size
-
-define internal void @g() {
-entry:
- br label %not_entry
-not_entry:
- call i8* @llvm.frameallocate(i32 4)
- ret void
-}
-; CHECK: llvm.frameallocate used outside of entry block
-
-define internal void @h() {
- call i8* @llvm.framerecover(i8* null, i8* null)
- ret void
-}
-; CHECK: llvm.framerecover first argument must be function defined in this module
-
-@global = constant i8 0
-
-declare void @declaration()
-
-define internal void @i() {
- call i8* @llvm.framerecover(i8* @global, i8* null)
- ret void
-}
-; CHECK: llvm.framerecover first argument must be function defined in this module
-
-define internal void @j() {
- call i8* @llvm.framerecover(i8* bitcast(void()* @declaration to i8*), i8* null)
- ret void
-}
-; CHECK: llvm.framerecover first argument must be function defined in this module
diff --git a/llvm/test/Verifier/frameescape.ll b/llvm/test/Verifier/frameescape.ll
new file mode 100644
index 0000000..54e0db4
--- /dev/null
+++ b/llvm/test/Verifier/frameescape.ll
@@ -0,0 +1,69 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+declare void @llvm.frameescape(...)
+declare i8* @llvm.framerecover(i8*, i8*, i32)
+
+define internal void @f() {
+ %a = alloca i8
+ call void (...)* @llvm.frameescape(i8* %a)
+ call void (...)* @llvm.frameescape(i8* %a)
+ ret void
+}
+; CHECK: multiple calls to llvm.frameescape in one function
+
+define internal void @g() {
+entry:
+ %a = alloca i8
+ br label %not_entry
+not_entry:
+ call void (...)* @llvm.frameescape(i8* %a)
+ ret void
+}
+; CHECK: llvm.frameescape used outside of entry block
+
+define internal void @h() {
+ call i8* @llvm.framerecover(i8* null, i8* null, i32 0)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
+
+@global = constant i8 0
+
+declare void @declaration()
+
+define internal void @i() {
+ call i8* @llvm.framerecover(i8* @global, i8* null, i32 0)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
+
+define internal void @j() {
+ call i8* @llvm.framerecover(i8* bitcast(void()* @declaration to i8*), i8* null, i32 0)
+ ret void
+}
+; CHECK: llvm.framerecover first argument must be function defined in this module
+
+define internal void @k(i32 %n) {
+ call i8* @llvm.framerecover(i8* bitcast(void()* @f to i8*), i8* null, i32 %n)
+ ret void
+}
+; CHECK: idx argument of llvm.framerecover must be a constant int
+
+define internal void @l(i8* %b) {
+ %a = alloca i8
+ call void (...)* @llvm.frameescape(i8* %a, i8* %b)
+ ret void
+}
+; CHECK: llvm.frameescape only accepts static allocas
+
+define internal void @m() {
+ %a = alloca i8
+ call void (...)* @llvm.frameescape(i8* %a)
+ ret void
+}
+
+define internal void @n(i8* %fp) {
+ call i8* @llvm.framerecover(i8* bitcast(void ()* @m to i8*), i8* %fp, i32 1)
+ ret void
+}
+; CHECK: all indices passed to llvm.framerecover must be less than the number of arguments passed ot llvm.frameescape in the parent function