[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC option -EHa)

2020-05-20 Thread Ten Tzen via Phabricator via cfe-commits
tentzen created this revision.
tentzen added reviewers: andrew.w.kaylor, rnk, majnemer, pengfei, eli.friedman, 
JosephTremoulet, asmith.
Herald added subscribers: llvm-commits, cfe-commits, jdoerfert, kbarton, 
hiraditya, kristof.beyls, nemanjai.
Herald added projects: clang, LLVM.

This patch adds the support of Hardware Exception for Microsoft Windows SEH 
(Structured Exception Handling).  This is the first step of this project; only 
X86_64 target is enabled in this patch. We will add AArch64 & ARM and X86 
targets later.

Compiler options:
For clang-cl.exe, the option is -EHa, the same as MSVC.
For clang.exe, the extra option is -feh-asynch, plus -triple x86_64-windows  
-fexceptions and -fcxx-exceptions as usual.

NOTE: : Without the -EHa or -feh-asynch, this patch is a NO-DIFF change.

The rules for C code:
For C-code, one way (MSVC approach) to achieve SEH -EHa semantic is to follow 
three rules. First, no exception can move in or out of _try region., i.e., no 
"potential faulty instruction can be moved across _try boundary. Second, the 
order of exceptions for instructions 'directly' under a _try must be preserved 
(not applied to those in callees). Finally, global states (local/global/heap 
variables) that can be read outside of _try region must be updated in memory 
(not just in register) before the subsequent exception occurs.

The impact to C++ code:
Although SEH is a feature for C code, -EHa does have a profound effect on C++ 
side. When a C++ function (in the same compilation unit with option -EHa ) is 
called by a SEH C function, a hardware exception occurs in C++ code can also be 
handled properly by an upstream SEH _try-handler or a C++ catch(…). As such, 
when that happens in the middle of an object’s life scope, the dtor must be 
invoked the same way as C++ Synchronous Exception during unwinding process.

Design:
A natural way to achieve the rules above in LLVM today is to allow an EH edge 
added on memory/computation instruction (previous iload/istore idea) so that 
exception path is modeled in Flow graph preciously. However, tracking every 
single memory instruction and potential faulty instruction can create many 
Invokes, complicate flow graph and possibly result in negative performance 
impact for downstream optimization and code generation. Making all 
optimizations be aware of the new semantic is also substantial.

This design does not intend to model exception path at instruction level. 
Instead, the proposed design tracks and reports EH state at BLOCK-level to 
reduce the complexity of flow graph and minimize the performance-impact on CPP 
code under -EHa option.

One key element of this design is the ability to compute State number at 
block-level. Our algorithm is based on the following rationales:

A _try scope is always a SEME (Single Entry Multiple Exits) region as jumping 
into a _try is not allowed.
The single entry must start with a seh_try_begin() invoke with a correct State 
number that is the initial state of the SEME.
Through control-flow, state number is propagated into all blocks.
Side exits marked by seh_try_end() will unwind to parent state based on 
existing SEHUnwindMap[].
Side exits can ONLY jump into parent scopes (lower state number).
Thus, when a block succeeds various states from its predecessors, the lowest 
State triumphs others.
If some exits flow to unreachable, propagation on those paths terminate, not 
affecting remaining blocks.
For CPP code, object lifetime region is usually a SEME as SEH _try. However 
there is one rare exception: jumping into a lifetime that has Dtor but has no 
Ctor is warned, but allowed:

  note: jump bypasses variable with a non-trivial destructor

In this case, this region is actually a MEME (multiple entry multiple exits). 
Our solution is to inject a seh_try_begin() invoke in the side entry block to 
ensure a correct State.

Implementation:
Detailed implementation described below.

- Two intrinsic are created to track CPP object scopes; eha_scope_begin() and 
eha_scope_end(). _scope_begin() is immediately added after ctor() is called and 
EHStack is pushed. So it must be an invoke, not a call. With that it's also 
guaranteed an EH-cleanup-pad is created regardless whether there exists a call 
in this scope. _scope_end is added before dtor(). These two intrinsics make the 
computation of Block-State possible in downstream code gen pass, even in the 
presence of ctor/dtor inlining.

- Two intrinsic, seh_try_begin() and seh_try_end(), are added for C-code to 
mark _try boundary and to prevent from exceptions being moved across _try 
boundary.

- All memory instructions inside a _try are considered as 'volatile' to assure 
2nd and 3rd rules for C-code above. This is a little sub-optimized. But it's 
acceptable as the amount of code directly under _try is very small.

- For both C++ & C-code, the state of each block is computed at the same place 
in BE (WinEHPreparing pass) where all other EH tables/maps are calculated. In 
add

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC option -EHa)

2020-05-21 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 265442.
tentzen added a comment.

fixed formats


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/include/llvm/CodeGen/SelectionDAGISel.h
  llvm/include/llvm/CodeGen/WinEHFuncInfo.h
  llvm/include/llvm/IR/BasicBlock.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/EHPersonalities.cpp
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/AsmPrinter/WinException.cpp
  llvm/lib/CodeGen/BranchFolding.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
  llvm/lib/CodeGen/WinEHPrepare.cpp
  llvm/lib/IR/BasicBlock.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/test/CodeGen/X86/windows-seh-EHa-CppCatchDotDotDot.ll
  llvm/test/CodeGen/X86/windows-seh-EHa-CppDtors01.ll
  llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll

Index: llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll
@@ -0,0 +1,226 @@
+; RUN: llc -verify-machineinstrs < %s | FileCheck %s
+
+; CHECK-LABEL: "?fin$0@0@main@@"
+; CHECK:  .seh_handlerdata
+; CHECK:  .set ".L?fin$0@0@main@@$parent_frame_offset", 48
+; CHECK-NEXT:.long   (.Llsda_end1-.Llsda_begin1)/16 
+; CHECK-NEXT: .Llsda_begin1:
+; CHECK-NEXT:.long   .Ltmp
+; CHECK-NEXT:.long   .Ltmp
+; CHECK-NEXT:.long   "?dtor$
+; CHECK-NEXT:.long   0
+; CHECK-NEXT: .Llsda_end1:
+
+; ModuleID = 'windows-seh-EHa-TryInFinally.cpp'
+source_filename = "windows-seh-EHa-TryInFinally.cpp"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc"
+
+$"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@" = comdat any
+
+$"??_C@_0BN@HHKJHLBE@?5?5In?5Inner?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0BN@HAIIIOKI@?5?5In?5outer?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0BJ@OJMMAGCD@?5?5In?5outer?5_try?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0CG@ENDJHCGA@?5?9?9?9?5In?5outer?5except?5handler?5i?5?$DN@" = comdat any
+
+@"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@" = linkonce_odr dso_local unnamed_addr constant [40 x i8] c" --- Test _Try in _finally --- i = %d \0A\00", comdat, align 1
+@"??_C@_0BN@HHKJHLBE@?5?5In?5Inner?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [29 x i8] c"  In Inner _finally i = %d \0A\00", comdat, align 1
+@"??_C@_0BN@HAIIIOKI@?5?5In?5outer?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [29 x i8] c"  In outer _finally i = %d \0A\00", comdat, align 1
+@"??_C@_0BJ@OJMMAGCD@?5?5In?5outer?5_try?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [25 x i8] c"  In outer _try i = %d \0A\00", comdat, align 1
+@"??_C@_0CG@ENDJHCGA@?5?9?9?9?5In?5outer?5except?5handler?5i?5?$DN@" = linkonce_odr dso_local unnamed_addr constant [38 x i8] c" --- In outer except handler i = %d \0A\00", comdat, align 1
+
+; Function Attrs: noinline norecurse optnone
+define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
+entry:
+  %retval = alloca i32, align 4
+  %i = alloca i32, align 4
+  %__exception_code = alloca i32, align 4
+  call void (...) @llvm.localescape(i32* %i)
+  store i32 0, i32* %retval, align 4
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+  %0 = load i32, i32* %i, align 4
+  %cmp = icmp slt i32 %0, 3
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+  %1 = load i32, i32* %i, align 4
+  call void (...) @"?printf@@YAXZZ"(i8* getelementptr inbounds ([40 x i8], [40 x i8]* @"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@", i64 0, i64 0), i32 %1)
+  invoke void @llvm.seh.try.begin()
+  to label %invoke.cont unwind label %catch.dispatch
+
+invoke.cont:  ; preds = %for.body
+  invoke void @llvm.seh.try.begin()
+  to label %invoke.cont1 unwind label %ehcleanup
+
+invoke.cont1:  

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC option -EHa)

2020-05-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 265672.
tentzen added a comment.

avoid lint warnings and lint hang on Windows


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/include/llvm/CodeGen/SelectionDAGISel.h
  llvm/include/llvm/CodeGen/WinEHFuncInfo.h
  llvm/include/llvm/IR/BasicBlock.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/Analysis/EHPersonalities.cpp
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/AsmPrinter/WinException.cpp
  llvm/lib/CodeGen/BranchFolding.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
  llvm/lib/CodeGen/WinEHPrepare.cpp
  llvm/lib/IR/BasicBlock.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/test/CodeGen/X86/windows-seh-EHa-CppCatchDotDotDot.ll
  llvm/test/CodeGen/X86/windows-seh-EHa-CppDtors01.ll
  llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll

Index: llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/windows-seh-EHa-TryInFinally.ll
@@ -0,0 +1,226 @@
+; RUN: llc -verify-machineinstrs < %s | FileCheck %s
+
+; CHECK-LABEL: "?fin$0@0@main@@"
+; CHECK:  .seh_handlerdata
+; CHECK:  .set ".L?fin$0@0@main@@$parent_frame_offset", 48
+; CHECK-NEXT:.long   (.Llsda_end1-.Llsda_begin1)/16 
+; CHECK-NEXT: .Llsda_begin1:
+; CHECK-NEXT:.long   .Ltmp
+; CHECK-NEXT:.long   .Ltmp
+; CHECK-NEXT:.long   "?dtor$
+; CHECK-NEXT:.long   0
+; CHECK-NEXT: .Llsda_end1:
+
+; ModuleID = 'windows-seh-EHa-TryInFinally.cpp'
+source_filename = "windows-seh-EHa-TryInFinally.cpp"
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc"
+
+$"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@" = comdat any
+
+$"??_C@_0BN@HHKJHLBE@?5?5In?5Inner?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0BN@HAIIIOKI@?5?5In?5outer?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0BJ@OJMMAGCD@?5?5In?5outer?5_try?5i?5?$DN?5?$CFd?5?6?$AA@" = comdat any
+
+$"??_C@_0CG@ENDJHCGA@?5?9?9?9?5In?5outer?5except?5handler?5i?5?$DN@" = comdat any
+
+@"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@" = linkonce_odr dso_local unnamed_addr constant [40 x i8] c" --- Test _Try in _finally --- i = %d \0A\00", comdat, align 1
+@"??_C@_0BN@HHKJHLBE@?5?5In?5Inner?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [29 x i8] c"  In Inner _finally i = %d \0A\00", comdat, align 1
+@"??_C@_0BN@HAIIIOKI@?5?5In?5outer?5_finally?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [29 x i8] c"  In outer _finally i = %d \0A\00", comdat, align 1
+@"??_C@_0BJ@OJMMAGCD@?5?5In?5outer?5_try?5i?5?$DN?5?$CFd?5?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [25 x i8] c"  In outer _try i = %d \0A\00", comdat, align 1
+@"??_C@_0CG@ENDJHCGA@?5?9?9?9?5In?5outer?5except?5handler?5i?5?$DN@" = linkonce_odr dso_local unnamed_addr constant [38 x i8] c" --- In outer except handler i = %d \0A\00", comdat, align 1
+
+; Function Attrs: noinline norecurse optnone
+define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
+entry:
+  %retval = alloca i32, align 4
+  %i = alloca i32, align 4
+  %__exception_code = alloca i32, align 4
+  call void (...) @llvm.localescape(i32* %i)
+  store i32 0, i32* %retval, align 4
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+  %0 = load i32, i32* %i, align 4
+  %cmp = icmp slt i32 %0, 3
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+  %1 = load i32, i32* %i, align 4
+  call void (...) @"?printf@@YAXZZ"(i8* getelementptr inbounds ([40 x i8], [40 x i8]* @"??_C@_0CI@MDFPIOJJ@?5?9?9?9?5Test?5_Try?5in?5_finally?5?9?9?9?5i@", i64 0, i64 0), i32 %1)
+  invoke void @llvm.seh.try.begin()
+  to label %invoke.cont unwind label %catch.dispatch
+
+invoke.cont:  ; preds = %for.body
+  invoke void @llvm.seh.try.begin()
+  to label %invoke.cont1 unwind label %ehcleanup
+
+invo

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC option -EHa)

2020-05-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 3 inline comments as done.
tentzen added a comment.

In D80344#2051127 , @lebedev.ri wrote:

> This should likely be at least 3 patches: llvm middle-end, llvm codegen, 
> clang.
>  Langref changes missing for new intrinsics.
>  Please post all patches with full context (`-U9`)


OK, makes sense. I will separate it to at least two patches, one Clang and one 
LLVM CodeGen as there is not much change in middle-end & Opt.
thank you for pointing out missing the change in Langref.rst.  I was thinking 
to update docs/ExceptionHandling.rst after this patch is accepted.  Do you 
think this types of intrinsic should be described in Langref?
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-05-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 265812.
tentzen retitled this revision from "[Windows SEH]: HARDWARE EXCEPTION HANDLING 
(MSVC option -EHa)" to "[Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) 
- Part 1".
tentzen edited the summary of this revision.
tentzen added a reviewer: lebedev.ri.
tentzen added a comment.

