Make llvm.eh.begincatch use an outparam

Ultimately, __CxxFrameHandler3 needs us to put a stack offset in a
table, and it will take responsibility for copying the exception object
into that slot. Modelling the exception object as an SSA value returned
by begincatch isn't going to work in general, so make it use an output
parameter.

Reviewers: andrew.w.kaylor

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

llvm-svn: 231086
diff --git a/llvm/test/CodeGen/X86/cppeh-catch-all.ll b/llvm/test/CodeGen/X86/cppeh-catch-all.ll
index ff0cea6..814e97d 100644
--- a/llvm/test/CodeGen/X86/cppeh-catch-all.ll
+++ b/llvm/test/CodeGen/X86/cppeh-catch-all.ll
@@ -40,7 +40,7 @@
 
 catch:                                            ; preds = %lpad
   %exn = load i8*, i8** %exn.slot
-  %tmp3 = call i8* @llvm.eh.begincatch(i8* %exn) #2
+  call void @llvm.eh.begincatch(i8* %exn, i8* null) #2
   call void @_Z16handle_exceptionv()
   br label %invoke.cont2
 
@@ -66,7 +66,7 @@
 
 declare i32 @__CxxFrameHandler3(...)
 
-declare i8* @llvm.eh.begincatch(i8*)
+declare void @llvm.eh.begincatch(i8*, i8*)
 
 declare void @_Z16handle_exceptionv() #1
 
diff --git a/llvm/test/CodeGen/X86/cppeh-catch-scalar.ll b/llvm/test/CodeGen/X86/cppeh-catch-scalar.ll
index 25cd801..9c16a9b 100644
--- a/llvm/test/CodeGen/X86/cppeh-catch-scalar.ll
+++ b/llvm/test/CodeGen/X86/cppeh-catch-scalar.ll
@@ -62,10 +62,8 @@
 
 catch:                                            ; preds = %catch.dispatch
   %exn11 = load i8*, i8** %exn.slot
-  %tmp4 = call i8* @llvm.eh.begincatch(i8* %exn11) #3
-  %tmp5 = bitcast i8* %tmp4 to i32*
-  %tmp6 = load i32, i32* %tmp5, align 4
-  store i32 %tmp6, i32* %i, align 4
+  %i.i8 = bitcast i32* %i to i8*
+  call void @llvm.eh.begincatch(i8* %exn11, i8* %i.i8) #3
   %tmp7 = load i32, i32* %i, align 4
   call void @_Z10handle_inti(i32 %tmp7)
   br label %invoke.cont2
@@ -92,9 +90,6 @@
 ; CHECK:   %eh.obj.ptr = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 1
 ; CHECK:   %eh.obj = load i8*, i8** %eh.obj.ptr
 ; CHECK:   %i = getelementptr inbounds %struct._Z4testv.ehdata, %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2
-; CHECK:   %tmp5 = bitcast i8* %eh.obj to i32*
-; CHECK:   %tmp6 = load i32, i32* %tmp5, align 4
-; CHECK:   store i32 %tmp6, i32* %i, align 4
 ; CHECK:   %tmp7 = load i32, i32* %i, align 4
 ; CHECK:   call void @_Z10handle_inti(i32 %tmp7)
 ; CHECK:   ret i8* blockaddress(@_Z4testv, %try.cont)
@@ -107,7 +102,7 @@
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.eh.typeid.for(i8*) #2
 
-declare i8* @llvm.eh.begincatch(i8*)
+declare void @llvm.eh.begincatch(i8*, i8*)
 
 declare void @llvm.eh.endcatch()
 
diff --git a/llvm/test/CodeGen/X86/cppeh-frame-vars.ll b/llvm/test/CodeGen/X86/cppeh-frame-vars.ll
index 3a611c3..471aeed 100644
--- a/llvm/test/CodeGen/X86/cppeh-frame-vars.ll
+++ b/llvm/test/CodeGen/X86/cppeh-frame-vars.ll
@@ -116,10 +116,8 @@
 
 catch:                                            ; preds = %catch.dispatch
   %exn = load i8*, i8** %exn.slot
