From: Reid Kleckner Date: Wed, 1 Mar 2017 22:41:12 +0000 (+0000) Subject: [Constant Hoisting] Avoid inserting instructions before EH pads X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=386f13715ae428fa267a9941c9d11f018c71d827;p=llvm [Constant Hoisting] Avoid inserting instructions before EH pads Now that terminators can be EH pads, this code needs to iterate over the immediate dominators of the EH pad to find a valid insertion point. Fix for PR32107 Patch by Robert Olliff! Differential Revision: https://reviews.llvm.org/D30511 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296698 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/ConstantHoisting.cpp b/lib/Transforms/Scalar/ConstantHoisting.cpp index ebe35aac098..ee6333e8871 100644 --- a/lib/Transforms/Scalar/ConstantHoisting.cpp +++ b/lib/Transforms/Scalar/ConstantHoisting.cpp @@ -136,8 +136,16 @@ Instruction *ConstantHoistingPass::findMatInsertPt(Instruction *Inst, if (Idx != ~0U && isa(Inst)) return cast(Inst)->getIncomingBlock(Idx)->getTerminator(); - BasicBlock *IDom = DT->getNode(Inst->getParent())->getIDom()->getBlock(); - return IDom->getTerminator(); + // This must be an EH pad. Iterate over immediate dominators until we find a + // non-EH pad. We need to skip over catchswitch blocks, which are both EH pads + // and terminators. + auto IDom = DT->getNode(Inst->getParent())->getIDom(); + while (IDom->getBlock()->isEHPad()) { + assert(Entry != IDom->getBlock() && "eh pad in entry block"); + IDom = IDom->getIDom(); + } + + return IDom->getBlock()->getTerminator(); } /// \brief Find an insertion point that dominates all uses. diff --git a/test/Transforms/ConstantHoisting/X86/ehpad.ll b/test/Transforms/ConstantHoisting/X86/ehpad.ll new file mode 100644 index 00000000000..3178e87f754 --- /dev/null +++ b/test/Transforms/ConstantHoisting/X86/ehpad.ll @@ -0,0 +1,62 @@ +; RUN: opt -S -consthoist < %s | FileCheck %s + +; FIXME: The catchpad doesn't even use the constant, so a better fix would be to +; insert the bitcast in the catchpad block. + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +; CHECK-LABEL: define i32 @main +; CHECK: %tobool = icmp eq i32 %argc, 0 +; CHECK-NEXT: bitcast i64 9209618997431186100 to i64 +; CHECK-NEXT: br i1 %tobool + +; Function Attrs: norecurse +define i32 @main(i32 %argc, i8** nocapture readnone %argv) local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { + %call = tail call i64 @fn(i64 0) + %call1 = tail call i64 @fn(i64 1) + %tobool = icmp eq i32 %argc, 0 + br i1 %tobool, label %2, label %1 + +;