Per Roman Lebedev's feedback, divide the patch into Clang and LLVM.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::eha_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::eha_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::eha_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::eha_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_eha_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_eha_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i
+// CHECK-NEXT: i32 %[[src]]
+// CHECK: invoke void @llvm.seh.try.end()
+// CHECK: invoke void @llvm.seh.try.end()
+
+// CHECK: define internal void @"?fin$0@0@main@@"(i8 %abnormal_termination
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: invoke void @llvm.seh.try.end()
+
+// ***

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-05-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

> It may be helpful (even for the reviewers) to first specify their behavior,
>  instead of writing that after-the-fact "backwardly" based on the 
> implementation.

For reviewers, the purpose of those intrinsic are described in Summary section:

- Two intrinsic are created to track CPP object scopes; eha_scope_begin() and 
eha_scope_end(). _scope_begin() is immediately added after ctor() is called and 
EHStack is pushed. So it must be an invoke, not a call. With that it's also 
guaranteed an EH-cleanup-pad is created regardless whether there exists a call 
in this scope. _scope_end is added before dtor(). These two intrinsics make the 
computation of Block-State possible in downstream code gen pass, even in the 
presence of ctor/dtor inlining.
- Two intrinsic, seh_try_begin() and seh_try_end(), are added for C-code to 
mark _try boundary and to prevent from exceptions being moved across _try 
boundary.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-05-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 265819.
tentzen removed a reviewer: lebedev.ri.
tentzen added a comment.

fixed tidy warnings


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::eha_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::eha_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::eha_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::eha_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_eha_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_eha_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i
+// CHECK-NEXT: i32 %[[src]]
+// CHECK: invoke void @llvm.seh.try.end()
+// CHECK: invoke void @llvm.seh.try.end()
+
+// CHECK: define internal void @"?fin$0@0@main@@"(i8 %abnormal_termination
+// CHECK: invoke void @llvm.seh.try.begin()
+// CHECK: invoke void @llvm.seh.try.end()
+
+// *
+// Abstract: Test __Try in __finally under SEH -EHa option
+void printf(...);
+int volatile *NullPtr = 0;
+int main() {
+  for (int i = 0; i < 3; i++) {
+printf(" --- Test _Try in _finally --

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-05-26 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 266374.
tentzen added a comment.

update LangRef.rst for new intrinsics


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::eha_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::eha_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::eha_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::eha_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_eha_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_eha_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,59 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled with Windows SEH Asynchrous Exception option,
+-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mark _try
+boundary and to prevent from potential exceptions being moved across boundary.
+
+'``llvm.eha.scope.begin``' and '``llvm.eha.scope.end``' Intrinsics
+

[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-06-02 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi, does this look good? or is there any other concern?
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-06-02 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Is there any feedback? thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-11 Thread Ten Tzen via Phabricator via cfe-commits
tentzen created this revision.
tentzen added reviewers: rnk, eli.friedman, JosephTremoulet, asmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Per Windows SEH Spec, except _leave, all other early exits of a _try 
(goto/return/continue/break) are considered abnormal exits.  In those cases, 
the first parameter passes to its _finally funclet should be TRUE to indicate 
an abnormal-termination.

One way to implement abnormal exits in _try is to invoke Windows runtime 
_local_unwind() (MSVC approach) that will invoke _dtor funclet where 
abnormal-termination flag is always TRUE when calling _finally.  Obviously this 
approach is less optimal and is complicated to implement in Clang.

Clang today has a NormalCleanupDestSlot mechanism to dispatch multiple exits at 
the end of _try.  Since  _leave (or try-end fall-through) is always Indexed 
with 0 in that NormalCleanupDestSlot,  this fix takes the advantage of that 
mechanism and just passes NormalCleanupDest ID as 1st Arg to _finally.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h


Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -160,7 +160,8 @@
   enum {
 F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasSehAbnormalExits = 0x8
   };
   unsigned flags;
 
@@ -179,6 +180,9 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
+
+  bool hasSehAbnormalExits() const { return flags & F_HasSehAbnormalExits; 
}
+  void setHasSehAbnormalExits() { flags |= F_HasSehAbnormalExits; }
 };
 
 
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,18 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasSehAbnormalExits()) {
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value* Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  IsForEH = CGF.Builder.CreateTrunc(Load, CGM.Int8Ty);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasSehAbnormalExits();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);


Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -160,7 +160,8 @@
   enum {
 F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasSehAbnormalExits = 0x8
   };
   unsigned flags;
 
@@ -179,6 +180,9 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
+
+  bool hasSehAbnormalExits() const { return flags & F_HasSehAbnormalExits; }
+  void setHasSehAbnormalExits() { flags |= F_HasSehAbnormalExits; }
 };
 
 
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,18 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indi

[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-11 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 256836.
tentzen marked an inline comment as done.
tentzen added a comment.

Per Eli's feedbacks:
(1) a test case (windows-seh-abnormal-exit.c) is added under clang\test\CodeGen 
directory.  
(2) an assert is added to catch the extremely rare case that the number of 
JumpDests in a function is greater than 255.  The max. number of JumpDests is 1 
(return) + 2*M + N, where M is the number of for/while-loops and N is the 
number of Goto targets.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/test/CodeGen/windows-seh-abnormal-exits.c

Index: clang/test/CodeGen/windows-seh-abnormal-exits.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-abnormal-exits.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-windows -Wno-implicit-function-declaraton -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[src:[0-9-]+]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
+// CHECK-NEXT: %[[src2:[0-9-]+]] = trunc i32 %cleanup.dest to i8
+// CHECK-NEXT: call void @"?fin$0@0@seh_abnormal_exits@@"(i8 %[[src2]], i8* %[[src]])
+
+void seh_abnormal_exits(int *Counter) {
+  for (int i = 0; i < 5; i++) {
+__try {
+  if (i == 0)
+continue;   // abnormal termination
+  else if (i == 1)
+goto t10;   // abnormal termination
+  else if (i == 2)
+__leave;  // normal execution
+  else if (i == 4)
+return;  // abnormal termination
+}
+__finally {
+  if (AbnormalTermination()) {
+*Counter += 1;
+  }
+}
+  t10:;
+  }
+  return; // *Counter == 3
+}
+
Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -158,9 +158,10 @@
 /// Generation flags.
 class Flags {
   enum {
-F_IsForEH = 0x1,
+F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasSehAbnormalExits = 0x8,
   };
   unsigned flags;
 
@@ -179,8 +180,10 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
-};
 
+  bool hasSehAbnormalExits() const { return flags & F_HasSehAbnormalExits; }
+  void setHasSehAbnormalExits() { flags |= F_HasSehAbnormalExits; }
+};
 
 /// Emit the cleanup.  For normal cleanups, this is run in the
 /// same EH context as when the cleanup was pushed, i.e. the
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,19 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasSehAbnormalExits()) {
+  assert(CGF.NextCleanupDestIndex < 256 && " JumpDest Index exceeds 255");
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value* Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  IsForEH = CGF.Builder.CreateTrunc(Load, CGM.Int8Ty);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasSehAbnormalExits();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 256840.
tentzen marked an inline comment as done.
tentzen added a comment.

Add option  -fms-extensions in test case


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/test/CodeGen/windows-seh-abnormal-exits.c

Index: clang/test/CodeGen/windows-seh-abnormal-exits.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-abnormal-exits.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[src:[0-9-]+]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
+// CHECK-NEXT: %[[src2:[0-9-]+]] = trunc i32 %cleanup.dest to i8
+// CHECK-NEXT: call void @"?fin$0@0@seh_abnormal_exits@@"(i8 %[[src2]], i8* %[[src]])
+
+void seh_abnormal_exits(int *Counter) {
+  for (int i = 0; i < 5; i++) {
+__try {
+  if (i == 0)
+continue;   // abnormal termination
+  else if (i == 1)
+goto t10;   // abnormal termination
+  else if (i == 2)
+__leave;  // normal execution
+  else if (i == 4)
+return;  // abnormal termination
+}
+__finally {
+  if (AbnormalTermination()) {
+*Counter += 1;
+  }
+}
+  t10:;
+  }
+  return; // *Counter == 3
+}
+
Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -158,9 +158,10 @@
 /// Generation flags.
 class Flags {
   enum {
-F_IsForEH = 0x1,
+F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasSehAbnormalExits = 0x8,
   };
   unsigned flags;
 
@@ -179,8 +180,10 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
-};
 
+  bool hasSehAbnormalExits() const { return flags & F_HasSehAbnormalExits; }
+  void setHasSehAbnormalExits() { flags |= F_HasSehAbnormalExits; }
+};
 
 /// Emit the cleanup.  For normal cleanups, this is run in the
 /// same EH context as when the cleanup was pushed, i.e. the
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,19 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasSehAbnormalExits()) {
+  assert(CGF.NextCleanupDestIndex < 256 && " JumpDest Index exceeds 255");
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value* Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  IsForEH = CGF.Builder.CreateTrunc(Load, CGM.Int8Ty);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasSehAbnormalExits();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D77936#1976938 , @efriedma wrote:

> Instead of asserting there are less than 256 cleanup destinations, can you 
> emit an icmp against zero, or something like that?


I did consider that. but it splits the block and induces one compare and one 
branch in _try exit sequence for something that will not happen in RWC.  And 
it's hard for Optimizer to deal with it.  Optimizer can probably can 
tail-duplicate each path at the expense of code size which I don't think LLVM 
would do today.  Do you really think it's worth to split the block here? thanks




Comment at: clang/lib/CodeGen/CGException.cpp:1651
+  llvm::Value* Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  IsForEH = CGF.Builder.CreateTrunc(Load, CGM.Int8Ty);
+}

efriedma wrote:
> Is just truncating the value really correct?  What's the possible range of 
> values stored in getNormalCleanupDestSlot()?
Good question! 
Usually the number in NormalCleanupDestSlot is single digit (or at most 
double-digit) , the totoal number of Jump Destinations 
(return/goto/break/continue/..)  in the function.  
I thought about widening 1st arg from CHAR to unsigned, but dropped the idea as 
it seems unnecessary.  Yes, someone can write a code to make more than 255 
Jumps in a function,  but it’s unlikely to happen in real world code.  What do 
you think?
I can go either way..
For sure, we can add an assert to catch it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen created this revision.
tentzen added reviewers: rnk, eli.friedman, JosephTremoulet, asmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change fixed a SEH bug (exposed by test58 & test61 in MSVC test xcpt4u.c);
when an Except-filter is located inside a finally, the frame-pointer generated 
today via intrinsic @llvm.eh.recoverfp is the frame-pointer of the immediate 
parent  _finally, not the frame-ptr of outermost host function.

The fix is to retrieve the Establisher's frame-pointer that was previously 
saved in parent's frame.  
The prolog of a filter inside a _finally should be like:

  %0 = call i8* @llvm.eh.recoverfp(i8* bitcast (@"?fin$0@0@main@@"), i8* 
%frame_pointer)
  %1 = call i8* @llvm.localrecover(i8* bitcast (@"?fin$0@0@main@@"), i8* %0, 
i32 0)
  %2 = bitcast i8* %1 to i8**
  %3 = load i8*, i8** %2, align 8


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77982

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/windows-seh-filter-inFinally.c

Index: clang/test/CodeGen/windows-seh-filter-inFinally.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-filter-inFinally.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer)
+// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0)
+// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8**
+// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8
+
+int
+main(int argc, char *argv[])
+{
+int Counter = 0;
+//
+// Try/except within the finally clause of a try/finally.
+//
+__try {
+  Counter -= 1;
+}
+__finally {
+  __try {
+Counter += 2;
+// RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
+  } __except(Counter) {
+__try {
+  Counter += 3;
+}
+__finally {
+  if (abnormal_termination() == 1) {
+Counter += 5;
+  }
+}
+  }
+}
+// expect Counter == 9
+return 1;
+}
+
Index: clang/lib/CodeGen/CodeGenFunction.h
===
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -367,6 +367,9 @@
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
+  // For outliner helper only
+  CodeGenFunction *ParentCGF = nullptr;
+
   typedef std::pair ComplexPairTy;
   LoopInfoStack LoopStack;
   CGBuilderTy Builder;
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1794,6 +1794,40 @@
 llvm::Constant *ParentI8Fn =
 llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
+
+// if the parent is a _finally, need to retrive Establisher's FP,
+//  2nd paramenter, saved & named frame_pointer in parent's frame
+if (ParentCGF.ParentCGF != NULL) {
+  // Locate and escape Parent's frame_pointer.addr alloca
+  llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
+  for (llvm::Instruction &I : ParentCGF.CurFn->getEntryBlock()) {
+llvm::AllocaInst *II = dyn_cast(&I);
+if (II && II->getName().startswith("frame_pointer")) {
+  FramePtrAddrAlloca = II;
+  break;
+}
+  }
+  assert(FramePtrAddrAlloca);
+  auto InsertPair = ParentCGF.EscapedLocals.insert(
+  std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
+  int FrameEscapeIdx = InsertPair.first->second;
+
+  // an example of a filter's prolog::
+  // %0 = call i8 * @llvm.eh.recoverfp(i8 * bitcast(@"?fin$0@0@main@@"), i8 * %frame_pointer)
+  // %1 = call i8 * @llvm.localrecover(i8 * bitcast(@"?fin$0@0@main@@"), i8 * %0, i32 0)
+  // %2 = bitcast i8 * %1 to i8 **
+  // %3 = load i8*, i8 * *%2, align 8
+  //   ==> %3 is the frame-pointer of outermost host function
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =
+  llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+  ParentFP = Builder.CreateCall(
+  FrameRecoverFn, {ParentI8Fn, ParentFP,
+   llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+  ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy);
+  ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign()));
+}
   }
 
   // Create llvm.localrecover calls for all capt

