<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:PMingLiU;
panose-1:2 2 5 0 0 0 0 0 0 0;}
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"\@PMingLiU";
panose-1:2 1 6 1 0 1 1 1 1 1;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
@font-face
{font-family:"Consolas\,";}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
{mso-style-priority:34;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:.5in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle21
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:1571383753;
mso-list-template-ids:361409334;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level3
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:1.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level4
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:2.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level5
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:2.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level6
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:3.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level7
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:3.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level8
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:4.0in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level9
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:4.5in;
mso-level-number-position:left;
text-indent:-.25in;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1
{mso-list-id:1642534016;
mso-list-type:hybrid;
mso-list-template-ids:1195824140 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l1:level1
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l1:level2
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l1:level3
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l1:level4
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l1:level5
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l1:level6
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
@list l1:level7
{mso-level-number-format:bullet;
mso-level-text:\F0B7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Symbol;}
@list l1:level8
{mso-level-number-format:bullet;
mso-level-text:o;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:"Courier New";}
@list l1:level9
{mso-level-number-format:bullet;
mso-level-text:\F0A7;
mso-level-tab-stop:none;
mso-level-number-position:left;
text-indent:-.25in;
font-family:Wingdings;}
ol
{margin-bottom:0in;}
ul
{margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">+ <a href="mailto:anton@korobeynikov.info">anton@korobeynikov.info</a>; Code Owner on “<span style="font-size:9.5pt;font-family:Consolas;color:black">Exception handling, Windows codegen, ARM EABI"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:9.5pt;font-family:Consolas;color:black">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:9.5pt;font-family:Consolas;color:black"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:9.5pt;font-family:Consolas;color:black">--Ten</span><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Ten Tzen <tentzen@microsoft.com> <br>
<b>Sent:</b> Thursday, April 30, 2020 11:35 PM<br>
<b>To:</b> Eli Friedman <efriedma@quicinc.com>; llvm-dev@lists.llvm.org<br>
<b>Cc:</b> rnk@google.com; Aaron Smith <aaron.smith@microsoft.com>; Joseph Tremoulet <jotrem@microsoft.com><br>
<b>Subject:</b> RE: [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal">Is there other concerns or suggestions about this proposal?
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I have added some details about Reid’s earlier feedback regarding control-flow “region”. The new doc for -EHa is also span off here:
<a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftentzen%2Fllvm-project%2Fwiki%2FWindows-SEH%3A-HARDWARE-EXCEPTION-HANDLING-(EHa)&data=02%7C01%7Ctentzen%40microsoft.com%7Cf4d98f9b3ba2412901d908d7ed99b658%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637239116754386920&sdata=imqhaHN02ZLJpxL6eN7C0tYz2YmcTIVL2VQIuFLM%2FHo%3D&reserved=0">
https://github.com/tentzen/llvm-project/wiki/Windows-SEH:-HARDWARE-EXCEPTION-HANDLING-(EHa)</a><o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Since last time I also added several changes in my prototype to more robustly compute State at block-level in SEME (Single-Entry-Multiple-Exits) region. I also fixed the bug brought up by Eli regarding memcpy intrinsic. The patch can be
read here: <a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftentzen%2Fllvm-project%2Fcompare%2FSEH-EHa-base...SEH-EHa%3Fexpand%3D1&data=02%7C01%7Ctentzen%40microsoft.com%7Cf4d98f9b3ba2412901d908d7ed99b658%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637239116754386920&sdata=%2FLqXkSgBt9Q3kXhkA%2B92jJIe0mPQ7TIqK92hsghBe%2FM%3D&reserved=0">
https://github.com/tentzen/llvm-project/compare/SEH-EHa-base...SEH-EHa?expand=1</a>.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The implementation is actually very simple, isolated and very easy to read. It adds very little complexity into existing code. <o:p></o:p></p>
<p class="MsoNormal">Major changes are in four files:<o:p></o:p></p>
<ul style="margin-top:0in" type="disc">
<li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3">[Clang] CGException.cpp and CGCleanup.cpp: Add scope_begin&scope_end intrinsic at entry and exits of seh-_try/cpp-cleanup SEME region.
<o:p></o:p></li><li class="MsoListParagraph" style="margin-left:0in;mso-list:l1 level1 lfo3">[LLVM] WinEHPrepare.coo & SelectionDAGISel.cpp: Compute and report EH State at block-level.<o:p></o:p></li></ul>
<p class="MsoNormal">Other charges are trivial and straight-forward helper code.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I believe I have answered and addressed all concerns or questions from you guys. Please let me know if I miss anything.<o:p></o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--Ten<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Ten Tzen <<a href="mailto:tentzen@microsoft.com">tentzen@microsoft.com</a>>
<br>
<b>Sent:</b> Thursday, April 16, 2020 1:52 PM<br>
<b>To:</b> Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>>;
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Cc:</b> <a href="mailto:rnk@google.com">rnk@google.com</a>; Aaron Smith <<a href="mailto:aaron.smith@microsoft.com">aaron.smith@microsoft.com</a>>; Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com">jotrem@microsoft.com</a>><br>
<b>Subject:</b> RE: [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">As stated in the design paragraph, this design does not intend to model precise CFG at instruction level since it’s complicated and unnecessary.
<o:p></o:p></p>
<p class="MsoNormal">As long as we comply C and C++ rules listed below, we achieve -EHa semantic. There is NO need to precisely model HW exception control flow at instruction-level.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Your example about memcpy() is just a bug in current implementation. I will fix it so that it’s volatilized in some manner. We are not in Code Review stage yet. let’s focus on design.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">There is one seh_try_begin() invoke at the beginning of _try and one seh_try_end() invoke at the end of _try. Their EH edge will point to _except handler. So
<o:p></o:p></p>
<p class="MsoNormal">your example below will not happen. Compiler should not generate code like that. <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--Ten<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b>From:</b> Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>>
<br>
<b>Sent:</b> Thursday, April 16, 2020 2:10 AM<br>
<b>To:</b> Ten Tzen <<a href="mailto:tentzen@microsoft.com">tentzen@microsoft.com</a>>;
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Cc:</b> <a href="mailto:rnk@google.com">rnk@google.com</a>; Aaron Smith <<a href="mailto:aaron.smith@microsoft.com">aaron.smith@microsoft.com</a>>; Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com">jotrem@microsoft.com</a>><br>
<b>Subject:</b> [EXTERNAL] RE: [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-left:.5in"><b>From:</b> Ten Tzen <<a href="mailto:tentzen@microsoft.com">tentzen@microsoft.com</a>>
<br>
<b>Sent:</b> Wednesday, April 15, 2020 9:15 PM<br>
<b>To:</b> Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>>;
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Cc:</b> <a href="mailto:rnk@google.com">rnk@google.com</a>; <a href="mailto:aaron.smith@microsoft.com">
aaron.smith@microsoft.com</a>; Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com">jotrem@microsoft.com</a>><br>
<b>Subject:</b> [EXT] RE: [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Hi, Eli,<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Why are you under the impression that
<span style="font-family:"Consolas\,";color:black">threw_exception() </span>will not be called if optimizations are enabled? I don’t know if the -EHa Spec is clearly described in MSFT Webs. At least this proposal has described the rules for both C & C++ code.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">The very first rule clearly said that “<b>no exception can move in or out of _try region., i.e., no potential faulty instruction can be moved across _try boundary</b>”. As such the dereference of statement
<span style="font-family:"Consolas\,";color:blue">return</span><span style="font-family:"Consolas\,";color:black"> *(C*)</span><span style="font-family:"Consolas\,";color:#09885A">0
</span> must be kept in _try scope and the access-violation fault will be caught in _except handler where
<span style="font-family:"Consolas\,";color:black">threw_exception() </span>will be called.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">There is no exception with your current implementation.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">LLVM IR load and store instructions are marked volatile. But *(C*)0 doesn’t generate an LLVM IR load or store instruction; it gets lowered to a llvm.memcpy. The LLVM optimizer will erase that, because dereferencing a null pointer is undefined
in C. Therefore, threw_exception will never be called. We didn’t move a fault-generating instruction across the boundary; the binary never contained a fault-generating instruction in the first place.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">From your response, clearly you think one of those steps shouldn’t be happening, but I’m not sure which step, or why. I’m assuming “potential faulty instruction” is referring to an assembly instruction, but maybe that’s not right?
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">I don’t see why Register allocation plays a part in this topic. I do see a serious problem in LLVM SJLJ today (All tests in MSVC’s Setjmp suite fail with -O2 that I will look into it soon). But I failed to see
why HW exception is corelated to setjmp/longjmp. These are two totally different features and the approaches employed are also totally different.
<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in">It would be helpful if you can give one example why this proposal need to care about how registers are allocated.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">The point doesn’t have anything to with the specific underlying technique used to handle control flow; the point is that you’re violating the normal LLVM CFG rules in essentially the same way. The code inside the __try will execute, and
then control flow will jump back before the try block, without that jump getting included in the CFG. Therefore, you’ll run into the same classes of issues with optimizations as we do with setjmp.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">For example, suppose you have something roughly like the following in your code:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">__declspec(dllimport) extern int a[10];<o:p></o:p></p>
<p class="MsoNormal">void f() {<o:p></o:p></p>
<p class="MsoNormal">__try {<o:p></o:p></p>
<p class="MsoNormal"> a[0] = 10;<o:p></o:p></p>
<p class="MsoNormal"> a[1] = 20;<o:p></o:p></p>
<p class="MsoNormal"> *(volatile int*)0 = 0;<o:p></o:p></p>
<p class="MsoNormal">} __except (1) {<o:p></o:p></p>
<p class="MsoNormal"> a[0] = 30;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Now, when the code is generated here, we need to compute the address of “a”, and store it somewhere, so we can then do a store. (Well, we’ll assume it does, for the purpose of describing this example.) So the compiler could generate
something like the following sequence of operations:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Before the try block:<o:p></o:p></p>
<p class="MsoNormal">a_address = &a;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In the try block:<o:p></o:p></p>
<p class="MsoNormal">a_val = 10;<o:p></o:p></p>
<p class="MsoNormal">*a_address = a_val;<o:p></o:p></p>
<p class="MsoNormal">a_address += 4;<o:p></o:p></p>
<p class="MsoNormal">a_val = 20;<o:p></o:p></p>
<p class="MsoNormal">*a_address = a_val<o:p></o:p></p>
<p class="MsoNormal">trigger exception<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In the except block:<o:p></o:p></p>
<p class="MsoNormal">a_val = 30;<o:p></o:p></p>
<p class="MsoNormal">*a_address = a_val;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(This is sort of pseudo-assembly using C syntax, so I don’t dive too deeply into target details; hopefully the intent is clear.)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Note that the compiler is assuming that either the try block or the except block will execute, not both, since that’s what the CFG indicates. (At least, that’s what I understand from your proposal.)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Now suppose a_address ends up in a spill slot. So the compiler has a space on the stack dedicated to storing a_address. When we actually trigger an exception, the compiler runs the except block, and loads the value which is supposed to
be &a[0]… but at that point, it actually contains &a[1], so it writes the value “30” to the wrong address. That’s a miscompile, similar to the one described in the link I gave you.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This is skipping over a lot of details about how the compiler makes various decisions about where to compute and store data (you’d need somewhat more complicated example to make the compiler actually spill this way), but this is a rough
outline of why your choice not to model the CFG correctly matters. <o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">-Eli<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Again what we intend to do in this feature is to achieve these two points below. Please take a moment to read through it. Let me know if there is anything unclear.
<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Thanks<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">--Ten<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">**** The rules for C code: ****<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> For C-code, one way (MSVC approach) to achieve SEH -EHa semantic is to<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> follow three rules. <span style="background:yellow;mso-highlight:yellow">
First, no exception can move in or out of _try<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:1.0in"><span style="background:yellow;mso-highlight:yellow"> region., i.e., no "potential faulty instruction can be moved across _try<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:1.0in"><span style="background:yellow;mso-highlight:yellow"> boundary</span>. Second, the order of exceptions for instructions 'directly'<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> under a _try must be preserved (not applied to those in callees).<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> Finally, global states (local/global/heap variables) that can be read<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> outside of _try region must be updated in memory (not just in register)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> before the subsequent exception occurs.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> **** The impact to C++ code: ****<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> Although SEH is a feature for C code, -EHa does have a profound effect<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> on C++ side. When a C++ function (in the same compilation unit with<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> option -EHa ) is called by a SEH C function, a hardware exception occurs<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> in C++ code can also be handled properly by an upstream SEH _try-handler<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> or a C++ catch(...). As such, when that happens in the middle of an<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> object's life scope, the dtor must be invoked the same way as C++<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"> Synchronous Exception during unwinding process.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-left:.5in"><b>From:</b> Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>>
<br>
<b>Sent:</b> Wednesday, April 15, 2020 4:29 PM<br>
<b>To:</b> Ten Tzen <<a href="mailto:tentzen@microsoft.com">tentzen@microsoft.com</a>>;
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Cc:</b> <a href="mailto:rnk@google.com">rnk@google.com</a>; Aaron Smith <<a href="mailto:aaron.smith@microsoft.com">aaron.smith@microsoft.com</a>>; Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com">jotrem@microsoft.com</a>><br>
<b>Subject:</b> [EXTERNAL] RE: [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">I still have basically the same concerns. I’ll try to give more concrete examples for what I’m concerned about.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Suppose I have something like the following:<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:blue">typedef</span><span style="font-family:"Consolas\,";color:black"> </span><span style="font-family:"Consolas\,";color:blue">struct</span><span style="font-family:"Consolas\,";color:black"> C { </span><span style="font-family:"Consolas\,";color:blue">int</span><span style="font-family:"Consolas\,";color:black"> x[</span><span style="font-family:"Consolas\,";color:#09885A">2</span><span style="font-family:"Consolas\,";color:black">]; } C;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:blue">void</span><span style="font-family:"Consolas\,";color:black"> threw_exception();<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:blue">void</span><span style="font-family:"Consolas\,";color:black"> z();<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black">C f() {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> __try {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> z();<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> </span><span style="font-family:"Consolas\,";color:blue">return</span><span style="font-family:"Consolas\,";color:black"> *(C*)</span><span style="font-family:"Consolas\,";color:#09885A">0</span><span style="font-family:"Consolas\,";color:black">;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> } __except(</span><span style="font-family:"Consolas\,";color:#09885A">1</span><span style="font-family:"Consolas\,";color:black">) {<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> threw_exception();<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> }<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> C c = {</span><span style="font-family:"Consolas\,";color:#09885A">0</span><span style="font-family:"Consolas\,";color:black">};<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"> </span><span style="font-family:"Consolas\,";color:blue">return</span><span style="font-family:"Consolas\,";color:black"> c;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black">}<o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in;background:#FFFFFE"><span style="font-family:"Consolas\,";color:black"><o:p> </o:p></span></p>
<p class="MsoNormal" style="margin-left:.5in">Currently, under your proposal, this won’t call threw_exception() if optimization is enabled, as far as I can tell. I have no idea if this is intentional: your proposal and your patch don’t contain or point to
any documentation, and I can’t find any documentation that describes this on Microsoft’s website. (I don’t really care what the answer is here; I care that there’s some documented answer to this question, and other questions like it.)<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">Constructing a testcase for the register allocation issues I mentioned before is hard because it’s sort of “random” based on the register allocation heuristics, but see
<a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Freviews.llvm.org%2FD77767&data=02%7C01%7Ctentzen%40microsoft.com%7Cf4d98f9b3ba2412901d908d7ed99b658%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637239116754396919&sdata=gCUgqv3o2j8AdjcZah7LUcd6f%2BAgXSPj4Wqhsr8%2Bu4I%3D&reserved=0">
https://reviews.llvm.org/D77767</a> for the sort of issues that come up. Note that we mark setjmp returns_twice, which turns off certain optimizations. I don’t really like extending the usage of this sort of construct further, but if we are going to, we should
at least mark the new intrinsics returns_twice, so they get the same protection as setjmp.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:.5in">-Eli<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:.5in"><o:p> </o:p></p>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-left:1.0in"><b>From:</b> Ten Tzen <<a href="mailto:tentzen@microsoft.com">tentzen@microsoft.com</a>>
<br>
<b>Sent:</b> Wednesday, April 15, 2020 1:51 PM<br>
<b>To:</b> <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<b>Cc:</b> <a href="mailto:rnk@google.com">rnk@google.com</a>; Eli Friedman <<a href="mailto:efriedma@quicinc.com">efriedma@quicinc.com</a>>;
<a href="mailto:aaron.smith@microsoft.com">aaron.smith@microsoft.com</a>; Joseph Tremoulet <<a href="mailto:jotrem@microsoft.com">jotrem@microsoft.com</a>><br>
<b>Subject:</b> [EXT] [RFC] [Windows SEH][-EHa] Support Hardware Exception Handling<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal" style="margin-left:1.0in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">Hi, <o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">This is a spin-off of previous Windows SEH RFC below. This RFC only focus on supporting HW Exception Handling.<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">A detailed implementation can be seen in here:
<a href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftentzen%2Fllvm-project%2Fcommit%2F8a2421c274b683051e456cbe12c177e3b934fb5e&data=02%7C01%7Ctentzen%40microsoft.com%7Cf4d98f9b3ba2412901d908d7ed99b658%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637239116754396919&sdata=UsstqRVUM%2FkMw6zc8JDlnFNI03cpSracVfotDbo0UhQ%3D&reserved=0">
https://github.com/tentzen/llvm-project/commit/8a2421c274b683051e456cbe12c177e3b934fb5e</a><o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">It passes all MSVC SEH suite (excluding those with “Jumping out of _finally” ( _Local_Unwind)).<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"><o:p> </o:p></p>
<p class="MsoNormal" style="margin-left:1.0in">Thanks,<o:p></o:p></p>
<p class="MsoNormal" style="margin-left:1.0in"><o:p> </o:p></p>
</div>
</body>
</html>