-  %tmp8 = call i8* @llvm.eh.begincatch(i8* %exn) #1
-  %tmp9 = bitcast i8* %tmp8 to i32*
-  %tmp10 = load i32, i32* %tmp9, align 4
-  store i32 %tmp10, i32* %e, align 4
+  %e.i8 = bitcast i32* %e to i8*
+  call void @llvm.eh.begincatch(i8* %exn, i8* %e.i8) #1
   %tmp11 = load i32, i32* %e, align 4
   %tmp12 = load i32, i32* %NumExceptions, align 4
   %idxprom = sext i32 %tmp12 to i64
@@ -190,9 +188,6 @@
 ; 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:   %tmp9 = bitcast i8* %eh.obj to i32*
-; CHECK:   %tmp10 = load i32, i32* %tmp9, align 4
-; CHECK:   store i32 %tmp10, i32* %e, align 4
 ; CHECK:   %tmp11 = load i32, i32* %e, align 4
 ; CHECK:   %tmp12 = load i32, i32* %NumExceptions, align 4
 ; CHECK:   %idxprom = sext i32 %tmp12 to i64
@@ -241,7 +236,7 @@
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.eh.typeid.for(i8*) #3
 
-declare i8* @llvm.eh.begincatch(i8*)
+declare void @llvm.eh.begincatch(i8*, i8*)
 
 declare void @llvm.eh.endcatch()
 
diff --git a/llvm/test/CodeGen/X86/cppeh-inalloca.ll b/llvm/test/CodeGen/X86/cppeh-inalloca.ll
index d7b7d56..61f5a0c 100644
--- a/llvm/test/CodeGen/X86/cppeh-inalloca.ll
+++ b/llvm/test/CodeGen/X86/cppeh-inalloca.ll
@@ -84,15 +84,13 @@
 
 catch:                                            ; preds = %catch.dispatch
   %exn = load i8*, i8** %exn.slot
-  %5 = call i8* @llvm.eh.begincatch(i8* %exn) #3
-  %6 = bitcast i8* %5 to i32*
-  %7 = load i32, i32* %6, align 4
-  store i32 %7, i32* %e, align 4
+  %e.i8 = bitcast i32* %e to i8*
+  call void @llvm.eh.begincatch(i8* %exn, i8* %e.i8) #3
   %a = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %0, i32 0, i32 0
   %a1 = getelementptr inbounds %struct.A, %struct.A* %a, i32 0, i32 0
-  %8 = load i32, i32* %a1, align 4
-  %9 = load i32, i32* %e, align 4
-  %add = add nsw i32 %8, %9
+  %tmp8 = load i32, i32* %a1, align 4
+  %tmp9 = load i32, i32* %e, align 4
+  %add = add nsw i32 %tmp8, %tmp9
   store i32 %add, i32* %retval
   store i32 1, i32* %cleanup.dest.slot
   call void @llvm.eh.endcatch() #3
@@ -109,14 +107,14 @@
 ; CHECK:   %.tmp.reload1 = load volatile <{ %struct.A }>*, <{ %struct.A }>** %.tmp.reg2mem
 ; CHECK:   %a2 = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %.tmp.reload1, i32 0, i32 0
 ; CHECK:   call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %a2) #2
-; CHECK:   %10 = load i32, i32* %retval
-; CHECK:   ret i32 %10
+; CHECK:   %tmp10 = load i32, i32* %retval
+; CHECK:   ret i32 %tmp10
 
 cleanup:                                          ; preds = %try.cont, %catch
   %a2 = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %0, i32 0, i32 0
   call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %a2) #3