[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 256896.
tentzen added a comment.

Fixed the format at comment lines


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/windows-seh-filter-inFinally.c

Index: clang/test/CodeGen/windows-seh-filter-inFinally.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-filter-inFinally.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer)
+// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0)
+// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8**
+// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8
+
+int
+main(int argc, char *argv[])
+{
+int Counter = 0;
+//
+// Try/except within the finally clause of a try/finally.
+//
+__try {
+  Counter -= 1;
+}
+__finally {
+  __try {
+Counter += 2;
+// RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
+  } __except(Counter) {
+__try {
+  Counter += 3;
+}
+__finally {
+  if (abnormal_termination() == 1) {
+Counter += 5;
+  }
+}
+  }
+}
+// expect Counter == 9
+return 1;
+}
+
Index: clang/lib/CodeGen/CodeGenFunction.h
===
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -367,6 +367,9 @@
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
+  // For outliner helper only
+  CodeGenFunction *ParentCGF = nullptr;
+
   typedef std::pair ComplexPairTy;
   LoopInfoStack LoopStack;
   CGBuilderTy Builder;
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1794,6 +1794,40 @@
 llvm::Constant *ParentI8Fn =
 llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
+
+// if the parent is a _finally, need to retrive Establisher's FP,
+//  2nd paramenter, saved & named frame_pointer in parent's frame
+if (ParentCGF.ParentCGF != NULL) {
+  // Locate and escape Parent's frame_pointer.addr alloca
+  llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
+  for (llvm::Instruction &I : ParentCGF.CurFn->getEntryBlock()) {
+llvm::AllocaInst *II = dyn_cast(&I);
+if (II && II->getName().startswith("frame_pointer")) {
+  FramePtrAddrAlloca = II;
+  break;
+}
+  }
+  assert(FramePtrAddrAlloca);
+  auto InsertPair = ParentCGF.EscapedLocals.insert(
+  std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
+  int FrameEscapeIdx = InsertPair.first->second;
+
+  // an example of a filter's prolog::
+  // %0 = call i8* @llvm.eh.recoverfp(bitcast(@"?fin$0@0@main@@"),..)
+  // %1 = call i8* @llvm.localrecover(bitcast(@"?fin$0@0@main@@"),..)
+  // %2 = bitcast i8* %1 to i8**
+  // %3 = load i8*, i8* *%2, align 8
+  //   ==> %3 is the frame-pointer of outermost host function
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =
+  llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+  ParentFP = Builder.CreateCall(
+  FrameRecoverFn, {ParentI8Fn, ParentFP,
+   llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+  ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy);
+  ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign()));
+}
   }
 
   // Create llvm.localrecover calls for all captures.
@@ -1992,6 +2026,7 @@
 
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
+  HelperCGF.ParentCGF = this;
   if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
 // Outline the finally block.
 llvm::Function *FinallyFunc =
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D77936#1976984 , @efriedma wrote:

> I'm not concerned about the performance implications of whatever approach we 
> take here.  In the worst case, an "icmp+zext" corresponds to two extra 
> arithmetic instructions; that's not enough to matter.  And I expect usually 
> it'll get optimized away.
>
> I'd prefer to avoid exposing our cleanup numbering to user code, if possible. 
>  The Microsoft documentation says it returns 0 or 1.


OK,  will do..
thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 256906.
tentzen added a comment.

Per Eli's suggestion,
Use icmp (and zext) to check the JumpDest index, instead of directly passing 
the Index to _finally().


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/test/CodeGen/windows-seh-abnormal-exits.c

Index: clang/test/CodeGen/windows-seh-abnormal-exits.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-abnormal-exits.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[src:[0-9-]+]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
+// CHECK-NEXT: %[[src2:[0-9-]+]] = icmp ne i32 %cleanup.dest, 0
+// CHECK-NEXT: %[[src3:[0-9-]+]] = zext i1 %[[src2]] to i8
+// CHECK-NEXT: call void @"?fin$0@0@seh_abnormal_exits@@"(i8 %[[src3]], i8* %[[src]])
+
+void seh_abnormal_exits(int *Counter) {
+  for (int i = 0; i < 5; i++) {
+__try {
+  if (i == 0)
+continue;   // abnormal termination
+  else if (i == 1)
+goto t10;   // abnormal termination
+  else if (i == 2)
+__leave;  // normal execution
+  else if (i == 4)
+return;  // abnormal termination
+}
+__finally {
+  if (AbnormalTermination()) {
+*Counter += 1;
+  }
+}
+  t10:;
+  }
+  return; // *Counter == 3
+}
+
Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -158,9 +158,10 @@
 /// Generation flags.
 class Flags {
   enum {
-F_IsForEH = 0x1,
+F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasSehAbnormalExits = 0x8,
   };
   unsigned flags;
 
@@ -179,8 +180,10 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
-};
 
+  bool hasSehAbnormalExits() const { return flags & F_HasSehAbnormalExits; }
+  void setHasSehAbnormalExits() { flags |= F_HasSehAbnormalExits; }
+};
 
 /// Emit the cleanup.  For normal cleanups, this is run in the
 /// same EH context as when the cleanup was pushed, i.e. the
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,19 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasSehAbnormalExits()) {
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
+  IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasSehAbnormalExits();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-13 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 4 inline comments as done.
tentzen added inline comments.



Comment at: clang/lib/CodeGen/CGException.cpp:1798
+
+// if the parent is a _finally, need to retrive Establisher's FP,
+//  2nd paramenter, saved & named frame_pointer in parent's frame

efriedma wrote:
> Maybe worth expanding this comment a little, to explain that a "finally" 
> should have at most one localescape'ed variable.  (At least, that's my 
> understanding.)
ok, will add more explanation.



Comment at: clang/lib/CodeGen/CGException.cpp:1800
+//  2nd paramenter, saved & named frame_pointer in parent's frame
+if (ParentCGF.ParentCGF != NULL) {
+  // Locate and escape Parent's frame_pointer.addr alloca

efriedma wrote:
> nullptr
> 
> Do you actually use ParentCGF.ParentCGF anywhere?  If not, do you really need 
> to save it?
Yes, I used it in other patches.  I found it's very handy to have a way to 
access parent CGF & Function.



Comment at: clang/lib/CodeGen/CGException.cpp:1805
+llvm::AllocaInst *II = dyn_cast(&I);
+if (II && II->getName().startswith("frame_pointer")) {
+  FramePtrAddrAlloca = II;

efriedma wrote:
> Using the name isn't reliable. You should be using data stored somewhere in 
> the CodeGenFunction or something like that.
good sense.  will update it.



Comment at: clang/lib/CodeGen/CGException.cpp:1822
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =

efriedma wrote:
> Is there some reason you can't reuse recoverAddrOfEscapedLocal here?
because recoverAddrOfEscapedLocal() is used to get escaped locals of outermost 
frame.  The escaped frame-pointer we are looking for here is in _finally frame, 
not outermost frame.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-13 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 256942.
tentzen added a comment.

Remove hard-code name "frame-pointer". 
get the name from 2nd Arg of the _finally().


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/windows-seh-filter-inFinally.c

Index: clang/test/CodeGen/windows-seh-filter-inFinally.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-filter-inFinally.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer)
+// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0)
+// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8**
+// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8
+
+int
+main(int argc, char *argv[])
+{
+int Counter = 0;
+//
+// Try/except within the finally clause of a try/finally.
+//
+__try {
+  Counter -= 1;
+}
+__finally {
+  __try {
+Counter += 2;
+// RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
+  } __except(Counter) {
+__try {
+  Counter += 3;
+}
+__finally {
+  if (abnormal_termination() == 1) {
+Counter += 5;
+  }
+}
+  }
+}
+// expect Counter == 9
+return 1;
+}
+
Index: clang/lib/CodeGen/CodeGenFunction.h
===
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -367,6 +367,9 @@
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
+  // For EH/SEH outlined funclets, this field points to parent's CGF
+  CodeGenFunction *ParentCGF = nullptr;
+
   typedef std::pair ComplexPairTy;
   LoopInfoStack LoopStack;
   CGBuilderTy Builder;
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1794,6 +1794,46 @@
 llvm::Constant *ParentI8Fn =
 llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
+
+// if the parent is a _finally, the passed-in ParentFP is the FP
+// of parent _finally, not Establisher's FP (FP of outermost function).
+// Establkisher FP is 2nd paramenter passed into parent _finally.
+// Fortunately, it's always saved in parent's frame. The following
+// code retrieves it, and escapes it so that spill instruction won't be
+// optimized away.
+if (ParentCGF.ParentCGF != nullptr) {
+  // Locate and escape Parent's frame_pointer.addr alloca
+  llvm::Function *Fn = ParentCGF.CurFn;
+  StringRef Name = Fn->getArg(1)->getName();
+  llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
+  for (llvm::Instruction &I : ParentCGF.CurFn->getEntryBlock()) {
+llvm::AllocaInst *II = dyn_cast(&I);
+if (II && II->getName().startswith(Name)) {
+  FramePtrAddrAlloca = II;
+  break;
+}
+  }
+  assert(FramePtrAddrAlloca);
+  auto InsertPair = ParentCGF.EscapedLocals.insert(
+  std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
+  int FrameEscapeIdx = InsertPair.first->second;
+
+  // an example of a filter's prolog::
+  // %0 = call i8* @llvm.eh.recoverfp(bitcast(@"?fin$0@0@main@@"),..)
+  // %1 = call i8* @llvm.localrecover(bitcast(@"?fin$0@0@main@@"),..)
+  // %2 = bitcast i8* %1 to i8**
+  // %3 = load i8*, i8* *%2, align 8
+  //   ==> %3 is the frame-pointer of outermost host function
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =
+  llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+  ParentFP = Builder.CreateCall(
+  FrameRecoverFn, {ParentI8Fn, ParentFP,
+   llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+  ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy);
+  ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign()));
+}
   }
 
   // Create llvm.localrecover calls for all captures.
@@ -1992,6 +2032,7 @@
 
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
+  HelperCGF.ParentCGF = this;
   if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
 // Outline the finally block.
 llvm::Function *FinallyFunc =
__

[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-13 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 2 inline comments as done.
tentzen added inline comments.



Comment at: clang/lib/CodeGen/CGCleanup.cpp:848
 
   // Build a switch-out if we need it:
   //   - if there are branch-afters threaded through the scope

rnk wrote:
> Are we sure this is the right set of predicates? It seems like we'll get the 
> wrong flag in cases like:
> ```
>   __try {
> mayThrow();
> goto out;  // AbnormalTermination should be 1
>   } __finally {
> tearDown();
>   }
> out:
>   return 0;
> ```
> 
> I think these conditions are designed to avoid the switch when there is no 
> normal fallthrough destination (!HasFallthrough). I see clang emits no switch 
> for this C++ input:
> 
> ```
> $ cat t.cpp
> void mayThrow();
> struct Dtor {
>   ~Dtor();
> };
> int f() {
>   do {
> Dtor o;
> mayThrow();
> break;
>   } while (0);
>   return 0;
> }
> 
> $ clang t.cpp  -S -emit-llvm -fno-exceptions -o - | grep switch
> # empty
> ```
Yes, this test passed.

```
  store i32 3, i32* %cleanup.dest.slot, align 4
  %0 = call i8* @llvm.localaddress()
  %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
  %1 = icmp ne i32 %cleanup.dest, 0
  %2 = zext i1 %1 to i8
  call void @"?fin$0@0@Test84@@"(i8 %2, i8* %0)
  %cleanup.dest1 = load i32, i32* %cleanup.dest.slot, align 4
  switch i32 %cleanup.dest1, label %unreachable [
i32 3, label %out
  ]
```





Comment at: clang/lib/CodeGen/CGCleanup.cpp:863-864
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasSehAbnormalExits();
+

rnk wrote:
> This flag is set for any cleanup that needs to switch-out to multiple normal 
> destinations. You have named this an "seh abnormal exit", an exit that is 
> abnormal for the purposes of SEH, but I think it would be clearer to give the 
> flag a more general name.
> 
> Based on the existing terminology, maybe (F_)HasBranchAfter would be the 
> closest to what we are looking for?
my original implementation in https://github.com/tentzen/llvm-project is still 
using  (F_)HasBranchAfters.  it's renamed because I'm afraid it may mis-imply 
it to Scope.getNumBranchAfters(). 

Yes, Agree, it should not be SEH specific.  
how about F_HasExitSwitch?



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-14 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 257227.
tentzen added a comment.

Do not use name comparison to locate parent's alloca of frame-pointer-addr. 
search parent's LocalDeclMap instead.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/windows-seh-filter-inFinally.c

Index: clang/test/CodeGen/windows-seh-filter-inFinally.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-filter-inFinally.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer)
+// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0)
+// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8**
+// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8
+
+int
+main(int argc, char *argv[])
+{
+int Counter = 0;
+//
+// Try/except within the finally clause of a try/finally.
+//
+__try {
+  Counter -= 1;
+}
+__finally {
+  __try {
+Counter += 2;
+// RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
+  } __except(Counter) {
+__try {
+  Counter += 3;
+}
+__finally {
+  if (abnormal_termination() == 1) {
+Counter += 5;
+  }
+}
+  }
+}
+// expect Counter == 9
+return 1;
+}
+
Index: clang/lib/CodeGen/CodeGenFunction.h
===
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -367,6 +367,9 @@
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
+  // For EH/SEH outlined funclets, this field points to parent's CGF
+  CodeGenFunction *ParentCGF = nullptr;
+
   typedef std::pair ComplexPairTy;
   LoopInfoStack LoopStack;
   CGBuilderTy Builder;
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1794,6 +1794,48 @@
 llvm::Constant *ParentI8Fn =
 llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
