Author: rnk Date: Tue Oct 6 20:07:13 2015 New Revision: 249497 URL: http://llvm.org/viewvc/llvm-project?rev=249497&view=rev Log: [SEH] Fix x64 __exception_code in __except blocks
Use llvm.eh.exceptioncode to get the code out of EAX for x64. For 32-bit, the filter is responsible for storing it to memory for us. Modified: cfe/trunk/lib/CodeGen/CGException.cpp cfe/trunk/test/CodeGen/exceptions-seh-new.c Modified: cfe/trunk/lib/CodeGen/CGException.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=249497&r1=249496&r2=249497&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGException.cpp (original) +++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Oct 6 20:07:13 2015 @@ -1898,14 +1898,21 @@ void CodeGenFunction::ExitSEHTryStmt(con ExceptBB = createBasicBlock("__except"); Builder.CreateCatchRet(CPI, ExceptBB); EmitBlock(ExceptBB); - } - - // On Win64, the exception pointer is the exception code. Copy it to the slot. - if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) { - llvm::Value *Code = - Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy); - Code = Builder.CreateTrunc(Code, Int32Ty); - Builder.CreateStore(Code, SEHCodeSlotStack.back()); + // On Win64, the exception code is returned in EAX. Copy it into the slot. + if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) { + llvm::Function *SEHCodeIntrin = + CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode); + llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI}); + Builder.CreateStore(Code, SEHCodeSlotStack.back()); + } + } else { + // On Win64, the exception pointer is the exception code. Copy it to the slot. + if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) { + llvm::Value *Code = + Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy); + Code = Builder.CreateTrunc(Code, Int32Ty); + Builder.CreateStore(Code, SEHCodeSlotStack.back()); + } } // Emit the __except body. Modified: cfe/trunk/test/CodeGen/exceptions-seh-new.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-new.c?rev=249497&r1=249496&r2=249497&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/exceptions-seh-new.c (original) +++ cfe/trunk/test/CodeGen/exceptions-seh-new.c Tue Oct 6 20:07:13 2015 @@ -265,4 +265,25 @@ void finally_capture_twice(int x) { // CHECK-NEXT: store i32 [[T0]], i32* [[Z]], align 4 // CHECK-NEXT: ret void +int exception_code_in_except(void) { + __try { + try_body(0, 0, 0); + } __except(1) { + return _exception_code(); + } +} + +// CHECK-LABEL: define i32 @exception_code_in_except() +// CHECK: %[[ret_slot:[^ ]*]] = alloca i32 +// CHECK: %[[code_slot:[^ ]*]] = alloca i32 +// CHECK: invoke void @try_body(i32 0, i32 0, i32* null) +// CHECK: %[[pad:[^ ]*]] = catchpad +// CHECK: catchret %[[pad]] +// X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]]) +// X64: store i32 %[[code]], i32* %[[code_slot]] +// CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]] +// CHECK: store i32 %[[ret1]], i32* %[[ret_slot]] +// CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]] +// CHECK: ret i32 %[[ret2]] + // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits