Index: docs/ExceptionHandling.rst =================================================================== --- docs/ExceptionHandling.rst +++ docs/ExceptionHandling.rst @@ -442,7 +442,7 @@ .. code-block:: llvm - i8* @llvm.eh.begincatch(i8* %exn) + void @llvm.eh.begincatch(i8* %ehptr, i8* %ehobj) This intrinsic marks the beginning of catch handling code within the blocks @@ -450,11 +450,11 @@ depends on the compilation target and the personality function associated with the ``landingpad`` instruction. -The argument to this intrinsic is a pointer that was previously extracted from -the aggregate return value of the ``landingpad`` instruction. The return -value of the intrinsic is a pointer to the exception object to be used by the -catch code. This pointer is returned as an ``i8*`` value, but the actual type -of the object will depend on the exception that was thrown. +The first argument to this intrinsic is a pointer that was previously extracted +from the aggregate return value of the ``landingpad`` instruction. The second +argument to the intrinsic is a pointer to stack space where the exception object +should be stored. The runtime handles the details of copying the exception +object into the slot. If the second parameter is null, no copy occurs. Uses of this intrinsic are generated by the C++ front-end. Many targets will use implementation-specific functions (such as ``__cxa_begin_catch``) instead Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -412,8 +412,10 @@ def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>; // eh.begincatch takes a pointer returned by a landingpad instruction and -// returns the exception object pointer for the exception to be handled. -def int_eh_begincatch : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>; +// copies the exception object into the memory pointed to by the second +// parameter. If the second parameter is null, no copy occurs. +def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], + [NoCapture<0>, NoCapture<1>]>; def int_eh_endcatch : Intrinsic<[], []>; // __builtin_unwind_init is an undocumented GCC intrinsic that causes all Index: test/Analysis/Lint/cppeh-catch-intrinsics-clean.ll =================================================================== --- test/Analysis/Lint/cppeh-catch-intrinsics-clean.ll +++ test/Analysis/Lint/cppeh-catch-intrinsics-clean.ll @@ -5,7 +5,7 @@ target triple = "x86_64-pc-windows-msvc" -declare i8* @llvm.eh.begincatch(i8*) +declare void @llvm.eh.begincatch(i8*, i8*) declare void @llvm.eh.endcatch() @@ -27,7 +27,7 @@ br i1 %matches, label %catch, label %eh.resume catch: ; preds = %lpad - %2 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @_Z10handle_intv() br label %invoke.cont2 @@ -77,7 +77,7 @@ catch: ; preds = %lpad, %lpad1 %exn2 = phi i8* [%exn, %lpad], [%exn1, %lpad1] %sel2 = phi i32 [%sel, %lpad], [%sel1, %lpad1] - %3 = call i8* @llvm.eh.begincatch(i8* %exn2) + call void @llvm.eh.begincatch(i8* %exn2, i8* null) call void @_Z10handle_intv() %matches1 = icmp eq i32 %sel2, 0 br i1 %matches1, label %invoke.cont2, label %invoke.cont3 Index: test/Analysis/Lint/cppeh-catch-intrinsics.ll =================================================================== --- test/Analysis/Lint/cppeh-catch-intrinsics.ll +++ test/Analysis/Lint/cppeh-catch-intrinsics.ll @@ -6,7 +6,7 @@ target triple = "x86_64-pc-windows-msvc" -declare i8* @llvm.eh.begincatch(i8*) +declare void @llvm.eh.begincatch(i8*, i8*) declare void @llvm.eh.endcatch() @@ -15,7 +15,7 @@ ; Function Attrs: uwtable define void @test_missing_endcatch() { ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch -; CHECK-NEXT: %2 = call i8* @llvm.eh.begincatch(i8* %exn) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null) entry: invoke void @_Z9may_throwv() to label %try.cont unwind label %lpad @@ -30,7 +30,7 @@ br i1 %matches, label %catch, label %eh.resume catch: ; preds = %lpad - %2 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @_Z10handle_intv() br label %invoke.cont2 @@ -79,8 +79,8 @@ ; Function Attrs: uwtable define void @test_multiple_begin() { ; CHECK: llvm.eh.begincatch may be called a second time before llvm.eh.endcatch -; CHECK-NEXT: %2 = call i8* @llvm.eh.begincatch(i8* %exn) -; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null) entry: invoke void @_Z9may_throwv() to label %try.cont unwind label %lpad @@ -95,12 +95,12 @@ br i1 %matches, label %catch, label %eh.resume catch: ; preds = %lpad - %2 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @_Z10handle_intv() br label %invoke.cont2 invoke.cont2: ; preds = %catch - %3 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @llvm.eh.endcatch() br label %try.cont @@ -130,7 +130,7 @@ br i1 %matches, label %catch, label %eh.resume catch: ; preds = %lpad - %2 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @_Z10handle_intv() call void @llvm.eh.endcatch() br label %invoke.cont2 @@ -150,10 +150,10 @@ ; Function Attrs: uwtable define void @test_begincatch_without_lpad() { ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad -; CHECK-NEXT: %0 = call i8* @llvm.eh.begincatch(i8* %exn) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn, i8* null) entry: %exn = alloca i8 - %0 = call i8* @llvm.eh.begincatch(i8* %exn) + call void @llvm.eh.begincatch(i8* %exn, i8* null) call void @_Z10handle_intv() br label %invoke.cont2 @@ -168,7 +168,7 @@ ; Function Attrs: uwtable define void @test_branch_to_begincatch_with_no_lpad(i32 %fake.sel) { ; CHECK: llvm.eh.begincatch may be reachable without passing a landingpad -; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn2) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn2, i8* null) entry: %fake.exn = alloca i8 invoke void @_Z9may_throwv() @@ -189,7 +189,7 @@ catch: ; preds = %lpad, %entry %exn2 = phi i8* [%exn, %lpad], [%fake.exn, %entry] %sel2 = phi i32 [%sel, %lpad], [%fake.sel, %entry] - %3 = call i8* @llvm.eh.begincatch(i8* %exn2) + call void @llvm.eh.begincatch(i8* %exn2, i8* null) call void @_Z10handle_intv() %matches1 = icmp eq i32 %sel2, 0 br i1 %matches1, label %invoke.cont2, label %invoke.cont3 @@ -213,7 +213,7 @@ ; Function Attrs: uwtable define void @test_branch_missing_endcatch() { ; CHECK: Some paths from llvm.eh.begincatch may not reach llvm.eh.endcatch -; CHECK-NEXT: %3 = call i8* @llvm.eh.begincatch(i8* %exn2) +; CHECK-NEXT: call void @llvm.eh.begincatch(i8* %exn2, i8* null) entry: invoke void @_Z9may_throwv() to label %invoke.cont unwind label %lpad @@ -247,7 +247,7 @@ catch: ; preds = %lpad, %lpad1 %exn2 = phi i8* [%exn, %lpad], [%exn1, %lpad1] %sel2 = phi i32 [%sel, %lpad], [%sel1, %lpad1] - %3 = call i8* @llvm.eh.begincatch(i8* %exn2) + call void @llvm.eh.begincatch(i8* %exn2, i8* null) call void @_Z10handle_intv() %matches1 = icmp eq i32 %sel2, 0 br i1 %matches1, label %invoke.cont2, label %invoke.cont3 Index: test/CodeGen/X86/cppeh-catch-all.ll =================================================================== --- test/CodeGen/X86/cppeh-catch-all.ll +++ test/CodeGen/X86/cppeh-catch-all.ll @@ -40,7 +40,7 @@ catch: ; preds = %lpad %exn = load i8** %exn.slot - %3 = call i8* @llvm.eh.begincatch(i8* %exn) #3 + call void @llvm.eh.begincatch(i8* %exn, i8* null) #3 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 Index: test/CodeGen/X86/cppeh-catch-scalar.ll =================================================================== --- test/CodeGen/X86/cppeh-catch-scalar.ll +++ test/CodeGen/X86/cppeh-catch-scalar.ll @@ -62,12 +62,10 @@ catch: ; preds = %catch.dispatch %exn11 = load i8** %exn.slot - %4 = call i8* @llvm.eh.begincatch(i8* %exn11) #3 - %5 = bitcast i8* %4 to i32* - %6 = load i32* %5, align 4 - store i32 %6, i32* %i, align 4 - %7 = load i32* %i, align 4 - call void @_Z10handle_inti(i32 %7) + %i.i8 = bitcast i32* %i to i8* + call void @llvm.eh.begincatch(i8* %exn11, i8* %i.i8) #3 + %4 = load i32* %i, align 4 + call void @_Z10handle_inti(i32 %4) br label %invoke.cont2 invoke.cont2: ; preds = %catch @@ -92,11 +90,8 @@ ; CHECK: %eh.obj.ptr = getelementptr inbounds %struct._Z4testv.ehdata* %eh.data, i32 0, i32 1 ; CHECK: %eh.obj = load i8** %eh.obj.ptr ; CHECK: %i = getelementptr inbounds %struct._Z4testv.ehdata* %eh.data, i32 0, i32 2 -; CHECK: %2 = bitcast i8* %eh.obj to i32* -; CHECK: %3 = load i32* %2, align 4 -; CHECK: store i32 %3, i32* %i, align 4 -; CHECK: %4 = load i32* %i, align 4 -; CHECK: call void @_Z10handle_inti(i32 %4) +; CHECK: %2 = load i32* %i, align 4 +; CHECK: call void @_Z10handle_inti(i32 %2) ; CHECK: ret i8* blockaddress(@_Z4testv, %try.cont) ; CHECK: } @@ -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() Index: test/CodeGen/X86/cppeh-frame-vars.ll =================================================================== --- test/CodeGen/X86/cppeh-frame-vars.ll +++ test/CodeGen/X86/cppeh-frame-vars.ll @@ -77,14 +77,14 @@ %ehselector.slot = alloca i32 %e = alloca i32, align 4 store i32 0, i32* %NumExceptions, align 4 - %0 = bitcast %struct.SomeData* %Data to i8* - call void @llvm.memset(i8* %0, i8 0, i64 8, i32 4, i1 false) + %tmp0 = bitcast %struct.SomeData* %Data to i8* + call void @llvm.memset(i8* %tmp0, i8 0, i64 8, i32 4, i1 false) store i32 0, i32* %i, align 4 br label %for.cond for.cond: ; preds = %for.inc, %entry - %1 = load i32* %i, align 4 - %cmp = icmp slt i32 %1, 10 + %tmp1 = load i32* %i, align 4 + %cmp = icmp slt i32 %tmp1, 10 br i1 %cmp, label %for.body, label %for.end for.body: ; preds = %for.cond @@ -92,60 +92,58 @@ to label %invoke.cont unwind label %lpad invoke.cont: ; preds = %for.body - %2 = load i32* %i, align 4 + %tmp2 = load i32* %i, align 4 %a = getelementptr inbounds %struct.SomeData* %Data, i32 0, i32 0 - %3 = load i32* %a, align 4 - %add = add nsw i32 %3, %2 + %tmp3 = load i32* %a, align 4 + %add = add nsw i32 %tmp3, %tmp2 store i32 %add, i32* %a, align 4 br label %try.cont lpad: ; preds = %for.body - %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) + %tmp4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) catch i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*) - %5 = extractvalue { i8*, i32 } %4, 0 - store i8* %5, i8** %exn.slot - %6 = extractvalue { i8*, i32 } %4, 1 - store i32 %6, i32* %ehselector.slot + %tmp5 = extractvalue { i8*, i32 } %tmp4, 0 + store i8* %tmp5, i8** %exn.slot + %tmp6 = extractvalue { i8*, i32 } %tmp4, 1 + store i32 %tmp6, i32* %ehselector.slot br label %catch.dispatch catch.dispatch: ; preds = %lpad %sel = load i32* %ehselector.slot - %7 = call i32 @llvm.eh.typeid.for(i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)) #1 - %matches = icmp eq i32 %sel, %7 + %tmp7 = call i32 @llvm.eh.typeid.for(i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*)) #1 + %matches = icmp eq i32 %sel, %tmp7 br i1 %matches, label %catch, label %eh.resume catch: ; preds = %catch.dispatch %exn = load i8** %exn.slot - %8 = call i8* @llvm.eh.begincatch(i8* %exn) #1 - %9 = bitcast i8* %8 to i32* - %10 = load i32* %9, align 4 - store i32 %10, i32* %e, align 4 - %11 = load i32* %e, align 4 - %12 = load i32* %NumExceptions, align 4 - %idxprom = sext i32 %12 to i64 + %e.i8 = bitcast i32* %e to i8* + call void @llvm.eh.begincatch(i8* %exn, i8* %e.i8) #1 + %tmp11 = load i32* %e, align 4 + %tmp12 = load i32* %NumExceptions, align 4 + %idxprom = sext i32 %tmp12 to i64 %arrayidx = getelementptr inbounds [10 x i32]* %ExceptionVal, i32 0, i64 %idxprom - store i32 %11, i32* %arrayidx, align 4 - %13 = load i32* %NumExceptions, align 4 - %inc = add nsw i32 %13, 1 + store i32 %tmp11, i32* %arrayidx, align 4 + %tmp13 = load i32* %NumExceptions, align 4 + %inc = add nsw i32 %tmp13, 1 store i32 %inc, i32* %NumExceptions, align 4 - %14 = load i32* %e, align 4 - %15 = load i32* %i, align 4 - %cmp1 = icmp eq i32 %14, %15 + %tmp14 = load i32* %e, align 4 + %tmp15 = load i32* %i, align 4 + %cmp1 = icmp eq i32 %tmp14, %tmp15 br i1 %cmp1, label %if.then, label %if.else if.then: ; preds = %catch - %16 = load i32* %e, align 4 + %tmp16 = load i32* %e, align 4 %b = getelementptr inbounds %struct.SomeData* %Data, i32 0, i32 1 - %17 = load i32* %b, align 4 - %add2 = add nsw i32 %17, %16 + %tmp17 = load i32* %b, align 4 + %add2 = add nsw i32 %tmp17, %tmp16 store i32 %add2, i32* %b, align 4 br label %if.end if.else: ; preds = %catch - %18 = load i32* %e, align 4 + %tmp18 = load i32* %e, align 4 %a3 = getelementptr inbounds %struct.SomeData* %Data, i32 0, i32 0 - %19 = load i32* %a3, align 4 - %add4 = add nsw i32 %19, %18 + %tmp19 = load i32* %a3, align 4 + %add4 = add nsw i32 %tmp19, %tmp18 store i32 %add4, i32* %a3, align 4 br label %if.end @@ -154,20 +152,20 @@ br label %try.cont try.cont: ; preds = %if.end, %invoke.cont - %20 = load i32* %NumExceptions, align 4 - call void @"\01?does_not_throw@@YAXH@Z"(i32 %20) + %tmp20 = load i32* %NumExceptions, align 4 + call void @"\01?does_not_throw@@YAXH@Z"(i32 %tmp20) br label %for.inc for.inc: ; preds = %try.cont - %21 = load i32* %i, align 4 - %inc5 = add nsw i32 %21, 1 + %tmp21 = load i32* %i, align 4 + %inc5 = add nsw i32 %tmp21, 1 store i32 %inc5, i32* %i, align 4 br label %for.cond for.end: ; preds = %for.cond - %22 = load i32* %NumExceptions, align 4 + %tmp22 = load i32* %NumExceptions, align 4 %arraydecay = getelementptr inbounds [10 x i32]* %ExceptionVal, i32 0, i32 0 - call void @"\01?dump@@YAXPEAHHAEAUSomeData@@@Z"(i32* %arraydecay, i32 %22, %struct.SomeData* dereferenceable(8) %Data) + call void @"\01?dump@@YAXPEAHHAEAUSomeData@@@Z"(i32* %arraydecay, i32 %tmp22, %struct.SomeData* dereferenceable(8) %Data) ret void eh.resume: ; preds = %catch.dispatch @@ -190,35 +188,32 @@ ; CHECK: %ExceptionVal = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 4 ; CHECK: %i = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 5 ; CHECK: %Data = getelementptr inbounds %"struct.\01?test@@YAXXZ.ehdata"* %eh.data, i32 0, i32 6 -; CHECK: %2 = bitcast i8* %eh.obj to i32* -; CHECK: %3 = load i32* %2, align 4 -; CHECK: store i32 %3, i32* %e, align 4 -; CHECK: %4 = load i32* %e, align 4 -; CHECK: %5 = load i32* %NumExceptions, align 4 -; CHECK: %idxprom = sext i32 %5 to i64 +; CHECK: %tmp11 = load i32* %e, align 4 +; CHECK: %tmp12 = load i32* %NumExceptions, align 4 +; CHECK: %idxprom = sext i32 %tmp12 to i64 ; CHECK: %arrayidx = getelementptr inbounds [10 x i32]* %ExceptionVal, i32 0, i64 %idxprom -; CHECK: store i32 %4, i32* %arrayidx, align 4 -; CHECK: %6 = load i32* %NumExceptions, align 4 -; CHECK: %inc = add nsw i32 %6, 1 +; CHECK: store i32 %tmp11, i32* %arrayidx, align 4 +; CHECK: %tmp13 = load i32* %NumExceptions, align 4 +; CHECK: %inc = add nsw i32 %tmp13, 1 ; CHECK: store i32 %inc, i32* %NumExceptions, align 4 -; CHECK: %7 = load i32* %e, align 4 -; CHECK: %8 = load i32* %i, align 4 -; CHECK: %cmp1 = icmp eq i32 %7, %8 +; CHECK: %tmp14 = load i32* %e, align 4 +; CHECK: %tmp15 = load i32* %i, align 4 +; CHECK: %cmp1 = icmp eq i32 %tmp14, %tmp15 ; CHECK: br i1 %cmp1, label %if.then, label %if.else ; ; CHECK: if.then: ; preds = %catch.entry -; CHECK: %9 = load i32* %e, align 4 +; CHECK: %tmp16 = load i32* %e, align 4 ; CHECK: %b = getelementptr inbounds %struct.SomeData* %Data, i32 0, i32 1 -; CHECK: %10 = load i32* %b, align 4 -; CHECK: %add2 = add nsw i32 %10, %9 +; CHECK: %tmp17 = load i32* %b, align 4 +; CHECK: %add2 = add nsw i32 %tmp17, %tmp16 ; CHECK: store i32 %add2, i32* %b, align 4 ; CHECK: br label %if.end ; ; CHECK: if.else: ; preds = %catch.entry -; CHECK: %11 = load i32* %e, align 4 +; CHECK: %tmp18 = load i32* %e, align 4 ; CHECK: %a3 = getelementptr inbounds %struct.SomeData* %Data, i32 0, i32 0 -; CHECK: %12 = load i32* %a3, align 4 -; CHECK: %add4 = add nsw i32 %12, %11 +; CHECK: %tmp19 = load i32* %a3, align 4 +; CHECK: %add4 = add nsw i32 %tmp19, %tmp18 ; CHECK: store i32 %add4, i32* %a3, align 4 ; CHECK: br label %if.end ; @@ -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()