+
+// if the parent is a _finally, the passed-in ParentFP is the FP
+// of parent _finally, not Establisher's FP (FP of outermost function).
+// Establkisher FP is 2nd paramenter passed into parent _finally.
+// Fortunately, it's always saved in parent's frame. The following
+// code retrieves it, and escapes it so that spill instruction won't be
+// optimized away.
+if (ParentCGF.ParentCGF != nullptr) {
+  // Locate and escape Parent's frame_pointer.addr alloca
+  // Depending on target, should be 1st/2nd one in LocalDeclMap.
+  // Let's just scan ImplicitParamDecl with VoidPtrTy.
+  llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
+  for (auto &I : ParentCGF.LocalDeclMap) {
+const VarDecl *D = cast(I.first);
+if (isa(D) &&
+D->getType() == getContext().VoidPtrTy) {
+  assert(D->getName().startswith("frame_pointer"));
+  FramePtrAddrAlloca = cast(I.second.getPointer());
+  break;
+}
+  }
+  assert(FramePtrAddrAlloca);
+  auto InsertPair = ParentCGF.EscapedLocals.insert(
+  std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
+  int FrameEscapeIdx = InsertPair.first->second;
+
+  // an example of a filter's prolog::
+  // %0 = call i8* @llvm.eh.recoverfp(bitcast(@"?fin$0@0@main@@"),..)
+  // %1 = call i8* @llvm.localrecover(bitcast(@"?fin$0@0@main@@"),..)
+  // %2 = bitcast i8* %1 to i8**
+  // %3 = load i8*, i8* *%2, align 8
+  //   ==> %3 is the frame-pointer of outermost host function
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =
+  llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+  ParentFP = Builder.CreateCall(
+  FrameRecoverFn, {ParentI8Fn, ParentFP,
+   llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+  ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy);
+  ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign()));
+}
   }
 
   // Create llvm.localrecover calls for all captures.
@@ -1992,6 +2034,7 @@
 
 void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
+  HelperCGF.Pare

[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-14 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D77982#1978105 , @efriedma wrote:

> Again, using the name isn't reliable.  Among other things, in release builds, 
> IR values don't have names at all.


ok, will fix it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-14 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D77982#1981505 , @efriedma wrote:

> Searching LocalDeclMap is less problematic, I guess... but still, it should 
> be possible to something more straightforward.  Maybe make 
> startOutlinedSEHHelper store the actual ImplicitParamDecl, or something like 
> that.


I respectfully disagree.  Two reasons:
(1) Nested filter within a _finally is a rare case.  Scanning 
CGF.LocalDeclMap is not much different from retrieving it from 
CGF.FuncletFramePointerAddr.  Why do we want to store a redundant information 
in CGF for a rare case of one specific target?
(2) The code a paremeter’s home address is allocated today is in 
EmitParmDecl() which (and two its callers in call-stack) are all target 
agnostic functions. See code and call-stack below.  To store DeclPtr in CGF for 
SEH filter only would require some target-specific code in those functions.  Do 
you really think it’s what you want? I thought one implementation philosophy is 
to avoid target-specific code in target-independent functions.

// Otherwise, create a temporary to hold the value.
DeclPtr = CreateMemTemp(Ty, getContext().getDeclAlign(&D), D.getName() 
+ ".addr");
  
clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitParmDecl(const 
clang::VarDecl & D, clang::CodeGen::CodeGenFunction::ParamValue Arg, unsigned 
int ArgNo) Line 2434 C++
clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitFunctionProlog(const 
clang::CodeGen::CGFunctionInfo & FI, llvm::Function * Fn, const 
clang::CodeGen::FunctionArgList & Args) Line 2631C++

clang-cl.exe!clang::CodeGen::CodeGenFunction::StartFunction(clang::GlobalDecl 
GD, clang::QualType RetTy, llvm::Function * Fn, const 
clang::CodeGen::CGFunctionInfo & FnInfo, const clang::CodeGen::FunctionArgList 
& Args, clang::SourceLocation Loc, clang::SourceLocation StartLoc) Line 1065 C++

clang-cl.exe!clang::CodeGen::CodeGenFunction::startOutlinedSEHHelper(clang::CodeGen::CodeGenFunction
 & ParentCGF, bool IsFilter, const clang::Stmt * OutlinedStmt) Line 2157C++

clang-cl.exe!clang::CodeGen::CodeGenFunction::GenerateSEHFinallyFunction(clang::CodeGen::CodeGenFunction
 & ParentCGF, const clang::SEHFinallyStmt & Finally) Line 2190  C++
clang-cl.exe!clang::CodeGen::CodeGenFunction::EnterSEHTryStmt(const 
clang::SEHTryStmt & S) Line 2315C++
clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitSEHTryStmt(const 
clang::SEHTryStmt & S) Line 1622 C++
clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitStmt(const 
clang::Stmt * S, llvm::ArrayRef Attrs) Line 191   C++

clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(const
 clang::CompoundStmt & S, bool GetLast, clang::CodeGen::AggValueSlot AggSlot) 
Line 446  C++
clang-cl.exe!clang::CodeGen::CodeGenFunction::EmitFunctionBody(const 
clang::Stmt * Body) Line 1159  C++

clang-cl.exe!clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl 
GD, llvm::Function * Fn, const clang::CodeGen::CGFunctionInfo & FnInfo) Line 
1325  C++




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-15 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

The fix there deals with SEH filter with SEH _finally parent where its 
prototype is FIXED (2 implicit parameters). It will never change.

For #2,

  "...I was thinking you would save the ImplicitParmDecl*, not the actual 
alloca".

If we just savw ImplicitParmDecl, we will still need to search Prolog for 
alloca BY NAME.  Is not it you are concerned with most?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-15 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 257849.
tentzen added a comment.

Replace F_HasSehAbnormalExits with F_HasExitSwitch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/test/CodeGen/windows-seh-abnormal-exits.c

Index: clang/test/CodeGen/windows-seh-abnormal-exits.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-abnormal-exits.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[src:[0-9-]+]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
+// CHECK-NEXT: %[[src2:[0-9-]+]] = icmp ne i32 %cleanup.dest, 0
+// CHECK-NEXT: %[[src3:[0-9-]+]] = zext i1 %[[src2]] to i8
+// CHECK-NEXT: call void @"?fin$0@0@seh_abnormal_exits@@"(i8 %[[src3]], i8* %[[src]])
+
+void seh_abnormal_exits(int *Counter) {
+  for (int i = 0; i < 5; i++) {
+__try {
+  if (i == 0)
+continue;   // abnormal termination
+  else if (i == 1)
+goto t10;   // abnormal termination
+  else if (i == 2)
+__leave;  // normal execution
+  else if (i == 4)
+return;  // abnormal termination
+}
+__finally {
+  if (AbnormalTermination()) {
+*Counter += 1;
+  }
+}
+  t10:;
+  }
+  return; // *Counter == 3
+}
+
Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -158,9 +158,10 @@
 /// Generation flags.
 class Flags {
   enum {
-F_IsForEH = 0x1,
+F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasExitSwitch = 0x8,
   };
   unsigned flags;
 
@@ -179,8 +180,10 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
-};
 
+  bool hasExitSwitch() const { return flags & F_HasExitSwitch; }
+  void setHasExitSwitch() { flags |= F_HasExitSwitch; }
+};
 
 /// Emit the cleanup.  For normal cleanups, this is run in the
 /// same EH context as when the cleanup was pushed, i.e. the
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,19 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasExitSwitch()) {
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
+  IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasExitSwitch();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-15 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

It can be greater than 2 because this Map includes Decls of User locals from 
parent.  
see CodeGenFunction::EmitCapturedLocals() (the same place of this fix).

  ..
  auto I = ParentCGF.LocalDeclMap.find(VD);
  if (I == ParentCGF.LocalDeclMap.end())
continue;
  
  Address ParentVar = I->second;
  setAddrOfLocalVar(
  VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77936: [Windows SEH] Fix abnormal-exits in _try

2020-04-16 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 257977.
tentzen added a comment.

remade a patch after re-sync


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77936/new/

https://reviews.llvm.org/D77936

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/test/CodeGen/windows-seh-abnormal-exits.c

Index: clang/test/CodeGen/windows-seh-abnormal-exits.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-abnormal-exits.c
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[src:[0-9-]+]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %cleanup.dest = load i32, i32* %cleanup.dest.slot, align 4
+// CHECK-NEXT: %[[src2:[0-9-]+]] = icmp ne i32 %cleanup.dest, 0
+// CHECK-NEXT: %[[src3:[0-9-]+]] = zext i1 %[[src2]] to i8
+// CHECK-NEXT: call void @"?fin$0@0@seh_abnormal_exits@@"(i8 %[[src3]], i8* %[[src]])
+
+void seh_abnormal_exits(int *Counter) {
+  for (int i = 0; i < 5; i++) {
+__try {
+  if (i == 0)
+continue;   // abnormal termination
+  else if (i == 1)
+goto t10;   // abnormal termination
+  else if (i == 2)
+__leave;  // normal execution
+  else if (i == 4)
+return;  // abnormal termination
+}
+__finally {
+  if (AbnormalTermination()) {
+*Counter += 1;
+  }
+}
+  t10:;
+  }
+  return; // *Counter == 3
+}
+
Index: clang/lib/CodeGen/EHScopeStack.h
===
--- clang/lib/CodeGen/EHScopeStack.h
+++ clang/lib/CodeGen/EHScopeStack.h
@@ -158,9 +158,10 @@
 /// Generation flags.
 class Flags {
   enum {
-F_IsForEH = 0x1,
+F_IsForEH = 0x1,
 F_IsNormalCleanupKind = 0x2,
-F_IsEHCleanupKind = 0x4
+F_IsEHCleanupKind = 0x4,
+F_HasExitSwitch = 0x8,
   };
   unsigned flags;
 
@@ -179,8 +180,10 @@
   /// cleanup.
   bool isEHCleanupKind() const { return flags & F_IsEHCleanupKind; }
   void setIsEHCleanupKind() { flags |= F_IsEHCleanupKind; }
-};
 
+  bool hasExitSwitch() const { return flags & F_HasExitSwitch; }
+  void setHasExitSwitch() { flags |= F_HasExitSwitch; }
+};
 
 /// Emit the cleanup.  For normal cleanups, this is run in the
 /// same EH context as when the cleanup was pushed, i.e. the
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1639,6 +1639,19 @@
 
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+
+// Except _leave and fall-through at the end, all other exits in a _try
+//   (return/goto/continue/break) are considered as abnormal terminations
+//   since _leave/fall-through is always Indexed 0,
+//   just use NormalCleanupDestSlot (>= 1 for goto/return/..),
+//   as 1st Arg to indicate abnormal termination
+if (!F.isForEHCleanup() && F.hasExitSwitch()) {
+  Address Addr = CGF.getNormalCleanupDestSlot();
+  llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");
+  llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);
+  IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);
+}
+
 Args.add(RValue::get(IsForEH), ArgTys[0]);
 Args.add(RValue::get(FP), ArgTys[1]);
 
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -860,6 +860,9 @@
 // TODO: base this on the number of branch-afters and fixups
 const unsigned SwitchCapacity = 10;
 
+// pass the abnormal exit flag to Fn (SEH cleanup)
+cleanupFlags.setHasExitSwitch();
+
 llvm::LoadInst *Load =
   createLoadInstBefore(getNormalCleanupDestSlot(), "cleanup.dest",
nullptr);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-06-03 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 3 inline comments as done.
tentzen added a comment.

thank you David.  will update and submit a new patch shortly.




Comment at: clang/lib/CodeGen/CGException.cpp:603-609
+  // For IsEHa catch(...) must handle HW exception
+  // Adjective = HT_IsStdDotDot (0x40), only catch C++ exceptions
+  // Also mark scope with SehTryBegin
+  if (getLangOpts().EHAsynch) {
+TypeInfo.Flags = 0;
+EmitRuntimeCallOrInvoke(getSehTryBeginFn(CGM));
+  }

majnemer wrote:
> I think this logic should move into MicrosoftCXXABI::getCatchAllTypeInfo.
good point. thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-06-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 268375.
tentzen marked an inline comment as done.
tentzen edited the summary of this revision.
tentzen added a comment.

update a couple of changes per David Majnemer's suggestion.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::eha_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::eha_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::eha_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::eha_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::eha_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_eha_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_eha_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,59 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled with Windows SEH Asynchrous Exception option,
+-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mark _try
+boundary and to prevent from potential exceptions being moved across boun

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-06-11 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

does it look good to you? or any more comment? 
thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-06-11 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

this patch has lasted for a couple of months.  a bug in this area is hard and 
time-consuming to diagnose. 
it's better to get this fix in sooner than later. could someone review and 
approve it?
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-07-12 Thread Ten Tzen via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG66f1dcd872db: [Windows SEH] Fix the frame-ptr of a 
nested-filter within a _finally (authored by tentzen).

Changed prior to commit:
  https://reviews.llvm.org/D77982?vs=257227&id=277279#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982

Files:
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGen/windows-seh-filter-inFinally.c

