[llvm-bugs] [Bug 32107] New: ConstantHoisting illegally modifying EHPad
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Mar 1 10:26:54 PST 2017
https://bugs.llvm.org/show_bug.cgi?id=32107
Bug ID: 32107
Summary: ConstantHoisting illegally modifying EHPad
Product: libraries
Version: trunk
Hardware: PC
OS: Windows NT
Status: NEW
Severity: normal
Priority: P
Component: Scalar Optimizations
Assignee: unassignedbugs at nondot.org
Reporter: robert.olliff at gmail.com
CC: llvm-bugs at lists.llvm.org
Created attachment 18037
--> https://bugs.llvm.org/attachment.cgi?id=18037&action=edit
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,
https://github.com/llvm-mirror/llvm/commit/18329ced975b85fbcf34aaa928e5d66fe8da8282
[2] SourceCode,
https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L265-L268
[3] SourceCode,
https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp#L8318-L8325
[4] SourceCode,
https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp#L266
[5] SourceCode,
https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L680-L707
[6] SourceCode,
https://github.com/llvm-mirror/llvm/blob/1896046c882da400cd0e898c5ef5b3cdabd9d824/lib/CodeGen/WinEHPrepare.cpp#L685-L686
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170301/c0d73445/attachment-0001.html>
More information about the llvm-bugs
mailing list