r249497 - [SEH] Fix x64 __exception_code in __except blocks

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 6 18:07:14 PDT 2015


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.*}} }




More information about the cfe-commits mailing list