-  %10 = load i32, i32* %retval
-  ret i32 %10
+  %tmp10 = load i32, i32* %retval
+  ret i32 %tmp10
 
 ehcleanup:                                        ; preds = %catch.dispatch
   %a3 = getelementptr inbounds <{ %struct.A }>, <{ %struct.A }>* %0, i32 0, i32 0
@@ -143,14 +141,11 @@
 ; 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:   %2 = bitcast i8* %eh.obj to i32*
-; CHECK:   %3 = load i32, i32* %2, align 4
-; CHECK:   store i32 %3, i32* %e, align 4
 ; 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:   %4 = load i32, i32* %a1, align 4
-; CHECK:   %5 = load i32, i32* %e, align 4
-; CHECK:   %add = add nsw i32 %4, %5
+; CHECK:   %tmp8 = load i32, i32* %a1, align 4
+; CHECK:   %tmp9 = load i32, i32* %e, align 4
+; CHECK:   %add = add nsw i32 %tmp8, %tmp9
 ; CHECK:   store i32 %add, i32* %retval
 ; CHECK:   store i32 1, i32* %cleanup.dest.slot
 ; CHECK:   ret i8* blockaddress(@"\01?test@@YAHUA@@@Z", %cleanup)
@@ -164,7 +159,7 @@
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.eh.typeid.for(i8*) #1
 
-declare i8* @llvm.eh.begincatch(i8*)
+declare void @llvm.eh.begincatch(i8*, i8*)
 
 declare void @llvm.eh.endcatch()
 
diff --git a/llvm/test/CodeGen/X86/cppeh-nonalloca-frame-values.ll b/llvm/test/CodeGen/X86/cppeh-nonalloca-frame-values.ll
index ebc540d..987b264 100644
--- a/llvm/test/CodeGen/X86/cppeh-nonalloca-frame-values.ll
+++ b/llvm/test/CodeGen/X86/cppeh-nonalloca-frame-values.ll
@@ -51,26 +51,26 @@
 @"\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, [10 x i32], i32, i32*, i32* }
+; 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 80)
+; 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 2
-; CHECK:  %i.019.reg2mem = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
-; CHECK:  %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 3
+; 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 5
+; 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 6
+; 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
@@ -80,6 +80,7 @@
 ; Function Attrs: uwtable
 define void @"\01?test@@YAXXZ"() #0 {
 entry:
+  %e = alloca i32, align 4
   %ExceptionVal = alloca [10 x i32], align 16
   %Data = alloca i64, align 8
   %tmpcast = bitcast i64* %Data to %struct.SomeData*
@@ -127,25 +128,25 @@
 
 catch:                                            ; preds = %lpad
   %5 = extractvalue { i8*, i32 } %2, 0
-  %6 = tail call i8* @llvm.eh.begincatch(i8* %5) #1
-  %7 = bitcast i8* %6 to i32*
-  %8 = load i32, i32* %7, align 4, !tbaa !7
+  %e.i8 = bitcast i32* %e to i8*
+  call void @llvm.eh.begincatch(i8* %5, i8* %e.i8) #1
+  %tmp8 = load i32, i32* %e, align 4, !tbaa !7
   %idxprom = sext i32 %NumExceptions.020 to i64
   %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %ExceptionVal, i64 0, i64 %idxprom
-  store i32 %8, i32* %arrayidx, align 4, !tbaa !7
+  store i32 %tmp8, i32* %arrayidx, align 4, !tbaa !7
   %inc = add nsw i32 %NumExceptions.020, 1
-  %cmp1 = icmp eq i32 %8, %i.019
+  %cmp1 = icmp eq i32 %tmp8, %i.019
   br i1 %cmp1, label %if.then, label %if.else
 
 if.then:                                          ; preds = %catch
-  %9 = load i32, i32* %b, align 4, !tbaa !8
-  %add2 = add nsw i32 %9, %i.019
+  %tmp9 = load i32, i32* %b, align 4, !tbaa !8
+  %add2 = add nsw i32 %tmp9, %i.019
   store i32 %add2, i32* %b, align 4, !tbaa !8
   br label %if.end
 
 if.else:                                          ; preds = %catch
