<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - ConstantHoisting illegally modifying EHPad"
href="https://bugs.llvm.org/show_bug.cgi?id=32107">32107</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>ConstantHoisting illegally modifying EHPad
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Scalar Optimizations
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>robert.olliff@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Created <span class=""><a href="attachment.cgi?id=18037" name="attach_18037" title="lit test files and patch diff">attachment 18037</a> <a href="attachment.cgi?id=18037&action=edit" title="lit test files and patch diff">[details]</a></span>
lit test files and patch diff
The attached patch file modifies Constant Hoisting so that instead of hoisting
a constant into an EHPad, it is hoisted to the idom of the EHPad.
Tests using attached files
RUN: opt -S -consthoist < ehpad.ll
Result: Verifier fails,
"CatchSwitchInst not the first non-PHI instruction in the block."
RUN: llc ehpad.ll
Result: crash in
llvm::SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks
RUN: clang -cc1 -S -O2 -fexceptions -fcxx-exceptions -emit-codegen-only
ehpad.cpp
Result: crash in
llvm::SelectionDAGBuilder::HandlePHINodesInSuccessorBlocks
In the attached program, the problem IR causing the failure is this BasicBlock:
catch.dispatch: ; preds = %2, %1
%z.0 = phi i64 [ %call, %1 ], [ %call1, %2 ]
%3 = catchswitch within none [label %4] unwind to caller
catch.dispatch is a catchswitch EHPad block, which are supposed to be used by
the compiler as "data only"[1], meaning that they do not have a direct
MachineBasicBlock counterpart. The problem with the block above is that it
contains a machinecode emitting instruction (phi), which means the block must
have a corresponding MachineBasicBlock. This causes confusion (and crashing)
during the SelectionDAGISel pass since the block is technically an EHPad
(catchswitch is first non-phi), but also emits machinecode (via phi). One part
of the pass[2] sees a catchswitch-EHPad block and does not create a
corresponding MachineBasicBlock, while another part[3] sees a standard
BasicBlock and crashes when attempting to use the corresponding
MachineBasicBlock. In debug configuration, this conflict is detected earlier
via an assertion during MachineBasicBlock creation. The assertion fails when a
BB is a catchswitch-EHPad and the catchswitch instruction is NOT the first
instruction[4].
Under normal conditions, this problematic phi would have been removed via
demotion before execution of SelectionDAGISel[5]; However, in the case of
catch.dispatch, phi demotion is not run because “Constant Hoisting” added a
bitcast instruction following the phi (See Listing 1), which in turn results in
an illegal EHPad (catchswitch is not the first non-phi instruction). The end
result is that phi-demotion does not see the block as an EHPad and does not
operate upon the block[6].
Another interesting note is that, after phi-demotion, a call to
SimplifyInstructionsInBlock is made. This general optimization utility undoes
the “optimizations” Constant Hoisting did. So there seems to be some confusion
on what an optimized constant looks like.
Listing 1: Constant Hoisting
Before Constant Hoisting
catch.dispatch: ; preds = %2, %1
%z.0 = phi i64 [ %call, %1 ], [ %call1, %2 ]
%3 = catchswitch within none [label %4] unwind to caller
; <label>:4: ; preds = %catch.dispatch
%5 = catchpad within %3 [i8* null, i32 64, i8* null]
%call4 = tail call i64 @fn(i64 %z.0) [ "funclet"(token %5) ]
%add = add i64 %call4, 9209618997431186100
%call5 = tail call i64 @fn(i64 %add) [ "funclet"(token %5) ]
%add6 = add i64 %call5, 9209618997431186100
%call7 = tail call i64 @fn(i64 %add6) [ "funclet"(token %5) ]
%call8 = tail call i64 @fn(i64 %call7) [ "funclet"(token %5) ]
catchret from %5 to label %6
After Constant Hoisting
catch.dispatch: ; preds = %2, %1
%z.0 = phi i64 [ %call, %1 ], [ %call1, %2 ]
%const = bitcast i64 9209618997431186100 to i64
%3 = catchswitch within none [label %4] unwind to caller
; <label>:4: ; preds = %catch.dispatch
%5 = catchpad within %3 [i8* null, i32 64, i8* null]
%call4 = tail call i64 @fn(i64 %z.0) [ "funclet"(token %5) ]
%add = add i64 %call4, %const
%call5 = tail call i64 @fn(i64 %add) [ "funclet"(token %5) ]
%add6 = add i64 %call5, %const
%call7 = tail call i64 @fn(i64 %add6) [ "funclet"(token %5) ]
%call8 = tail call i64 @fn(i64 %call7) [ "funclet"(token %5) ]
catchret from %5 to label %6
[1] Description,
<a href="https://github.com/llvm-mirror/llvm/commit/18329ced975b85fbcf34aaa928e5d66fe8da8282">https://github.com/llvm-mirror/llvm/commit/18329ced975b85fbcf34aaa928e5d66fe8da8282</a>
[2] SourceCode,
<a href="https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L265-L268">https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L265-L268</a>
[3] SourceCode,
<a href="https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp#L8318-L8325">https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp#L8318-L8325</a>
[4] SourceCode,
<a href="https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L266">https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L266</a>
[5] SourceCode,
<a href="https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L680-L707">https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L680-L707</a>
[6] SourceCode,
<a href="https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L685-L686">https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L685-L686</a></pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>