Index: clang/test/CodeGen/windows-seh-filter-inFinally.c
===
--- /dev/null
+++ clang/test/CodeGen/windows-seh-filter-inFinally.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-windows -fms-extensions -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: %[[dst:[0-9-]+]] = call i8* @llvm.eh.recoverfp(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %frame_pointer)
+// CHECK-NEXT: %[[dst1:[0-9-]+]] = call i8* @llvm.localrecover(i8* bitcast (void (i8, i8*)* @"?fin$0@0@main@@" to i8*), i8* %[[dst]], i32 0)
+// CHECK-NEXT: %[[dst2:[0-9-]+]] = bitcast i8* %[[dst1]] to i8**
+// CHECK-NEXT: = load i8*, i8** %[[dst2]], align 8
+
+int
+main(int argc, char *argv[])
+{
+int Counter = 0;
+//
+// Try/except within the finally clause of a try/finally.
+//
+__try {
+  Counter -= 1;
+}
+__finally {
+  __try {
+Counter += 2;
+// RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
+  } __except(Counter) {
+__try {
+  Counter += 3;
+}
+__finally {
+  if (abnormal_termination() == 1) {
+Counter += 5;
+  }
+}
+  }
+}
+// expect Counter == 9
+return 1;
+}
+
Index: clang/lib/CodeGen/CodeGenFunction.h
===
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -264,6 +264,9 @@
   CodeGenModule &CGM;  // Per-module state.
   const TargetInfo &Target;
 
+  // For EH/SEH outlined funclets, this field points to parent's CGF
+  CodeGenFunction *ParentCGF = nullptr;
+
   typedef std::pair ComplexPairTy;
   LoopInfoStack LoopStack;
   CGBuilderTy Builder;
Index: clang/lib/CodeGen/CGException.cpp
===
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1815,6 +1815,48 @@
 llvm::Constant *ParentI8Fn =
 llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
 ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
+
+// if the parent is a _finally, the passed-in ParentFP is the FP
+// of parent _finally, not Establisher's FP (FP of outermost function).
+// Establkisher FP is 2nd paramenter passed into parent _finally.
+// Fortunately, it's always saved in parent's frame. The following
+// code retrieves it, and escapes it so that spill instruction won't be
+// optimized away.
+if (ParentCGF.ParentCGF != nullptr) {
+  // Locate and escape Parent's frame_pointer.addr alloca
+  // Depending on target, should be 1st/2nd one in LocalDeclMap.
+  // Let's just scan for ImplicitParamDecl with VoidPtrTy.
+  llvm::AllocaInst *FramePtrAddrAlloca = nullptr;
+  for (auto &I : ParentCGF.LocalDeclMap) {
+const VarDecl *D = cast(I.first);
+if (isa(D) &&
+D->getType() == getContext().VoidPtrTy) {
+  assert(D->getName().startswith("frame_pointer"));
+  FramePtrAddrAlloca = cast(I.second.getPointer());
+  break;
+}
+  }
+  assert(FramePtrAddrAlloca);
+  auto InsertPair = ParentCGF.EscapedLocals.insert(
+  std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));
+  int FrameEscapeIdx = InsertPair.first->second;
+
+  // an example of a filter's prolog::
+  // %0 = call i8* @llvm.eh.recoverfp(bitcast(@"?fin$0@0@main@@"),..)
+  // %1 = call i8* @llvm.localrecover(bitcast(@"?fin$0@0@main@@"),..)
+  // %2 = bitcast i8* %1 to i8**
+  // %3 = load i8*, i8* *%2, align 8
+  //   ==> %3 is the frame-pointer of outermost host function
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+  &CGM.getModule(), llvm::Intrinsic::localrecover);
+  llvm::Constant *ParentI8Fn =
+  llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+  ParentFP = Builder.CreateCall(
+  FrameRecoverFn, {ParentI8Fn, ParentFP,
+   llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
+  ParentFP = Builder.CreateBitCast(ParentFP, CGM.VoidPtrPtrTy);
+  ParentFP = Builder.CreateLoad(Address(ParentFP, getPointerAlign()));
+}
   }
 
   // Create llvm.localrecover calls for all captures.