-  %10 = load i32, i32* %a, align 8, !tbaa !2
-  %add4 = add nsw i32 %10, %8
+  %tmp10 = load i32, i32* %a, align 8, !tbaa !2
+  %add4 = add nsw i32 %tmp10, %tmp8
   store i32 %add4, i32* %a, align 8, !tbaa !2
   br label %if.end
 
@@ -190,33 +191,34 @@
 ; CHECK:   %eh.data = bitcast i8* %eh.alloc to %"struct.\01?test@@YAXXZ.ehdata"*
 ; CHECK:   %eh.obj.ptr = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 1
 ; CHECK:   %eh.obj = load i8*, i8** %eh.obj.ptr
-; CHECK:   %eh.temp.alloca = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 2
+; 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:   %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 3
-; CHECK:   %eh.temp.alloca1 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4
+; 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:   %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 5
+; CHECK:   %eh.temp.alloca2 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6
 ; 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 6
+; CHECK:   %eh.temp.alloca3 = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata", %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 7
 ; CHECK:   %b.reload = load i32*, i32** %eh.temp.alloca3
-; CHECK:   %2 = bitcast i8* %eh.obj to i32*
-; CHECK:   %3 = load i32, i32* %2, align 4, !tbaa !7
+; CHECK:   %e.i8 = bitcast i32* %e to i8*
+; CHECK:   %tmp8 = load i32, i32* %e, align 4, !tbaa !7
 ; CHECK:   %idxprom = sext i32 %NumExceptions.020.reload to i64
 ; CHECK:   %arrayidx = getelementptr inbounds [10 x i32], [10 x i32]* %ExceptionVal, i64 0, i64 %idxprom
-; CHECK:   store i32 %3, i32* %arrayidx, align 4, !tbaa !7
+; CHECK:   store i32 %tmp8, i32* %arrayidx, align 4, !tbaa !7
 ; CHECK:   %inc = add nsw i32 %NumExceptions.020.reload, 1
-; CHECK:   %cmp1 = icmp eq i32 %3, %i.019.reload
+; CHECK:   %cmp1 = icmp eq i32 %tmp8, %i.019.reload
 ; CHECK:   br i1 %cmp1, label %if.then, label %if.else
 ;
 ; CHECK: if.then:                                          ; preds = %catch.entry
-; CHECK:   %4 = load i32, i32* %b.reload, align 4, !tbaa !8
-; CHECK:   %add2 = add nsw i32 %4, %i.019.reload
+; CHECK:   %tmp9 = load i32, i32* %b.reload, align 4, !tbaa !8
+; CHECK:   %add2 = add nsw i32 %tmp9, %i.019.reload
 ; CHECK:   store i32 %add2, i32* %b.reload, align 4, !tbaa !8
 ; CHECK:   br label %if.end
 ;
 ; CHECK: if.else:                                          ; preds = %catch.entry
-; CHECK:   %5 = load i32, i32* %a.reload, align 8, !tbaa !2
-; CHECK:   %add4 = add nsw i32 %5, %3
+; CHECK:   %tmp10 = load i32, i32* %a.reload, align 8, !tbaa !2
+; CHECK:   %add4 = add nsw i32 %tmp10, %tmp8
 ; CHECK:   store i32 %add4, i32* %a.reload, align 8, !tbaa !2
 ; CHECK:   br label %if.end
 ;
@@ -234,7 +236,7 @@
 ; Function Attrs: nounwind readnone
 declare i32 @llvm.eh.typeid.for(i8*) #3
 
-declare i8* @llvm.eh.begincatch(i8*)
+declare void @llvm.eh.begincatch(i8*, i8*)
 
 declare void @llvm.eh.endcatch()