[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