@@ -2013,6 +2055,7 @@
 
 void CodeGenFunction::EnterSEHTryStmt(cons

[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-04-28 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

any more concern or comment?
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-05-01 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a reviewer: asl.
tentzen added a comment.

Hi, Anton,
I found you are the Code Owner of "Exception handling, Windows CodeGen, ARM 
EABI".
could you please provide a quick review here? thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D77982: [Windows SEH] Fix the frame-ptr of a nested-filter within a _finally

2020-05-13 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi,  Is there more concern?
To re-iterate the implementation strategy of this change:

This is a rare case that only manifests itself under Windows SEH.  We don't 
want to pollut target agnostic codes.  
The ABI of SEH _finally is fixed with two implicit parameters; one abnormal 
execution and one establisher Stack-pointer. This ABI will never change, or a 
huge problem will arise.  
CGF.LocalDeclMap is the fundamental data structure in Clang-CodeGen phase with 
one primary purpose, storing alloca instructions.  Retrieving alloca of 
spilling instruction for 2nd implicit-argument from that data structure is 
legitimate and robust.
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77982/new/

https://reviews.llvm.org/D77982



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2022-04-14 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#3450940 , @bowang wrote:

> Any updates on this patch? Would like to see it moving forward.
>
> I was trying to use Google Breakpad with Clang. Breakpad is a crash handling 
> library that generates a minidump at crash. The exception handler on Windows 
> relies on SEH.
>
> Breakpad works fine with MSVC. But when it is built with Clang, the exception 
> code returned in `exinfo>ExceptionRecord->ExceptionCode` is incorrect. In my 
> test program, an access to nullptr should trigger 
> `EXCEPTION_ACCESS_VIOLATION` but what's returned is `EXCEPTION_BREAKPOINT`. I 
> suspect it is due to Hardware Exception Handling in Clang.
>
> I tried to add flag `-fasync-exceptions` but the problem stays the same.
>
> I tried to add flag `-fseh-exceptions` but received an error `error: invalid 
> exception model 'seh' for target 'x86_64-pc-windows-msvc19.0.24245'`
>
> I'm not fully sure whether this patch can address my issue, but would 
> appreciate if anyone could shed some light on this. Thanks in advance.

Hi, this patch is just part-1 of Windows SEH feature support.  Part-2 work had 
been sitting in https://reviews.llvm.org/D102817/new/ since last May 2021.  
It's been reviewed, and feedbacks had been addressed. but nobody has approved 
it.  To handle Hardware Exception in Clang & LLVM, we both patches in.  thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2022-04-18 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#3453565 , @bowang wrote:

>> Hi, this patch is just part-1 of Windows SEH feature support.  Part-2 work 
>> had been sitting in https://reviews.llvm.org/D102817/new/ since last May 
>> 2021.  It's been reviewed, and feedbacks had been addressed. but nobody has 
>> approved it.  To handle Hardware Exception in Clang & LLVM, we both patches 
>> in.  thanks.
>
> Thanks for the feedback. This feature is really useful.
>
> We are attempting to switch from MSVC to Clang company-wise. We resolved most 
> issues but lastly got stuck by Clang not supporting SEH. I believe we are not 
> an unique case running into this issue. I'd be very happy to see this feature 
> get merged in.

Yes totally understood. but I had been blocked to move forward Part-2 patch 
https://reviews.llvm.org/D102817/new/  for almost one year.  I cannot just land 
it in without an "approval".
thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-17 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi, John, thank you for reviewing this patch and providing feedback.
regarding your comments:

1, In the RFC thread early, Reid K (the major contributor of Windows SEH/EH 
support) had agreed that "the value proposition is clear and large".  
2,  could you elaborate why do you think "block-level tracking state / control 
flow is potentially really problematic for LLVM.."? Could you be more specific 
or provide some examples?  Remainder that this design also relies on existent 
EH framework to compute block state, and it has passed MSVC SEH suite that 
contains many complicated SEH cases.
3, I don't understand your concern "the way we handle cleanups in Clang today 
is sufficiently "atomic" in design to accommodate this".  From Cleanup 
perspective, there is no difference between HW exception and non-HW exceptions. 
 The key of handling HW exception is to catch exceptions on those faulty / 
memory instructions.  Once it's caught the cleanup process is identical to 
non-HW exception.  again, could you elaborate further?

Finally, regarding naming/option in the code, -EHa or "Asynchronous" is the 
terminology used in MSVC in Windows.  Programmers who use/care this feature 
should know it well as it's the feature to match MSVC in Windows.
Thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-21 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Thank you for prompt reply again.

> [rjmccall] And I agree with him that the potential benefits are substantial. 
> I'm just saying that one barely-trafficked RFC thread is not evidence of a 
> community consensus.

OK, thanks.  it's good to know you are also supportive in adding this feature.

> [rjmccall] As I understand it, you are creating implicit edges within the 
> function to the active SEH handler (potentially part of the same function) 
> from arbitrary places within covered basic blocks, turning basic blocks from 
> a single-entry single-(internal-)exit representation to a single-entry 
> multiple-exit representation. That is a huge change. How do you expect LLVM 
> transformations to preserve or merge this information across blocks? How do 
> you expect transformations to not move code between blocks in problematic 
> ways, or reorder code within blocks in ways that will suddenly be visible to 
> the optimizer? These are the standard objections to supporting features like 
> this, that they have basically unspecified behavior and appear to work by 
> good intentions and happy thoughts.

There is absolutely NO explicit edge added in this design. You misunderstood 
the term of SEME here.  It refers to a SEH scope-region of many blocks that can 
have multi-blocks jumping out of this region, not multi-branches jumping out of 
a block.  Since blocks in LLVM are already 'completely' connected by Control 
Flow (no lexical concept at all before layout), there is nothing we need to do 
to //build //this SEME region.  For LLVM transformations/optimizations, the 
only constrain added is **volatile** attribute on memory operations within a 
SEH region.  As described earlier, it's a little sub-optimal, but given that 
the amount of code directly under a SEH scope is very small, the impact to 
overall code quality is minor.  Volatile-ness is robust as it's one fundamental 
attribute that is expected to be honored by entire framework.

> [rjmccall] Does it pass under all combinations of optimization and 
> code-generation settings? How do LLVM contributors ensure that this test 
> suite continues to pass?

Yes. this is just the first patch.  there will be second patch to land LLVM 
code-gen part in, then 3rd patch to add some test cases (Ex, xcpt4u.c from 
MSVC). Without option -EHa, the patch is a zero-impact change for now.

> [rjmccall] There is a major difference between HW exceptions and non-HW 
> exceptions, which is that non-HW exceptions are observed only at call sites. 
> It is quite easy to write code in IRGen that works because the code emitted 
> at a certain point isn't totally arbitrary

still not completely sure what you are referring to. let me guess. Are you 
concerned that the Cleanup mechanism of a SEH region may not be setup properly 
if there is no call instruction in the region? This is actually a good 
question.  The answer is that the presence of seh.try.begin() intrinsic will 
ensure that a Cleanup stack is established properly because there is an EH edge 
built for seh.try.begin() automatically. hope this answer your concern here.

> [rjmccall] Yes, but it's not known well to all the compiler developers who 
> are reading and maintaining the Clang codebase. I'm not saying you should 
> rename the command-line flag, I'm asking that you not just say "EHa" in 
> comments and identifiers.

Ok, no problem. more comments will be added.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-22 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2286838 , @rjmccall wrote:

> In D80344#228 , @tentzen wrote:
>
>> Thank you for prompt reply again.
>>
>>> [rjmccall] And I agree with him that the potential benefits are 
>>> substantial. I'm just saying that one barely-trafficked RFC thread is not 
>>> evidence of a community consensus.
>>
>> OK, thanks.  it's good to know you are also supportive in adding this 
>> feature.
>>
>>> [rjmccall] As I understand it, you are creating implicit edges within the 
>>> function to the active SEH handler (potentially part of the same function) 
>>> from arbitrary places within covered basic blocks, turning basic blocks 
>>> from a single-entry single-(internal-)exit representation to a single-entry 
>>> multiple-exit representation. That is a huge change. How do you expect LLVM 
>>> transformations to preserve or merge this information across blocks? How do 
>>> you expect transformations to not move code between blocks in problematic 
>>> ways, or reorder code within blocks in ways that will suddenly be visible 
>>> to the optimizer? These are the standard objections to supporting features 
>>> like this, that they have basically unspecified behavior and appear to work 
>>> by good intentions and happy thoughts.
>>
>> There is absolutely NO explicit edge added in this design.
>
> I didn't say there was.  I said that there was an *implicit* edge: from the 
> memory access to the handler.  It's precisely because that edge is implicit 
> that it's problematic for analysis and optimization.

Oh, sorry I misread it.
For HW exceptions the 'implicit' edge is unavoidable unless an explicit 
approach (like previous iload/istore) is employed.  iload approach was 
extensively discussed and evaluated when it's proposed. As far as I know, the 
concerns were that it could create many Invokes, complicate flow graph and 
possibly result in negative performance impact for downstream optimization and 
code generation. Making all optimizations be aware of the new semantic is also 
substantial.
So this design applies an IMPLICT approach. I respectfully disagree that it's 
problematic because as long as volatile attribute is honored it's robust. 
please see the C & C++ SEH rule stated in patch description section.

>> For LLVM transformations/optimizations, the only constrain added is 
>> **volatile** attribute on memory operations within a SEH region.
>
> When is this attribute applied?  Because you can't just apply it at a single 
> point; you also need to mark operations when they're copied/inlined into the 
> region.  We once had a similar attempt at handling exceptions with a 
> setjmp-based ABI (not the "SJLJ" exceptions supported by the backends, 
> something frontend-centric) that had persistent problems because of poor 
> modeling in the IR, which it feels like this is doomed to repeat.

This is applied only once in FE. Consider it's like from the source code. So NO 
there is no other place we need to change. Per SEH semantic, the inline code is 
immune from volatile constraint.
I don't think this is the same as SJLJ story.  I did once look into SJLJ 
problem when I found every single test in MSVC Setjmp suite was broken.  it's 
because the implicit back edge from longjmp (or a callee with longjump) was not 
modeled properly.  actually I have a simple idea that can fix this SJLJ problem 
robustly, but I've been clogged in this SEH task.

>>> [rjmccall] Does it pass under all combinations of optimization and 
>>> code-generation settings? How do LLVM contributors ensure that this test 
>>> suite continues to pass?
>>
>> Yes. this is just the first patch.  there will be second patch to land LLVM 
>> code-gen part in, then 3rd patch to add some test cases (Ex, xcpt4u.c from 
>> MSVC). Without option -EHa, the patch is a zero-impact change for now.
>
> Do you expect to maintain a CI bot that runs the full test suite continuously 
> as changes go into LLVM?  Because this sort of thing is extremely easy to 
> break.

Yes, as long as it's a bug/flaw in the design/implementation.  New 
opt/analysis/tools that violates original basic volatile/cleanup/EH-framework 
exposed by SEH test cases is not included.  Isn't this the policy of Clang/LLVM 
community?

>>> [rjmccall] There is a major difference between HW exceptions and non-HW 
>>> exceptions, which is that non-HW exceptions are observed only at call 
>>> sites. It is quite easy to write code in IRGen that works because the code 
>>> emitted at a certain point isn't totally arbitrary
>>
>> still not completely sure what you are referring to. let me guess. Are you 
>> concerned that the Cleanup mechanism of a SEH region may not be setup 
>> properly if there is no call instruction in the region? This is actually a 
>> good question. The answer is that the presence of seh.try.begin() intrinsic 
>> will ensure that a Cleanup stack is established properly because th

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-23 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2291156 , @rjmccall wrote:

> In D80344#2288898 , @tentzen wrote:
>
>> In D80344#2286838 , @rjmccall wrote:
>>
>>> In D80344#228 , @tentzen wrote:
>>>
 There is absolutely NO explicit edge added in this design.
>>>
>>> I didn't say there was.  I said that there was an *implicit* edge: from the 
>>> memory access to the handler.  It's precisely because that edge is implicit 
>>> that it's problematic for analysis and optimization.
>>
>> Oh, sorry I misread it.
>> For HW exceptions the 'implicit' edge is unavoidable unless an explicit 
>> approach (like previous iload/istore) is employed.  iload approach was 
>> extensively discussed and evaluated when it's proposed. As far as I know, 
>> the concerns were that it could create many Invokes, complicate flow graph 
>> and possibly result in negative performance impact for downstream 
>> optimization and code generation. Making all optimizations be aware of the 
>> new semantic is also substantial.
>
> Hmm.  I suppose it's not that different from the general problem with 
> `setjmp`/`longjmp`.  I think you'll still have representation problems here, 
> but I'll address them below; I concede that in principle marking regions with 
> an intrinsic that instructions can't necessary be moved over is workable, and 
> so you don't need to turn every faulting instruction into an `invoke`.  You 
> may need to mark the initial `seh.try.begin` with something like 
> `returns_twice` or otherwise communicate that there's non-obvious control 
> flow within that function.

OK, good to know this. thank you!
Other than blocking some opts, does this `returns_twice` attribute have some 
other implications?

>> So this design applies an IMPLICT approach. I respectfully disagree that 
>> it's problematic because as long as volatile attribute is honored it's 
>> robust. please see the C & C++ SEH rule stated in patch description section.
>
> You also need to make sure that potentially-faulting instructions aren't 
> moved *into* the `_try` region.  I don't think that just making accesses with 
> the `_try` `volatile` achieves that.  Probably the easiest way to do this 
> would be to outline the `_try` region through most of the LLVM pipeline and 
> only inline it very late.

The intrinsic is set with unknown memory access.  Plus `returns_twice` you just 
suggested, is not it sufficient to block potentially-faulting instructions from 
being moved across?

 For LLVM transformations/optimizations, the only constrain added is 
 **volatile** attribute on memory operations within a SEH region.
>>>
>>> When is this attribute applied?  Because you can't just apply it at a 
>>> single point; you also need to mark operations when they're copied/inlined 
>>> into the region.  We once had a similar attempt at handling exceptions with 
>>> a setjmp-based ABI (not the "SJLJ" exceptions supported by the backends, 
>>> something frontend-centric) that had persistent problems because of poor 
>>> modeling in the IR, which it feels like this is doomed to repeat.
>>
>> This is applied only once in FE. Consider it's like from the source code. So 
>> NO there is no other place we need to change. Per SEH semantic, the inline 
>> code is immune from volatile constraint.
>
> The SEH semantics say that faulting instructions not lexically within the 
> `_try` can be re-ordered with each other, but it's not clear that it's okay 
> to re-order them with instructions within the `_try`.  If I had to guess, I 
> would say that the expectation is that inlining is disabled within a `_try` 
> scope.

Reordering is NOT okay for instructions 'directly' within a _try. 'directly' 
here means it's the code from source code originally, i.e., inlined code or the 
code in callees is not included. Disabling inline in general is good, but not 
necessary.

>> I don't think this is the same as SJLJ story.  I did once look into SJLJ 
>> problem when I found every single test in MSVC Setjmp suite was broken.  
>> it's because the implicit back edge from longjmp (or a callee with longjump) 
>> was not modeled properly.  actually I have a simple idea that can fix this 
>> SJLJ problem robustly, but I've been clogged in this SEH task.
>
> The issue I'm describing was somewhat different from the general problems of 
> using `setjmp`.  The C `setjmp`/`longjmp` library functions don't guarantee 
> that stores to non-`volatile` objects will be visible after the `longjmp`; 
> that is, they require user cooperation in order to get consistency.  This 
> creates a problem when trying to use `setjmp`/`longjmp` directly in IR to 
> implement language exceptions: while you can relatively easily mark all the 
> accesses within a lexical `try` as volatile in the frontend, non-`volatile` 
> accesses can be introduced into the function

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-24 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2291688 , @rjmccall wrote:

> In D80344#2291456 , @tentzen wrote:
>
>> Reordering is NOT okay for instructions 'directly' within a _try. 'directly' 
>> here means it's the code from source code originally, i.e., inlined code or 
>> the code in callees is not included. Disabling inline in general is good, 
>> but not necessary.
>> As said above, SEH semantic only applies to code "directly" under SEH scope 
>> for few obvious reasons (Ex, indirect callees or callees not in the same 
>> module wont be visible).  if faulty instructions are allowed to be reordered 
>> inside a callee, those instructions are allowed to do so even after they are 
>> inlined into _try.
>
> I feel almost certain that this is wrong.  Let me try to explain.  It would 
> be helpful to have a more precise statement of semantics than I can find 
> online, but we can start from the basics.
>
> "X and Y can be reordered" is how optimizer folks talk, but it's not 
> generally how semantics are specified.  As a general rule (ignoring sequence 
> points and concurrency for simplicity), C and C++ require operations to be 
> executed in a particular order on the abstract machine, and there are no 
> rules explicitly sanctioning reordering.  Instead, the "as if" rule gives the 
> implementation broad leeway to do things differently from how they're 
> specified on the abstract machine, as long as the difference cannot be 
> observed by a valid program.  Faults generally correspond to conditions that 
> have undefined behavior under the language, and so the implementation may 
> assume they do not happen in a valid program, and so the consequences of them 
> happening cannot be observed by a valid program, and so faults can be ignored 
> when deciding whether to reorder operations, which allows a lot of reordering.
>
> `_try` should be understood as fully defining the behavior of faulting 
> operations written within its scope so that they have the defined semantics 
> of resuming execution in the `_except` clause.  Because faults have the 
> defined behavior of ending execution of the `_try` block, whether the fault 
> occurred is observable, so the "as if" leeway stops applying.  Thus, other 
> operations with side-effects cannot be reordered with potentially faulty 
> operations written within the `_try`, no more than they could be reordered 
> with a `break` statement.  That applies whether those other operations are 
> written within the `_try` or not; it's just that potentially-faulty 
> operations written within the `_try` must always be treated as having 
> side-effects.
>
> `-EHa` more generally should be understand as partially defining the behavior 
> of faulting operations even if they are not written in a `_try`: if the 
> operation faults, the behavior is defined so that scopes are unwound and 
> control resumes at an `_except` clause if one is dynamically active, but this 
> may be observed at an  indeterminate point.  It is hard to describe these 
> semantics formally, but the intended rules for the implementation are pretty 
> clear: potentially faulty operations outside of a `_try` can be reordered 
> around each other or even moved to different scopes, as per normal 
> optimization rules, but whenever those operations are executed, if they fault 
> they must trigger an unwind and cause execution to resume at an `_except` 
> clause if one is active.
>
> So I think you cannot allow operations inlined from a call made within a 
> `_try` to be reordered with operations written within the `_try`, or to 
> happen outside the `_try`.  Since LLVM doesn't promise not to reorder 
> volatile and non-volatile stores to provably non-aliased locations, you 
> cannot safely inline non-volatile stores within a `_try`.  You can either 
> disable inlining or mark the calls in some way that will cause the inliner to 
> make any inlined stores volatile (and whatever else is necessary to ensure 
> they will not be reordered).

Oh, yes you are right.  I was talking about reordering between inlined faulty 
instructions is allowed.  Reordering inlined instruction with any 'direct' 
volatile instruction should be prohibited.  I overlooked LLVM doesn't promise 
not to reorder volatile and non-volatile. I will simply disable inlining into a 
_try scope.  thanks!

>> Volatile-ness here is primary for reordering constraint, not for data-flow. 
>> Per LLVM EH framework, a data-defined in _try will flow through explicit EH 
>> edge into the Handler.  In this SEH design, there will be a seh.try.end() at 
>> every exit of SEH region that ensures data defined in _try scope flow to the 
>> use in Handler.
>
> Where is the "explicit EH edge into the handler" from a faulting instruction? 
>  It seems like there's an EH edge to the innermost cleanup from the last 
> cleanup scope you entered, but that's not the same as from a faulting 
> instructio

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-24 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2291926 , @rjmccall wrote:

> Okay.  I think we're on the same page about representation now.  If you can 
> come up with a good replacement for "eha" in the intrinsic names, I think 
> this is pretty much ready to go.

how about seh.cppscope.begin() and seh.cppscope.end()? or any suggestion?

> This is a very emission-centric description of the intrinsic. Maybe something 
> like:

Very good writing for LangRef.rst:-).  Will update it with your writing. Thanks!

As for pairing question, we simply utilizes existent Cleanup mechanism as you 
described in which abnormal exits and normal fall-through are merged in a 
'cleanup' pad.  What this implementation does is to inject a scope.begin right 
after a ctor and a scope.end right before dtor in cleanup-pad.  Use the same 
example, it will be something like below:

  void test(int x, int &state) {
int jumpdest;
state = 0;
std::string a;  
**seh.cppscope.begin();  // for object a**
state = 1;
if (x > 0) {
  state = 2;
  std::string b;
  **seh.cppscope.begin();  // for b**
  state = 3;
  if (x > 10) {
state = 4;
jumpdest = 0;
goto destroy_b;
  }
  state = 5;
  std::string c;
  **seh.cppscope.begin();  // for c**
  state = 6;
  **seh.cppscope.end(); // for c dtor**
  c.~std::string();
  jumpdest = 1;
destroy_b:
  **seh.cppscope.end();   // for b dtor**
  b.~std::string();
  switch (jumpdest) {
  case 0: goto destroy_a;
  case 1: goto fallthrough;
  }
fallthrough:
  ;
}
state = 7;
  destroy_a:
**seh.cppscope.begin();  // for a dtor **
a.~std::string();
  }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-12-17 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi, Is there any more concerns, feedbacks or suggestions?
thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-18 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 306287.
tentzen added a comment.

per review feedback from John McCall and others, this update includes:

- Rename intrinsic eha.scope.begin() with seh.scope.begin().
- Update LangRef.rst with detailed explanation
- Add conditional cleanup test case and move the emission of seh.scope.begin() 
into EHScopeStack::pushCleanup()
- Add sideEntry label support in AST-dumper and de/serialization.

also add tests for Windows ABI temps' ctor and dtor process


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,66 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+
+
+Syntax:
+"""
+
+::
+
+  declare void @llv

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-19 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 306469.
tentzen added a comment.

Fixed the clang fault when built without '-feh-asynch'  option.
EHStack's CGF field must be initialized even without -feh-asynch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,66 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+"

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-19 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added inline comments.



Comment at: llvm/docs/LangRef.rst:11591
+and the EH cleanup is no longer required (e.g. because the destructor is being
+called).
+

JosephTremoulet wrote:
> Maybe add something here like
> 
> > Any set of operations can then be confined to the region by reading their 
> > leaf inputs via volatile loads and writing their root outputs via volatile 
> > stores.
> 
> IIUC, for something like `x = 1 / y`, the volatile load of y and volatile 
> store of x being things you can't move past these intrinsic calls is how you 
> make sure the potentially-faulting divide stays in the right scope.  IMO it's 
> a bit confusing to talk about "arbitrary faulting instructions" being 
> constrained without that extra bit. 
Very good point!  will clarify as you suggested..


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-19 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 306510.
tentzen added a comment.

Per Joseph's feedback, further clarify the semantic of llvm.seh.try.begin and 
llvm.seh.try.end.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,68 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-19 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 2 inline comments as done.
tentzen added a comment.

In D80344#2407250 , @pengfei wrote:

> Do we need to consider FP exceptions in _try block?

Yes, FP exception is handled as long as FP exceptions are not disabled (Ex via 
_controlfp() runtime) and FP exception code is filtered & handled via 
___except() statement (Ex, 
___except(GetExceptionCode()==EXCEPTION_FLT_INEXACT_RESULT)).




Comment at: clang/include/clang/Driver/Options.td:886
   HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
+def feh_asynch: Flag<["-"], "feh-asynch">, Group,
+  HelpText<"Enable EH Asynchronous exceptions">, Flags<[CC1Option]>;

pengfei wrote:
> It's better to follow alphabetical for it and line 1531.
really? I see some others are not in alphabetical order.  it's natural to right 
besides fcxx_exceptions.



Comment at: clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp:1
+// RUN: %clang_cc1 -triple x86_64-windows -feh-asynch -fcxx-exceptions 
-fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S 
-emit-llvm %s -o - | FileCheck %s
+

pengfei wrote:
> Should this be a C file? I saw LangRef says they are used for C function.
yes it's a C-function that can be placed in .cpp file.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-19 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2407309 , @belliash wrote:

> Does it really work for x86_64 architecture only? I have tried using this 
> with x86 build and produced binaries looks like this should work on this 
> platform as well, but I have not tried running produced executables to see 
> the results yet tbh.

This is just part-1 (Clang) of SEH HW exception support.  We need another patch 
for LLVM part to work for x86_64.  After that we will need another two LLVM 
changes to enable it for X86 and Arm64.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-09-28 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

OK, great.  
Summarize our discussion above, I will follow up with:

- rename intrinsic eha.scope.begin() with seh.scope.begin().
- update LangRef.rst with detailed explanation
- not to allow inlining under SEH direct lexical scope
- add conditional cleanup test case and make sure that eha.scope.begin() is 
emitted in the right place
- add sideEntry label support in AST-dumper and de/serialization.

thank you for your thorough review and valuable feedbacks.  I'm in the middle 
of something else. I will post another patch latter.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2020-11-24 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D80344#2410417 , @pengfei wrote:

> In D80344#2407305 , @tentzen wrote:
>
>> In D80344#2407250 , @pengfei wrote:
>>
>>> Do we need to consider FP exceptions in _try block?
>>
>> Yes, FP exception is handled as long as FP exceptions are not disabled (Ex 
>> via _controlfp() runtime) and FP exception code is filtered & handled via 
>> ___except() statement (Ex, 
>> ___except(GetExceptionCode()==EXCEPTION_FLT_INEXACT_RESULT)).
>
> I see. If this is the case, you may need to assign FPE_Strict to _try block 
> to preserve FP instructions' order.

Is FPE_Strict in Clang/LLVM  equivalent to /fp:strict in VC++/Windows.  -EHa 
does not automatically imply /fp:strict semantic in Windows. So for FP 
sensitive cases, users can explicitly specify -EHa and -FPE_Strict together.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-05-16 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Passed many CodeGen related test suites over the weekend.
It landed in..

commit 9ca9be098fedb14182c50c9dd700f3fa91c8d4c7 (HEAD -> main)
Author: Ten Tzen 
Date:   Sun May 16 18:12:47 2021 -0700

  [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-01-28 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.
Herald added a reviewer: jansvoboda11.

Hi, John,
sorry for the delay.  I'm still in the middle of something.
will context-switch a little bit latter. thanks,


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-02-17 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked an inline comment as not done.
tentzen added a comment.

thank you for the thorough review again.  My answer for each comment below:




Comment at: clang/lib/CodeGen/CGCleanup.cpp:1341
+  llvm::FunctionCallee SehCppScope =
+  CGM.CreateRuntimeFunction(FTy, "llvm.seh.scope.begin");
+  EmitSehScope(*this, SehCppScope);

rjmccall wrote:
> We generally prefer to get intrinsic functions with `CGM.getIntrinsic`.
Does this really matter? there are more than 200 uses of 
CGM.CreateRuntimeFunction().



Comment at: clang/lib/CodeGen/CGException.cpp:465
 if (const CapturedDecl* CD = dyn_cast_or_null(D)) {
-  if (CD->isNothrow())
+  if (CD->isNothrow() && !getLangOpts().EHAsynch /* !IsEHa */)
 EHStack.pushTerminate();

rjmccall wrote:
> Please remove the comment here.  The option name should be sufficiently 
> self-descriptive.
> 
> Anyway, I don't think this change is right, because we *do* still need to 
> push a terminate scope: we need C++ exceptions to trigger a call to 
> `std::terminate`.  It's just that such scopes aren't fully terminal when 
> async exceptions are enabled, because MSVC defines those exceptions as 
> passing through `noexcept` and so on.  (I assume that's true; can you link to 
> documentation about it?)
Yes, MSVC terminate() runtime bypasses HW exceptions to its caller.
Hmm, it's been a whole. I think I placed that code there because Clang's 
terminate runtime does not dispatch HW exception to caller when I tried a year 
ago.  It issues an unhandled exception.  I felt if a user explicitly specify 
-EHa, HW exception probably is more significant than C++ noexcept/nothrow 
directive.
Anyways, I can undo this code and let terminate-runtime handler it one way or 
the other.



Comment at: clang/lib/CodeGen/CGException.cpp:554
+  if (isNoexceptExceptionSpec(EST) && Proto->canThrow() == CT_Cannot &&
+  !EHStack.empty() /* possible empty when -EHa */) {
 EHStack.popTerminate();

rjmccall wrote:
> Again, please try to refer to this in a more driver-agnostic way: "under 
> async exceptions" rather than "when -EHa".  But actually as mentioned above I 
> think this is incorrect.
will do.



Comment at: clang/lib/CodeGen/CGException.cpp:1668
+  } else if (isa(J)) {
+auto *MCI = cast(J);
+MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));

rjmccall wrote:
> Please use `dyn_cast` for all of these.
ok will fix them. thanks.



Comment at: clang/lib/CodeGen/CGException.cpp:1678
+  VolatilizeTryBlocks(TI->getSuccessor(I), V);
+  }
+}

rjmccall wrote:
> Volatilizing every block that's reachable from the `try` block seems like it 
> makes a lot of assumptions about where branches within the `try` can reach.  
> For example, a `goto` could certainly go to a block that's already been 
> emitted, as could `break` or `continue` if the emitter just makes slightly 
> different decisions about emission order.  Please look at how 
> `FragileHazards` (in the ObjC emission code) collects blocks in order to do 
> its transforms — I think you can probably extract a reasonable common base 
> out.  Alternatively, I think you could handle this directly in the insertion 
> callback (`CodeGenFunction::InsertHelper`) when we're in an appropriate `try` 
> scope.
A _try region is a Single Entry Multiple Exits regions. this code starts from 
Entry block and follows control-flow to reach all successors.  Yes a block 
could have multi-predecessors.  Note the 2nd line of this function: a visit 
flag is marked and checked
   !V.insert(BB).second /* already visited */ 

As long as it follows control-flows, it does not matter what the lexical order 
is.



Comment at: clang/lib/CodeGen/CGException.cpp:603
+
+  //  For IsEHa catch(...) must handle HW exception
+  //  Adjective = HT_IsStdDotDot (0x40), only catch C++ exceptions

rjmccall wrote:
> asmith wrote:
> > nit - extra space after //
> The comment here isn't explaining anything, it's just repeating what the code 
> is doing.  If you want a useful comment, you could explain why it's important 
> to mark the scope.
Yes, will do. thanks.



Comment at: clang/lib/Driver/ToolChains/Clang.cpp:6584
+if (EH.Asynch)
+  CmdArgs.push_back("-feh-asynch");
   }

rjmccall wrote:
> For consistency with the existing options, please spell this option 
> `-fasync-exceptions`, and please spell the corresponding LangOption 
> `AsyncExceptions`.
OK will do.



Comment at: clang/lib/Frontend/CompilerInvocation.cpp:2786
   Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
+  Opts.EHAsynch = Args.hasArg(OPT_feh_asynch);
 

rjmccall wrote:
> You should emit an error if this is enabled on targets that are not in the 
> appropriate Windows environment

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-02-23 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 325966.
tentzen added a comment.
Herald added a subscriber: jfb.

changed option name and a couple of minor changes per John McCall's comments.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.ll
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.ll
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.asm
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.ll
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.obj
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.s
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.asm
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.ll
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.obj
  clang/test/CodeGen/xxx
  clang/test/xxCG.log
  llvm/docs/LangRef.rst
  llvm/include/llvm/CodeGen/SelectionDAGISel.h
  llvm/include/llvm/CodeGen/WinEHFuncInfo.h
  llvm/include/llvm/IR/BasicBlock.h
  llvm/include/llvm/IR/Intrinsics.td
  llvm/include/llvm/Support/ManagedStatic.h
  llvm/lib/Analysis/EHPersonalities.cpp
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/AsmPrinter/WinException.cpp
  llvm/lib/CodeGen/BranchFolding.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
  llvm/lib/CodeGen/WinEHPrepare.cpp
  llvm/lib/IR/BasicBlock.cpp
  llvm/lib/IR/Verifier.cpp

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-06-03 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi, yes I can repro the crash with -fasync-exceptions plus -O2 option. Working 
on it now..
thank you for reporting this bug..
@aganea , this patch should be zero-impact without explicit option 
-fasync-exceptions.  Are you also seeing a crash without this option?
thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-06-03 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

@aganea Oh, my mistake. did not mean to enable -fasync-exceptions under -EHa in 
this patch. will fix it shortly...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-03 Thread Ten Tzen via Phabricator via cfe-commits
tentzen created this revision.
tentzen added reviewers: asmith, aganea, zahiraam.
tentzen requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patch fixes a Windows -EHa crash induced by previous commit 
797ad701522988e212495285dade8efac41a24d4 
. 
The crush was caused  "LifetimeMarker" scope (with option -O2) that should not 
be considered as SEH Scope.

This change also turns off -fasync-exceptions by default under -EHa option for 
now.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103664

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp


Index: clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
===
--- clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
+++ clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions 
-fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S 
-emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions 
-fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -O2 -S 
-emit-llvm %s -o - | FileCheck %s
 
 // CHECK: invoke void @llvm.seh.scope.begin()
 // CHECK: invoke void @llvm.seh.scope.begin()
@@ -8,8 +9,8 @@
 // CHECK: invoke void @llvm.seh.scope.end()
 
 // CHECK: invoke void @llvm.seh.try.begin()
-// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i
-// CHECK-NEXT: invoke void @"?crash@@YAXH@Z"(i32 %[[src]])
+// CHECK: = load volatile i32, i32* %i
+// CHECK-NEXT: invoke void @"?crash@@YAXH@Z"(i32
 // CHECK: invoke void @llvm.seh.try.end()
 
 // 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&
+  if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
   CGF->getTarget().getCXXABI().isMicrosoft())
 CGF->EmitSehCppScopeBegin();
 


Index: clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
===
--- clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
+++ clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows -fasync-exceptions -fcxx-exceptions -fexceptions -fms-extensions -x c++ -Wno-implicit-function-declaration -O2 -S -emit-llvm %s -o - | FileCheck %s
 
 // CHECK: invoke void @llvm.seh.scope.begin()
 // CHECK: invoke void @llvm.seh.scope.begin()
@@ -8,8 +9,8 @@
 // CHECK: invoke void @llvm.seh.scope.end()
 
 // CHECK: invoke void @llvm.seh.try.begin()
-// CHECK: %[[src:[0-9-]+]] = load volatile i32, i32* %i
-// CHECK-NEXT: invoke void @"?crash@@YAXH@Z"(i32 %[[src]])
+// CHECK: = load volatile i32, i32* %i
+// CHECK-NEXT: invoke void @"?crash@@YAXH@Z"(i32
 // CHECK: invoke void @llvm.seh.try.end()
 
 // 
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EH

[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

In D103664#2798732 , @aganea wrote:

> Thanks for the quick fix! Would you mind fixing the two failing tests please? 
> (see above)

Hmm, I cannot repro locally..

@zahiraam, currently -EHa is not completely ready yet. we need a couple of more 
patches.  So turn it off to preserve zero-diff, unless that -fasync-exceptions 
is explicitly specified.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103664/new/

https://reviews.llvm.org/D103664

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 349939.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103664/new/

https://reviews.llvm.org/D103664

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/Driver/ToolChains/Clang.cpp


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&
+  if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
   CGF->getTarget().getCXXABI().isMicrosoft())
 CGF->EmitSehCppScopeBegin();
 


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&
+  if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
   CGF->getTarget().getCXXABI().isMicrosoft())
 CGF->EmitSehCppScopeBegin();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

@zahiraam, are you removing all those CHECKs:

- CHECK: invoke void @llvm.seh.scope.**

those are placed there to ensure SEH scope semantic is preserved for Od..


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103664/new/

https://reviews.llvm.org/D103664

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

since I cannot repro it locally, let's have this patch in to resolve -EHa -O2 
crashes for now.
I will add more -O2 tests in following patches.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103664/new/

https://reviews.llvm.org/D103664

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103664: [Windows SEH]: Fix -O2 crash for Windows -EHa

2021-06-04 Thread Ten Tzen via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG33ba8bd2c942: [Windows SEH]: Fix -O2 crash for Windows -EHa 
(authored by tentzen).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103664/new/

https://reviews.llvm.org/D103664

Files:
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/Driver/ToolChains/Clang.cpp


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&
+  if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
   CGF->getTarget().getCXXABI().isMicrosoft())
 CGF->EmitSehCppScopeBegin();
 


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -7151,8 +7151,6 @@
 if (types::isCXX(InputType))
   CmdArgs.push_back("-fcxx-exceptions");
 CmdArgs.push_back("-fexceptions");
-if (EH.Asynch)
-  CmdArgs.push_back("-fasync-exceptions");
   }
   if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
 CmdArgs.push_back("-fexternc-nounwind");
Index: clang/lib/CodeGen/CGCleanup.cpp
===
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -195,7 +195,7 @@
 Scope->setLifetimeMarker();
 
   // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup
-  if (CGF->getLangOpts().EHAsynch && IsEHCleanup &&
+  if (CGF->getLangOpts().EHAsynch && IsEHCleanup && !IsLifetimeMarker &&
   CGF->getTarget().getCXXABI().isMicrosoft())
 CGF->EmitSehCppScopeBegin();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137381: [clang][compiler-rt] Exception escape out of an non-unwinding function is an undefined behaviour

2022-12-04 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added inline comments.



Comment at: clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp:3
 
+// FIXME: this check appears to be miscompiled?
+// XFAIL: *

lebedev.ri wrote:
> This test broke once we always started adding (outermost) UB scope for 
> nounwind functions.
> I don't quite get what is going wrong. It could be a bug in SEH handling.
> Can someone who has some idea about that code take a look and suggest a fix?
> @tentzen ?
By definition, non-unwind function I think is for Synchronous EH. So this 
Sanitizer check should exclude Asynchronous EH functions, those with option 
-fasync-exceptions.
 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137381/new/

https://reviews.llvm.org/D137381

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D137381: [clang][compiler-rt] Exception escape out of an non-unwinding function is an undefined behaviour

2022-12-06 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added inline comments.



Comment at: clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp:3
 
+// FIXME: this check appears to be miscompiled?
+// XFAIL: *

lebedev.ri wrote:
> efriedma wrote:
> > lebedev.ri wrote:
> > > tentzen wrote:
> > > > lebedev.ri wrote:
> > > > > This test broke once we always started adding (outermost) UB scope 
> > > > > for nounwind functions.
> > > > > I don't quite get what is going wrong. It could be a bug in SEH 
> > > > > handling.
> > > > > Can someone who has some idea about that code take a look and suggest 
> > > > > a fix?
> > > > > @tentzen ?
> > > > By definition, non-unwind function I think is for Synchronous EH. So 
> > > > this Sanitizer check should exclude Asynchronous EH functions, those 
> > > > with option -fasync-exceptions.
> > > >  
> > > I do not understand.
> > > If the function can unwind, then why is it marked `nounwind`?
> > > This kind of thing is exactly what i was afraid of with those SEH patches.
> > clang should not be marking functions "nounwind" in -fasync-exceptions 
> > mode; if it is, I'd consider that a bug.  (I assume someone just forgot to 
> > add a check to some code that adds nounwind.)
> My thoughts precisely. @tentzen please fix :)
This is copied from LLVM reference manual:

nounwind
This function attribute indicates that the function never raises an exception. 
If the function does raise an exception, its runtime behavior is undefined. 
However, functions marked nounwind may still trap or generate asynchronous 
exceptions. Exception handling schemes that are recognized by LLVM to handle 
asynchronous exceptions, such as SEH, will still provide their implementation 
defined semantics.

So I think nounwind only implies no synchronous/software unwind, not HW traps 
etc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137381/new/

https://reviews.llvm.org/D137381

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-01 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 334855.
tentzen added a comment.

Removed some files (mostly for Part 2 of this feature) that were accidentally 
put in last revision.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4223,6 +4223,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2789,6 +2789,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6583,6 +6587,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -456,6 +456,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : Intrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -11530,6 +11530,68 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+^^
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled 

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-03 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 335068.
tentzen added a comment.

rebase the patch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4415,6 +4415,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2871,6 +2871,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6784,6 +6788,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -516,6 +516,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrReadMem, IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : DefaultAttrsIntrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -12252,6 +12252,68 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+^^
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled with Windows SEH Asynchrous Exception option,
+-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to mar

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-05 Thread Ten Tzen via Phabricator via cfe-commits
tentzen marked 13 inline comments as done.
tentzen added a comment.

hi,  I believe I'd addressed all issues or concerns, and it's rebased to 
up-to-date source in new _main branch now. Does this look good to everyone? If 
I don't hear any objection in a couple of days, I will go ahead make this patch 
in. Again This is just part-1 of Windows SEH feature.  Without new option 
specified, it's a zero-impact change.




Comment at: clang/include/clang/Driver/Options.td:886
   HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
+def fasync_exceptions: Flag<["-"], "fasync-exceptions">, Group,
+  HelpText<"Enable EH Asynchronous exceptions">, Flags<[CC1Option]>;

jansvoboda11 wrote:
> Can you rebase and use the new option marshalling infrastructure instead?
> 
> https://clang.llvm.org/docs/InternalsManual.html#adding-new-command-line-option
SEH Async-excception option is implemented the same way as CXX-exception or 
ObjC-exception.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-07 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 336011.
tentzen marked an inline comment as done.
tentzen added a comment.

clang-format fixes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4415,6 +4415,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2871,6 +2871,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6784,6 +6788,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -516,6 +516,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : DefaultAttrsIntrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -12252,6 +12252,68 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+^^
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled with Windows SEH Asynchrous Exception option,
+-feh_asynch (aka MSVC -EHa), these two intrinsics 

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-08 Thread Ten Tzen via Phabricator via cfe-commits
tentzen updated this revision to Diff 336033.
tentzen added a comment.

fixed command option typos in two test cases


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

Files:
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/CodeGen/CGCleanup.cpp
  clang/lib/CodeGen/CGException.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/EHScopeStack.h
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Sema/JumpDiagnostics.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCatchDotDotDot.cpp
  clang/test/CodeGen/windows-seh-EHa-CppCondiTemps.cpp
  clang/test/CodeGen/windows-seh-EHa-CppDtors01.cpp
  clang/test/CodeGen/windows-seh-EHa-TryInFinally.cpp
  llvm/docs/LangRef.rst
  llvm/include/llvm/IR/Intrinsics.td
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/IR/Verifier.cpp

Index: llvm/lib/IR/Verifier.cpp
===
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -4415,6 +4415,10 @@
   Assert(
   !F->isIntrinsic() || isa(I) ||
   F->getIntrinsicID() == Intrinsic::donothing ||
+  F->getIntrinsicID() == Intrinsic::seh_try_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_try_end ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_begin ||
+  F->getIntrinsicID() == Intrinsic::seh_scope_end ||
   F->getIntrinsicID() == Intrinsic::coro_resume ||
   F->getIntrinsicID() == Intrinsic::coro_destroy ||
   F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void ||
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2871,6 +2871,10 @@
   llvm_unreachable("Cannot invoke this intrinsic");
 case Intrinsic::donothing:
   // Ignore invokes to @llvm.donothing: jump directly to the next BB.
+case Intrinsic::seh_try_begin:
+case Intrinsic::seh_scope_begin:
+case Intrinsic::seh_try_end:
+case Intrinsic::seh_scope_end:
   break;
 case Intrinsic::experimental_patchpoint_void:
 case Intrinsic::experimental_patchpoint_i64:
@@ -6784,6 +6788,10 @@
   lowerCallToExternalSymbol(I, FunctionName);
 return;
   case Intrinsic::donothing:
+  case Intrinsic::seh_try_begin:
+  case Intrinsic::seh_scope_begin:
+  case Intrinsic::seh_try_end:
+  case Intrinsic::seh_scope_end:
 // ignore
 return;
   case Intrinsic::experimental_stackmap:
Index: llvm/include/llvm/IR/Intrinsics.td
===
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -516,6 +516,16 @@
  [llvm_ptr_ty, llvm_ptr_ty],
  [IntrNoMem]>;
 
+// To mark the beginning/end of a try-scope for Windows SEH -EHa
+//  calls/invokes to these intrinsics are placed to model control flows
+//caused by HW exceptions under option -EHa.
+//  calls/invokes to these intrinsics will be discarded during a codegen pass
+//   after EH tables are generated
+def int_seh_try_begin : Intrinsic<[], [], [IntrWriteMem, IntrWillReturn]>;
+def int_seh_try_end : Intrinsic<[], [], [IntrWriteMem, IntrWillReturn]>;
+def int_seh_scope_begin : Intrinsic<[], [], [IntrNoMem]>;
+def int_seh_scope_end : Intrinsic<[], [], [IntrNoMem]>;
+
 // Note: we treat stacksave/stackrestore as writemem because we don't otherwise
 // model their dependencies on allocas.
 def int_stacksave : DefaultAttrsIntrinsic<[llvm_ptr_ty]>,
Index: llvm/docs/LangRef.rst
===
--- llvm/docs/LangRef.rst
+++ llvm/docs/LangRef.rst
@@ -12252,6 +12252,68 @@
 the escaped allocas are allocated, which would break attempts to use
 '``llvm.localrecover``'.
 
+'``llvm.seh.try.begin``' and '``llvm.seh.try.end``' Intrinsics
+^^
+
+Syntax:
+"""
+
+::
+
+  declare void @llvm.seh.try.begin()
+  declare void @llvm.seh.try.end()
+
+Overview:
+"
+
+The '``llvm.seh.try.begin``' and '``llvm.seh.try.end``' intrinsics mark
+the boundary of a _try region for Windows SEH Asynchrous Exception Handling.
+
+Semantics:
+""
+
+When a C-function is compiled with Windows SEH Asynchrous Exception option,
+-feh_asynch (aka MSVC -EHa), these two intrinsics are injected to m

[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-12 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

Hi, (Last call for review!!)
Is there any more comments? This review has lasted for more than a year now. I 
believe I had addressed or answered all questions and concerns. Thank all 
reviewers' precious feedbacks.
For late comers, again
(1) Original llvm-dev [RFC] discussions can be found in these two threads below:
https://lists.llvm.org/pipermail/llvm-dev/2020-March/140541.html
https://lists.llvm.org/pipermail/llvm-dev/2020-April/141338.html

(2) John McCall had done a thorough and insightful review. please see details 
above.

(3) Finally, a prototype of entire Windows SEH implementation (including both 
HW exception handling and local unwind) is stored in 
https://github.com/tentzen/llvm-project.  This prototype had been stressed by a 
Microsoft Windows internal SEH test suite.
Note this check-in is just part-1 of HW exception handling.

Could please someone accept it as a record?
thank you!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D80344: [Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1

2021-04-14 Thread Ten Tzen via Phabricator via cfe-commits
tentzen added a comment.

  bool keepFramePointer(const MachineFunction &MF) const override;

In D80344#2673335 , @lebedev.ri wrote:

> In D80344#2673148 , @asmith wrote:
>
>> In D80344#2671157 , @lebedev.ri 
>> wrote:
>>
>>> It would be good for @rjmccall / @rsmith / etc to actually finish reviewing 
>>> this and accept it.
>>> I would personally want to see the next patches - what changes are needed 
>>> for llvm analysis, transforms?
>>
>> All changes were provided a year ago and discussed on llvm-dev. I’m inclined 
>> to move forward unless any of the reviewers have additional comments???
>
> Could you please add relevant links to the patch description?

Hi,

In D80344#2688530 , @lebedev.ri wrote:

> In D80344#2684450 , @tentzen wrote:
>
>> Hi,
>
>
>
>> (Last call for review!!)
>
> Please refer to https://llvm.org/docs/CodeReview.html
>
>> Is there any more comments? This review has lasted for more than a year now. 
>> I believe I had addressed or answered all questions and concerns. Thank all 
>> reviewers' precious feedbacks.
>> For late comers, again
>> (1) Original llvm-dev [RFC] discussions can be found in these two threads 
>> below:
>> https://lists.llvm.org/pipermail/llvm-dev/2020-March/140541.html
>> https://lists.llvm.org/pipermail/llvm-dev/2020-April/141338.html
>>
>> (2) John McCall had done a thorough and insightful review. please see 
>> details above.
>
>
>
>> (3) Finally, a prototype of entire Windows SEH implementation (including 
>> both HW exception handling and local unwind) is stored in 
>> https://github.com/tentzen/llvm-project.  This prototype had been stressed 
>> by a Microsoft Windows internal SEH test suite.
>> Note this check-in is just part-1 of HW exception handling.
>
> So can you actually post the other patches as reviews?
>
>> Could please someone accept it as a record?
>> thank you!



In D80344#2688530 , @lebedev.ri wrote:

> In D80344#2684450 , @tentzen wrote:
>
>> Hi,
>
>
>
>> (Last call for review!!)
>
> Please refer to https://llvm.org/docs/CodeReview.html
>
>> Is there any more comments? This review has lasted for more than a year now. 
>> I believe I had addressed or answered all questions and concerns. Thank all 
>> reviewers' precious feedbacks.
>> For late comers, again
>> (1) Original llvm-dev [RFC] discussions can be found in these two threads 
>> below:
>> https://lists.llvm.org/pipermail/llvm-dev/2020-March/140541.html
>> https://lists.llvm.org/pipermail/llvm-dev/2020-April/141338.html
>>
>> (2) John McCall had done a thorough and insightful review. please see 
>> details above.
>
>
>
>> (3) Finally, a prototype of entire Windows SEH implementation (including 
>> both HW exception handling and local unwind) is stored in 
>> https://github.com/tentzen/llvm-project.  This prototype had been stressed 
>> by a Microsoft Windows internal SEH test suite.
>> Note this check-in is just part-1 of HW exception handling.
>
> So can you actually post the other patches as reviews?
>
>> Could please someone accept it as a record?
>> thank you!

Yes, I read that policy. and per policy, I waited for a week and pinged.

What other patches you were asking? LLVM HW EH Part-2 change or including Local 
Unwind?  
I did at first put the whole design and implementation in RFC, but I was asked 
to separate Local Unwind and HW exception.
So I did and submitted a patch specific for HW exception, but was asked to 
further divide it.
So I did, and this is part-1 for Clang.  After this patch is landed, yes I will 
work on next patch.

Meanwhile please refer to those RFC threads and Code/Wiki in 
https://github.com/tentzen/llvm-project for more details.

One step at a time, for now for this patch, is there any other feedback? thanks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D80344/new/

https://reviews.llvm.org/D80344

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits