[llvm] r245149 - [IR] Give catchret an optional 'return value' operand

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 19:46:09 PDT 2015


Author: majnemer
Date: Fri Aug 14 21:46:08 2015
New Revision: 245149

URL: http://llvm.org/viewvc/llvm-project?rev=245149&view=rev
Log:
[IR] Give catchret an optional 'return value' operand

Some personality routines require funclet exit points to be clearly
marked, this is done by producing a token at the funclet pad and
consuming it at the corresponding ret instruction.  CleanupReturnInst
already had a spot for this operand but CatchReturnInst did not.
Other personality routines don't need to use this which is why it has
been made optional.

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/Instructions.h
    llvm/trunk/lib/Analysis/CaptureTracking.cpp
    llvm/trunk/lib/Analysis/InstructionSimplify.cpp
    llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/lib/IR/Dominators.cpp
    llvm/trunk/lib/IR/Instructions.cpp
    llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
    llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
    llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
    llvm/trunk/test/CodeGen/WinEH/wineh-demotion.ll
    llvm/trunk/test/Feature/exception.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Fri Aug 14 21:46:08 2015
@@ -5284,7 +5284,7 @@ Syntax:
 
 ::
 
-      catchret label <normal>
+      catchret <type> <value> to label <normal>
 
 Overview:
 """""""""
@@ -5308,6 +5308,7 @@ whose unwinding was interrupted with a
 The :ref:`personality function <personalityfn>` gets a chance to execute
 arbitrary code to, for example, run a C++ destructor.
 Control then transfers to ``normal``.
+It may be passed an optional, personality specific, value.
 
 Example:
 """"""""

Modified: llvm/trunk/include/llvm/IR/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instructions.h?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instructions.h (original)
+++ llvm/trunk/include/llvm/IR/Instructions.h Fri Aug 14 21:46:08 2015
@@ -4037,8 +4037,11 @@ class CatchReturnInst : public Terminato
   CatchReturnInst(const CatchReturnInst &RI);
 
 private:
-  CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore = nullptr);
-  CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd);
+  void init(BasicBlock *BB, Value *RetVal);
+  CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+                  Instruction *InsertBefore = nullptr);
+  CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+                  BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
@@ -4046,22 +4049,35 @@ protected:
   CatchReturnInst *cloneImpl() const;
 
 public:
-  static CatchReturnInst *Create(BasicBlock *BB,
+  static CatchReturnInst *Create(BasicBlock *BB, Value *RetVal = nullptr,
                                  Instruction *InsertBefore = nullptr) {
-    return new (1) CatchReturnInst(BB, InsertBefore);
+    assert(BB);
+    unsigned Values = 1;
+    if (RetVal)
+      ++Values;
+    return new (Values) CatchReturnInst(BB, RetVal, Values, InsertBefore);
   }
-  static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) {
-    return new (1) CatchReturnInst(BB, InsertAtEnd);
+  static CatchReturnInst *Create(BasicBlock *BB, Value *RetVal,
+                                 BasicBlock *InsertAtEnd) {
+    assert(BB);
+    unsigned Values = 1;
+    if (RetVal)
+      ++Values;
+    return new (Values) CatchReturnInst(BB, RetVal, Values, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
   /// Convenience accessors.
-  BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<0>()); }
-  void setSuccessor(BasicBlock *NewSucc) { Op<0>() = (Value *)NewSucc; }
+  BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<-1>()); }
+  void setSuccessor(BasicBlock *NewSucc) { Op<-1>() = (Value *)NewSucc; }
   unsigned getNumSuccessors() const { return 1; }
 
+  bool hasReturnValue() const { return getNumOperands() > 1; }
+  Value *getReturnValue() const { return Op<-2>(); }
+  void setReturnValue(Value *RetVal) { Op<-2>() = RetVal; }
+
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
     return (I->getOpcode() == Instruction::CatchRet);
@@ -4078,7 +4094,7 @@ private:
 
 template <>
 struct OperandTraits<CatchReturnInst>
-    : public FixedNumOperandTraits<CatchReturnInst, /*ARITY=*/1> {};
+    : public VariadicOperandTraits<CatchReturnInst> {};
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
 

Modified: llvm/trunk/lib/Analysis/CaptureTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CaptureTracking.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CaptureTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/CaptureTracking.cpp Fri Aug 14 21:46:08 2015
@@ -80,11 +80,12 @@ namespace {
       if (BB == BeforeHere->getParent()) {
         // 'I' dominates 'BeforeHere' => not safe to prune.
         //
-        // The value defined by an invoke dominates an instruction only if it
-        // dominates every instruction in UseBB. A PHI is dominated only if
-        // the instruction dominates every possible use in the UseBB. Since
+        // The value defined by an invoke/catchpad dominates an instruction only
+        // if it dominates every instruction in UseBB. A PHI is dominated only
+        // if the instruction dominates every possible use in the UseBB. Since
         // UseBB == BB, avoid pruning.
-        if (isa<InvokeInst>(BeforeHere) || isa<PHINode>(I) || I == BeforeHere)
+        if (isa<InvokeInst>(BeforeHere) || isa<CatchPadInst>(BeforeHere) ||
+            isa<PHINode>(I) || I == BeforeHere)
           return false;
         if (!OrderedBB->dominates(BeforeHere, I))
           return false;

Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Fri Aug 14 21:46:08 2015
@@ -123,9 +123,9 @@ static bool ValueDominatesPHI(Value *V,
   }
 
   // Otherwise, if the instruction is in the entry block, and is not an invoke,
-  // then it obviously dominates all phi nodes.
+  // and is not a catchpad, then it obviously dominates all phi nodes.
   if (I->getParent() == &I->getParent()->getParent()->getEntryBlock() &&
-      !isa<InvokeInst>(I))
+      !isa<InvokeInst>(I) && !isa<CatchPadInst>(I))
     return true;
 
   return false;

Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Fri Aug 14 21:46:08 2015
@@ -146,6 +146,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(
   BasicBlock::iterator IP = I; ++IP;
   if (InvokeInst *II = dyn_cast<InvokeInst>(I))
     IP = II->getNormalDest()->begin();
+  if (CatchPadInst *CPI = dyn_cast<CatchPadInst>(I))
+    IP = CPI->getNormalDest()->begin();
   while (isa<PHINode>(IP) || isa<LandingPadInst>(IP))
     ++IP;
   return ReuseOrCreateCast(I, Ty, Op, IP);

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Fri Aug 14 21:46:08 2015
@@ -5027,13 +5027,24 @@ bool LLParser::ParseCleanupRet(Instructi
 }
 
 /// ParseCatchRet
-///   ::= 'catchret' TypeAndValue
+///   ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue
 bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
+  Type *RetTy = nullptr;
+  Value *RetVal = nullptr;
+
+  if (ParseType(RetTy, /*AllowVoid=*/true))
+    return true;
+
+  if (!RetTy->isVoidTy())
+    if (ParseValue(RetTy, RetVal, PFS))
+      return true;
+
   BasicBlock *BB;
-  if (ParseTypeAndBasicBlock(BB, PFS))
+  if (ParseToken(lltok::kw_to, "expected 'to' in catchret") ||
+      ParseTypeAndBasicBlock(BB, PFS))
       return true;
 
-  Inst = CatchReturnInst::Create(BB);
+  Inst = CatchReturnInst::Create(BB, RetVal);
   return false;
 }
 

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Aug 14 21:46:08 2015
@@ -3847,12 +3847,18 @@ std::error_code BitcodeReader::parseFunc
       break;
     }
     case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#]
-      if (Record.size() != 1)
+      if (Record.size() != 1 && Record.size() != 3)
         return error("Invalid record");
-      BasicBlock *BB = getBasicBlock(Record[0]);
+      unsigned Idx = 0;
+      BasicBlock *BB = getBasicBlock(Record[Idx++]);
       if (!BB)
         return error("Invalid record");
-      I = CatchReturnInst::Create(BB);
+      Value *RetVal = nullptr;
+      if (Record.size() == 3 &&
+          getValueTypePair(Record, Idx, NextValueNo, RetVal))
+        return error("Invalid record");
+
+      I = CatchReturnInst::Create(BB, RetVal);
       InstructionList.push_back(I);
       break;
     }

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Fri Aug 14 21:46:08 2015
@@ -1867,6 +1867,8 @@ static void WriteInstruction(const Instr
     Code = bitc::FUNC_CODE_INST_CATCHRET;
     const auto &CRI = cast<CatchReturnInst>(I);
     Vals.push_back(VE.getValueID(CRI.getSuccessor()));
+    if (CRI.hasReturnValue())
+      PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
     break;
   }
   case Instruction::CatchPad: {

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Fri Aug 14 21:46:08 2015
@@ -2900,6 +2900,16 @@ void AssemblyWriter::printInstruction(co
     Out << "]";
   } else if (isa<ReturnInst>(I) && !Operand) {
     Out << " void";
+  } else if (const auto *CRI = dyn_cast<CatchReturnInst>(&I)) {
+    if (CRI->hasReturnValue()) {
+      Out << ' ';
+      writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
+    } else {
+      Out << " void";
+    }
+
+    Out << " to ";
+    writeOperand(CRI->getSuccessor(), /*PrintType=*/true);
   } else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
     if (CRI->hasReturnValue()) {
       Out << ' ';

Modified: llvm/trunk/lib/IR/Dominators.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Dominators.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Dominators.cpp (original)
+++ llvm/trunk/lib/IR/Dominators.cpp Fri Aug 14 21:46:08 2015
@@ -91,11 +91,11 @@ bool DominatorTree::dominates(const Inst
   if (Def == User)
     return false;
 
-  // The value defined by an invoke dominates an instruction only if
+  // The value defined by an invoke/catchpad dominates an instruction only if
   // it dominates every instruction in UseBB.
   // A PHI is dominated only if the instruction dominates every possible use
   // in the UseBB.
-  if (isa<InvokeInst>(Def) || isa<PHINode>(User))
+  if (isa<InvokeInst>(Def) || isa<CatchPadInst>(Def) || isa<PHINode>(User))
     return dominates(Def, UseBB);
 
   if (DefBB != UseBB)
@@ -126,15 +126,20 @@ bool DominatorTree::dominates(const Inst
   if (DefBB == UseBB)
     return false;
 
-  const InvokeInst *II = dyn_cast<InvokeInst>(Def);
-  if (!II)
-    return dominates(DefBB, UseBB);
+  // Invoke/CatchPad results are only usable in the normal destination, not in
+  // the exceptional destination.
+  if (const auto *II = dyn_cast<InvokeInst>(Def)) {
+    BasicBlock *NormalDest = II->getNormalDest();
+    BasicBlockEdge E(DefBB, NormalDest);
+    return dominates(E, UseBB);
+  }
+  if (const auto *CPI = dyn_cast<CatchPadInst>(Def)) {
+    BasicBlock *NormalDest = CPI->getNormalDest();
+    BasicBlockEdge E(DefBB, NormalDest);
+    return dominates(E, UseBB);
+  }
 
-  // Invoke results are only usable in the normal destination, not in the
-  // exceptional destination.
-  BasicBlock *NormalDest = II->getNormalDest();
-  BasicBlockEdge E(DefBB, NormalDest);
-  return dominates(E, UseBB);
+  return dominates(DefBB, UseBB);
 }
 
 bool DominatorTree::dominates(const BasicBlockEdge &BBE,
@@ -232,7 +237,7 @@ bool DominatorTree::dominates(const Inst
   if (!isReachableFromEntry(DefBB))
     return false;
 
-  // Invoke instructions define their return values on the edges
+  // Invoke/CatchPad instructions define their return values on the edges
   // to their normal successors, so we have to handle them specially.
   // Among other things, this means they don't dominate anything in
   // their own block, except possibly a phi, so we don't need to
@@ -242,6 +247,11 @@ bool DominatorTree::dominates(const Inst
     BasicBlockEdge E(DefBB, NormalDest);
     return dominates(E, U);
   }
+  if (const auto *CPI = dyn_cast<CatchPadInst>(Def)) {
+    BasicBlock *NormalDest = CPI->getNormalDest();
+    BasicBlockEdge E(DefBB, NormalDest);
+    return dominates(E, U);
+  }
 
   // If the def and use are in different blocks, do a simple CFG dominator
   // tree query.

Modified: llvm/trunk/lib/IR/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Instructions.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Instructions.cpp (original)
+++ llvm/trunk/lib/IR/Instructions.cpp Fri Aug 14 21:46:08 2015
@@ -797,27 +797,38 @@ void CatchEndPadInst::setSuccessorV(unsi
 //===----------------------------------------------------------------------===//
 //                        CatchReturnInst Implementation
 //===----------------------------------------------------------------------===//
+void CatchReturnInst::init(BasicBlock *BB, Value *RetVal) {
+  Op<-1>() = BB;
+  if (RetVal)
+    Op<-2>() = RetVal;
+}
 
 CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
     : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
                      OperandTraits<CatchReturnInst>::op_end(this) -
                          CRI.getNumOperands(),
                      CRI.getNumOperands()) {
-  Op<0>() = CRI.Op<0>();
+  Op<-1>() = CRI.Op<-1>();
+  if (CRI.getNumOperands() != 1) {
+    assert(CRI.getNumOperands() == 2);
+    Op<-2>() = CRI.Op<-2>();
+  }
 }
 
-CatchReturnInst::CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore)
+CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+                                 Instruction *InsertBefore)
     : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
-                     OperandTraits<CatchReturnInst>::op_begin(this), 1,
-                     InsertBefore) {
-  Op<0>() = BB;
+                     OperandTraits<CatchReturnInst>::op_end(this) - Values,
+                     Values, InsertBefore) {
+  init(BB, RetVal);
 }
 
-CatchReturnInst::CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd)
+CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
+                                 BasicBlock *InsertAtEnd)
     : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
-                     OperandTraits<CatchReturnInst>::op_begin(this), 1,
-                     InsertAtEnd) {
-  Op<0>() = BB;
+                     OperandTraits<CatchReturnInst>::op_end(this) - Values,
+                     Values, InsertAtEnd) {
+  init(BB, RetVal);
 }
 
 BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
@@ -3924,7 +3935,7 @@ CatchEndPadInst *CatchEndPadInst::cloneI
 }
 
 CatchReturnInst *CatchReturnInst::cloneImpl() const {
-  return new (1) CatchReturnInst(*this);
+  return new (getNumOperands()) CatchReturnInst(*this);
 }
 
 CatchPadInst *CatchPadInst::cloneImpl() const {

Modified: llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/Reassociate.cpp Fri Aug 14 21:46:08 2015
@@ -951,6 +951,8 @@ static Value *NegateValue(Value *V, Inst
     if (Instruction *InstInput = dyn_cast<Instruction>(V)) {
       if (InvokeInst *II = dyn_cast<InvokeInst>(InstInput)) {
         InsertPt = II->getNormalDest()->begin();
+      } else if (auto *CPI = dyn_cast<CatchPadInst>(InstInput)) {
+        InsertPt = CPI->getNormalDest()->begin();
       } else {
         InsertPt = InstInput;
         ++InsertPt;

Modified: llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CodeExtractor.cpp Fri Aug 14 21:46:08 2015
@@ -560,14 +560,20 @@ emitCallAndSwitchStatement(Function *new
           // Restore values just before we exit
           Function::arg_iterator OAI = OutputArgBegin;
           for (unsigned out = 0, e = outputs.size(); out != e; ++out) {
-            // For an invoke, the normal destination is the only one that is
-            // dominated by the result of the invocation
+            // For an invoke/catchpad, the normal destination is the only one
+            // that is dominated by the result of the invocation
             BasicBlock *DefBlock = cast<Instruction>(outputs[out])->getParent();
 
             bool DominatesDef = true;
 
-            if (InvokeInst *Invoke = dyn_cast<InvokeInst>(outputs[out])) {
-              DefBlock = Invoke->getNormalDest();
+            BasicBlock *NormalDest = nullptr;
+            if (auto *Invoke = dyn_cast<InvokeInst>(outputs[out]))
+              NormalDest = Invoke->getNormalDest();
+            if (auto *CatchPad = dyn_cast<CatchPadInst>(outputs[out]))
+              NormalDest = CatchPad->getNormalDest();
+
+            if (NormalDest) {
+              DefBlock = NormalDest;
 
               // Make sure we are looking at the original successor block, not
               // at a newly inserted exit block, which won't be in the dominator

Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Fri Aug 14 21:46:08 2015
@@ -82,14 +82,15 @@ static bool processInstruction(Loop &L,
 
   ++NumLCSSA; // We are applying the transformation
 
-  // Invoke instructions are special in that their result value is not available
-  // along their unwind edge. The code below tests to see whether DomBB
-  // dominates
-  // the value, so adjust DomBB to the normal destination block, which is
-  // effectively where the value is first usable.
+  // Invoke/CatchPad instructions are special in that their result value is not
+  // available along their unwind edge. The code below tests to see whether
+  // DomBB dominates the value, so adjust DomBB to the normal destination block,
+  // which is effectively where the value is first usable.
   BasicBlock *DomBB = Inst.getParent();
   if (InvokeInst *Inv = dyn_cast<InvokeInst>(&Inst))
     DomBB = Inv->getNormalDest();
+  if (auto *CPI = dyn_cast<CatchPadInst>(&Inst))
+    DomBB = CPI->getNormalDest();
 
   DomTreeNode *DomNode = DT.getNode(DomBB);
 

Modified: llvm/trunk/test/CodeGen/WinEH/wineh-demotion.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-demotion.ll?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-demotion.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-demotion.ll Fri Aug 14 21:46:08 2015
@@ -43,7 +43,7 @@ catch:
   ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
   ; CHECK-NEXT: call void @h(i32 [[Reload]])
   call void @h(i32 %phi)
-  catchret label %exit
+  catchret void to label %exit
 
 catchend:
   catchendpad unwind to caller
@@ -89,7 +89,7 @@ catch.inner:
           to label %catchret.inner unwind label %merge.outer
 
 catchret.inner:
-  catchret label %exit
+  catchret void to label %exit
 catchend.inner:
   catchendpad unwind label %merge.outer
 
@@ -109,10 +109,10 @@ catch.outer:
   ; CHECK: catch.outer:
   ; CHECK-DAG: load i32, i32* [[Slot1]]
   ; CHECK-DAG: load i32, i32* [[Slot2]]
-  ; CHECK: catchret label
+  ; CHECK: catchret void to label
   call void @h(i32 %x)
   call void @h(i32 %y)
-  catchret label %exit
+  catchret void to label %exit
 
 exit:
   ret void
@@ -152,7 +152,7 @@ merge:
   ; CHECK:   %phi = phi i32 [ [[ReloadX]], %left ]
   %phi = phi i32 [ %x, %left ], [ 42, %right ]
   call void @h(i32 %phi)
-  catchret label %exit
+  catchret void to label %exit
 
 catchend:
   catchendpad unwind to caller
@@ -192,7 +192,7 @@ catchpad.inner:
    %phi.inner = phi i32 [ %l, %left ], [ %r, %right ]
    catchpad void [] to label %catch.inner unwind label %catchend.inner
 catch.inner:
-   catchret label %join
+   catchret void to label %join
 catchend.inner:
    catchendpad unwind label  %catchpad.outer
 join:
@@ -213,7 +213,7 @@ catch.outer:
    ; CHECK:   [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
    ; CHECK:   call void @h(i32 [[Reload]])
    call void @h(i32 %phi.outer)
-   catchret label %exit
+   catchret void to label %exit
 catchend.outer:
    catchendpad unwind to caller
 exit:
@@ -286,7 +286,7 @@ catch:
   ; CHECK:   [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]]
   ; CHECK:   call void @h(i32 [[CatchReload]]
   call void @h(i32 %phi.catch)
-  catchret label %exit
+  catchret void to label %exit
 
 catchend:
   catchendpad unwind to caller

Modified: llvm/trunk/test/Feature/exception.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/exception.ll?rev=245149&r1=245148&r2=245149&view=diff
==============================================================================
--- llvm/trunk/test/Feature/exception.ll (original)
+++ llvm/trunk/test/Feature/exception.ll Fri Aug 14 21:46:08 2015
@@ -63,7 +63,7 @@ define void @catchret() personality i32
 entry:
   br label %bb
 bb:
-  catchret label %bb
+  catchret void to label %bb
 }
 
 define i8 @catchpad() personality i32 (...)* @__gxx_personality_v0 {
@@ -72,11 +72,16 @@ entry:
 
 try.cont:
   invoke void @_Z3quxv() optsize
-          to label %bb unwind label %bb2
+          to label %exit unwind label %bb2
 bb:
+  catchret token %cbv to label %exit
+
+exit:
   ret i8 0
 bb2:
-  %cbv = catchpad i8 [i7 4] to label %bb unwind label %bb2
+  %cbv = catchpad token [i7 4] to label %bb unwind label %bb3
+bb3:
+  catchendpad unwind to caller
 }
 
 define void @terminatepad0() personality i32 (...)* @__gxx_personality_v0 {




More information about the llvm-commits mailing list