AVX512: Implemented encoding and intrinsics for
[oota-llvm.git] / include / llvm / IR / Instructions.h
index 60ead82e0e24d27a63220f2b2ec0127a85c6ef9a..d979b393066f5a13fc7fa180d3577a755864b582 100644 (file)
@@ -1473,8 +1473,14 @@ public:
 
   /// getArgOperand/setArgOperand - Return/set the i-th call argument.
   ///
-  Value *getArgOperand(unsigned i) const { return getOperand(i); }
-  void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+  Value *getArgOperand(unsigned i) const {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperand(i);
+  }
+  void setArgOperand(unsigned i, Value *v) {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    setOperand(i, v);
+  }
 
   /// arg_operands - iteration adapter for range-for loops.
   iterator_range<op_iterator> arg_operands() {
@@ -1489,8 +1495,14 @@ public:
   }
 
   /// \brief Wrappers for getting the \c Use of a call argument.
-  const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
-  Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+  const Use &getArgOperandUse(unsigned i) const {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperandUse(i);
+  }
+  Use &getArgOperandUse(unsigned i) {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperandUse(i);
+  }
 
   /// getCallingConv/setCallingConv - Get or set the calling convention of this
   /// function call.
@@ -1595,6 +1607,15 @@ public:
     addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
   }
 
+  /// @brief Determine if the call can access memmory only using pointers based
+  /// on its arguments.
+  bool onlyAccessesArgMemory() const {
+    return hasFnAttr(Attribute::ArgMemOnly);
+  }
+  void setOnlyAccessesArgMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+  }
+
   /// \brief Determine if the call cannot return.
   bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
   void setDoesNotReturn() {
@@ -1613,6 +1634,12 @@ public:
     addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate);
   }
 
+  /// \brief Determine if the call is convergent
+  bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }
+  void setConvergent() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::Convergent);
+  }
+
   /// \brief Determine if the call returns a structure through first
   /// pointer argument.
   bool hasStructRetAttr() const {
@@ -2731,7 +2758,7 @@ public:
 
   void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
     assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
-    *(&Op<-1>() - idx) = (Value*)NewSucc;
+    *(&Op<-1>() - idx) = NewSucc;
   }
 
   /// \brief Swap the successors of this branch instruction.
@@ -3047,7 +3074,7 @@ public:
   }
   void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
     assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
-    setOperand(idx*2+1, (Value*)NewSucc);
+    setOperand(idx * 2 + 1, NewSucc);
   }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -3147,7 +3174,7 @@ public:
     return cast<BasicBlock>(getOperand(i+1));
   }
   void setSuccessor(unsigned i, BasicBlock *NewSucc) {
-    setOperand(i+1, (Value*)NewSucc);
+    setOperand(i + 1, NewSucc);
   }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -3259,8 +3286,14 @@ public:
 
   /// getArgOperand/setArgOperand - Return/set the i-th invoke argument.
   ///
-  Value *getArgOperand(unsigned i) const { return getOperand(i); }
-  void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+  Value *getArgOperand(unsigned i) const {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperand(i);
+  }
+  void setArgOperand(unsigned i, Value *v) {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    setOperand(i, v);
+  }
 
   /// arg_operands - iteration adapter for range-for loops.
   iterator_range<op_iterator> arg_operands() {
@@ -3273,8 +3306,14 @@ public:
   }
 
   /// \brief Wrappers for getting the \c Use of a invoke argument.
-  const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
-  Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
+  const Use &getArgOperandUse(unsigned i) const {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperandUse(i);
+  }
+  Use &getArgOperandUse(unsigned i) {
+    assert(i < getNumArgOperands() && "Out of bounds!");
+    return getOperandUse(i);
+  }
 
   /// getCallingConv/setCallingConv - Get or set the calling convention of this
   /// function call.
@@ -3364,6 +3403,15 @@ public:
     addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
   }
 
+  /// @brief Determine if the call access memmory only using it's pointer
+  /// arguments.
+  bool onlyAccessesArgMemory() const {
+    return hasFnAttr(Attribute::ArgMemOnly);
+  }
+  void setOnlyAccessesArgMemory() {
+    addAttribute(AttributeSet::FunctionIndex, Attribute::ArgMemOnly);
+  }
+
   /// \brief Determine if the call cannot return.
   bool doesNotReturn() const { return hasFnAttr(Attribute::NoReturn); }
   void setDoesNotReturn() {
@@ -3552,140 +3600,34 @@ struct OperandTraits<ResumeInst> :
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
 
 //===----------------------------------------------------------------------===//
-//                               CleanupReturnInst Class
+//                               CatchEndPadInst Class
 //===----------------------------------------------------------------------===//
 
-class CleanupReturnInst : public TerminatorInst {
-  CleanupReturnInst(const CleanupReturnInst &RI);
-
-private:
-  void init(Value *RetVal, BasicBlock *UnwindBB);
-  CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
-                    unsigned Values, Instruction *InsertBefore = nullptr);
-  CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
-                    unsigned Values, BasicBlock *InsertAtEnd);
-
-  int getUnwindLabelOpIdx() const {
-    assert(hasUnwindDest());
-    return 0;
-  }
-
-  int getRetValOpIdx() const {
-    assert(hasReturnValue());
-    if (hasUnwindDest())
-      return 1;
-    return 0;
-  }
-
-protected:
-  // Note: Instruction needs to be a friend here to call cloneImpl.
-  friend class Instruction;
-  CleanupReturnInst *cloneImpl() const;
-
-public:
-  static CleanupReturnInst *Create(LLVMContext &C,
-                                   Value *RetVal = nullptr,
-                                   BasicBlock *UnwindBB = nullptr,
-                                   Instruction *InsertBefore = nullptr) {
-    unsigned Values = 0;
-    if (RetVal)
-      ++Values;
-    if (UnwindBB)
-      ++Values;
-    return new (Values)
-        CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertBefore);
-  }
-  static CleanupReturnInst *Create(LLVMContext &C, Value *RetVal,
-                                   BasicBlock *UnwindBB,
-                                   BasicBlock *InsertAtEnd) {
-    unsigned Values = 0;
-    if (RetVal)
-      ++Values;
-    if (UnwindBB)
-      ++Values;
-    return new (Values)
-        CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertAtEnd);
-  }
-
-  /// Provide fast operand accessors
-  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
-  bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
-  bool unwindsToCaller() const { return !hasUnwindDest(); }
-  bool hasReturnValue() const { return getSubclassDataFromInstruction() & 2; }
-
-  /// Convenience accessor. Returns null if there is no return value.
-  Value *getReturnValue() const {
-    if (!hasReturnValue())
-      return nullptr;
-    return getOperand(getRetValOpIdx());
-  }
-  void setReturnValue(Value *RetVal) {
-    assert(hasReturnValue());
-    setOperand(getRetValOpIdx(), RetVal);
-  }
-
-  unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
-
-  BasicBlock *getUnwindDest() const;
-  void setUnwindDest(BasicBlock *NewDest);
-
-  // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const Instruction *I) {
-    return (I->getOpcode() == Instruction::CleanupRet);
-  }
-  static inline bool classof(const Value *V) {
-    return isa<Instruction>(V) && classof(cast<Instruction>(V));
-  }
-
+class CatchEndPadInst : public TerminatorInst {
 private:
-  BasicBlock *getSuccessorV(unsigned Idx) const override;
-  unsigned getNumSuccessorsV() const override;
-  void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+  CatchEndPadInst(const CatchEndPadInst &RI);
 
-  // Shadow Instruction::setInstructionSubclassData with a private forwarding
-  // method so that subclasses cannot accidentally use it.
-  void setInstructionSubclassData(unsigned short D) {
-    Instruction::setInstructionSubclassData(D);
-  }
-};
-
-template <>
-struct OperandTraits<CleanupReturnInst>
-    : public VariadicOperandTraits<CleanupReturnInst> {};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
-
-//===----------------------------------------------------------------------===//
-//                               CatchEndBlockInst Class
-//===----------------------------------------------------------------------===//
-
-class CatchEndBlockInst : public TerminatorInst {
-  CatchEndBlockInst(const CatchEndBlockInst &RI);
-
-private:
   void init(BasicBlock *UnwindBB);
-  CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
-                    Instruction *InsertBefore = nullptr);
-  CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
-                    BasicBlock *InsertAtEnd);
+  CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+                  Instruction *InsertBefore = nullptr);
+  CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
+                  BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
   friend class Instruction;
-  CatchEndBlockInst *cloneImpl() const;
+  CatchEndPadInst *cloneImpl() const;
 
 public:
-  static CatchEndBlockInst *Create(LLVMContext &C,
-                                   BasicBlock *UnwindBB = nullptr,
-                                   Instruction *InsertBefore = nullptr) {
+  static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr,
+                                 Instruction *InsertBefore = nullptr) {
     unsigned Values = UnwindBB ? 1 : 0;
-    return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertBefore);
+    return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore);
   }
-  static CatchEndBlockInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
-                                   BasicBlock *InsertAtEnd) {
+  static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
+                                 BasicBlock *InsertAtEnd) {
     unsigned Values = UnwindBB ? 1 : 0;
-    return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertAtEnd);
+    return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
@@ -3697,7 +3639,9 @@ public:
   /// Convenience accessor. Returns null if there is no return value.
   unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
 
-  BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
+  BasicBlock *getUnwindDest() const {
+    return hasUnwindDest() ? cast<BasicBlock>(Op<-1>()) : nullptr;
+  }
   void setUnwindDest(BasicBlock *NewDest) {
     assert(NewDest);
     Op<-1>() = NewDest;
@@ -3705,7 +3649,7 @@ public:
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
-    return (I->getOpcode() == Instruction::CatchEndBlock);
+    return (I->getOpcode() == Instruction::CatchEndPad);
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -3716,7 +3660,6 @@ private:
   unsigned getNumSuccessorsV() const override;
   void setSuccessorV(unsigned Idx, BasicBlock *B) override;
 
-private:
   // Shadow Instruction::setInstructionSubclassData with a private forwarding
   // method so that subclasses cannot accidentally use it.
   void setInstructionSubclassData(unsigned short D) {
@@ -3725,61 +3668,58 @@ private:
 };
 
 template <>
-struct OperandTraits<CatchEndBlockInst>
-    : public VariadicOperandTraits<CatchEndBlockInst> {};
+struct OperandTraits<CatchEndPadInst>
+    : public VariadicOperandTraits<CatchEndPadInst> {};
 
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndBlockInst, Value)
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndPadInst, Value)
 
 //===----------------------------------------------------------------------===//
-//                           CatchBlockInst Class
+//                           CatchPadInst Class
 //===----------------------------------------------------------------------===//
 
-class CatchBlockInst : public TerminatorInst {
+class CatchPadInst : public TerminatorInst {
 private:
   void init(BasicBlock *IfNormal, BasicBlock *IfException,
             ArrayRef<Value *> Args, const Twine &NameStr);
 
-  CatchBlockInst(const CatchBlockInst &CBI);
+  CatchPadInst(const CatchPadInst &CPI);
 
-  explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
-                          BasicBlock *IfException, ArrayRef<Value *> Args,
-                          unsigned Values, const Twine &NameStr,
-                          Instruction *InsertBefore);
-  explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
-                          BasicBlock *IfException, ArrayRef<Value *> Args,
-                          unsigned Values, const Twine &NameStr,
-                          BasicBlock *InsertAtEnd);
+  explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+                        ArrayRef<Value *> Args, unsigned Values,
+                        const Twine &NameStr, Instruction *InsertBefore);
+  explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
+                        ArrayRef<Value *> Args, unsigned Values,
+                        const Twine &NameStr, BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
   friend class Instruction;
-  CatchBlockInst *cloneImpl() const;
+  CatchPadInst *cloneImpl() const;
 
 public:
-  static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
-                                BasicBlock *IfException, ArrayRef<Value *> Args,
-                                const Twine &NameStr = "",
-                                Instruction *InsertBefore = nullptr) {
+  static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+                              ArrayRef<Value *> Args, const Twine &NameStr = "",
+                              Instruction *InsertBefore = nullptr) {
     unsigned Values = unsigned(Args.size()) + 2;
-    return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
-                                       Values, NameStr, InsertBefore);
+    return new (Values) CatchPadInst(IfNormal, IfException, Args, Values,
+                                     NameStr, InsertBefore);
   }
-  static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
-                                BasicBlock *IfException, ArrayRef<Value *> Args,
-                                const Twine &NameStr, BasicBlock *InsertAtEnd) {
+  static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
+                              ArrayRef<Value *> Args, const Twine &NameStr,
+                              BasicBlock *InsertAtEnd) {
     unsigned Values = unsigned(Args.size()) + 2;
-    return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
-                                       Values, NameStr, InsertAtEnd);
+    return new (Values)
+        CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
 
-  /// getNumArgOperands - Return the number of catchblock arguments.
+  /// getNumArgOperands - Return the number of catchpad arguments.
   ///
   unsigned getNumArgOperands() const { return getNumOperands() - 2; }
 
-  /// getArgOperand/setArgOperand - Return/set the i-th catchblock argument.
+  /// getArgOperand/setArgOperand - Return/set the i-th catchpad argument.
   ///
   Value *getArgOperand(unsigned i) const { return getOperand(i); }
   void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
@@ -3794,31 +3734,31 @@ public:
     return iterator_range<const_op_iterator>(op_begin(), op_end() - 2);
   }
 
-  /// \brief Wrappers for getting the \c Use of a catchblock argument.
+  /// \brief Wrappers for getting the \c Use of a catchpad argument.
   const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
   Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
 
   // get*Dest - Return the destination basic blocks...
   BasicBlock *getNormalDest() const { return cast<BasicBlock>(Op<-2>()); }
   BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
-  void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast<Value *>(B); }
-  void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast<Value *>(B); }
+  void setNormalDest(BasicBlock *B) { Op<-2>() = B; }
+  void setUnwindDest(BasicBlock *B) { Op<-1>() = B; }
 
   BasicBlock *getSuccessor(unsigned i) const {
-    assert(i < 2 && "Successor # out of range for catchblock!");
+    assert(i < 2 && "Successor # out of range for catchpad!");
     return i == 0 ? getNormalDest() : getUnwindDest();
   }
 
   void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
-    assert(idx < 2 && "Successor # out of range for catchblock!");
-    *(&Op<-2>() + idx) = reinterpret_cast<Value *>(NewSucc);
+    assert(idx < 2 && "Successor # out of range for catchpad!");
+    *(&Op<-2>() + idx) = NewSucc;
   }
 
   unsigned getNumSuccessors() const { return 2; }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::CatchBlock;
+    return I->getOpcode() == Instruction::CatchPad;
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -3831,53 +3771,49 @@ private:
 };
 
 template <>
-struct OperandTraits<CatchBlockInst>
-    : public VariadicOperandTraits<CatchBlockInst, /*MINARITY=*/2> {};
+struct OperandTraits<CatchPadInst>
+    : public VariadicOperandTraits<CatchPadInst, /*MINARITY=*/2> {};
 
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchBlockInst, Value)
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value)
 
 //===----------------------------------------------------------------------===//
-//                           TerminateBlockInst Class
+//                           TerminatePadInst Class
 //===----------------------------------------------------------------------===//
 
-class TerminateBlockInst : public TerminatorInst {
+class TerminatePadInst : public TerminatorInst {
 private:
-  void init(BasicBlock *BB, ArrayRef<Value *> Args, const Twine &NameStr);
+  void init(BasicBlock *BB, ArrayRef<Value *> Args);
 
-  TerminateBlockInst(const TerminateBlockInst &TBI);
+  TerminatePadInst(const TerminatePadInst &TPI);
 
-  explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
-                              ArrayRef<Value *> Args, unsigned Values,
-                              const Twine &NameStr, Instruction *InsertBefore);
-  explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
-                              ArrayRef<Value *> Args, unsigned Values,
-                              const Twine &NameStr, BasicBlock *InsertAtEnd);
+  explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
+                            ArrayRef<Value *> Args, unsigned Values,
+                            Instruction *InsertBefore);
+  explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
+                            ArrayRef<Value *> Args, unsigned Values,
+                            BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
   friend class Instruction;
-  TerminateBlockInst *cloneImpl() const;
+  TerminatePadInst *cloneImpl() const;
 
 public:
-  static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
-                                    ArrayRef<Value *> Args = {},
-                                    const Twine &NameStr = "",
-                                    Instruction *InsertBefore = nullptr) {
+  static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
+                                  ArrayRef<Value *> Args = None,
+                                  Instruction *InsertBefore = nullptr) {
     unsigned Values = unsigned(Args.size());
     if (BB)
       ++Values;
-    return new (Values)
-        TerminateBlockInst(C, BB, Args, Values, NameStr, InsertBefore);
+    return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore);
   }
-  static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB,
-                                    ArrayRef<Value *> Args,
-                                    const Twine &NameStr,
-                                    BasicBlock *InsertAtEnd) {
+  static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB,
+                                  ArrayRef<Value *> Args,
+                                  BasicBlock *InsertAtEnd) {
     unsigned Values = unsigned(Args.size());
     if (BB)
       ++Values;
-    return new (Values)
-        TerminateBlockInst(C, BB, Args, Values, NameStr, InsertAtEnd);
+    return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
@@ -3886,7 +3822,7 @@ public:
   bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
   bool unwindsToCaller() const { return !hasUnwindDest(); }
 
-  /// getNumArgOperands - Return the number of terminateblock arguments.
+  /// getNumArgOperands - Return the number of terminatepad arguments.
   ///
   unsigned getNumArgOperands() const {
     unsigned NumOperands = getNumOperands();
@@ -3895,7 +3831,7 @@ public:
     return NumOperands;
   }
 
-  /// getArgOperand/setArgOperand - Return/set the i-th terminateblock argument.
+  /// getArgOperand/setArgOperand - Return/set the i-th terminatepad argument.
   ///
   Value *getArgOperand(unsigned i) const { return getOperand(i); }
   void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
@@ -3922,7 +3858,7 @@ public:
     return iterator_range<const_op_iterator>(op_begin(), arg_end());
   }
 
-  /// \brief Wrappers for getting the \c Use of a terminateblock argument.
+  /// \brief Wrappers for getting the \c Use of a terminatepad argument.
   const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
   Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
 
@@ -3934,14 +3870,14 @@ public:
   }
   void setUnwindDest(BasicBlock *B) {
     assert(B && hasUnwindDest());
-    Op<-1>() = reinterpret_cast<Value *>(B);
+    Op<-1>() = B;
   }
 
   unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::TerminateBlock;
+    return I->getOpcode() == Instruction::TerminatePad;
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -3960,43 +3896,40 @@ private:
 };
 
 template <>
-struct OperandTraits<TerminateBlockInst>
-    : public VariadicOperandTraits<TerminateBlockInst, /*MINARITY=*/1> {};
+struct OperandTraits<TerminatePadInst>
+    : public VariadicOperandTraits<TerminatePadInst, /*MINARITY=*/1> {};
 
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminateBlockInst, Value)
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value)
 
 //===----------------------------------------------------------------------===//
-//                           CleanupBlockInst Class
+//                           CleanupPadInst Class
 //===----------------------------------------------------------------------===//
 
-class CleanupBlockInst : public Instruction {
+class CleanupPadInst : public Instruction {
 private:
   void init(ArrayRef<Value *> Args, const Twine &NameStr);
 
-  CleanupBlockInst(const CleanupBlockInst &TBI);
+  CleanupPadInst(const CleanupPadInst &CPI);
 
-  explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
-                            const Twine &NameStr, Instruction *InsertBefore);
-  explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
-                            const Twine &NameStr, BasicBlock *InsertAtEnd);
+  explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+                          const Twine &NameStr, Instruction *InsertBefore);
+  explicit CleanupPadInst(LLVMContext &C, ArrayRef<Value *> Args,
+                          const Twine &NameStr, BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
   friend class Instruction;
-  CleanupBlockInst *cloneImpl() const;
+  CleanupPadInst *cloneImpl() const;
 
 public:
-  static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
-                                  const Twine &NameStr = "",
-                                  Instruction *InsertBefore = nullptr) {
-    return new (Args.size())
-        CleanupBlockInst(RetTy, Args, NameStr, InsertBefore);
+  static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+                                const Twine &NameStr = "",
+                                Instruction *InsertBefore = nullptr) {
+    return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore);
   }
-  static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
-                                  const Twine &NameStr,
-                                  BasicBlock *InsertAtEnd) {
-    return new (Args.size())
-        CleanupBlockInst(RetTy, Args, NameStr, InsertAtEnd);
+  static CleanupPadInst *Create(LLVMContext &C, ArrayRef<Value *> Args,
+                                const Twine &NameStr, BasicBlock *InsertAtEnd) {
+    return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
@@ -4004,7 +3937,7 @@ public:
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Instruction *I) {
-    return I->getOpcode() == Instruction::CleanupBlock;
+    return I->getOpcode() == Instruction::CleanupPad;
   }
   static inline bool classof(const Value *V) {
     return isa<Instruction>(V) && classof(cast<Instruction>(V));
@@ -4012,10 +3945,10 @@ public:
 };
 
 template <>
-struct OperandTraits<CleanupBlockInst>
-    : public VariadicOperandTraits<CleanupBlockInst, /*MINARITY=*/0> {};
+struct OperandTraits<CleanupPadInst>
+    : public VariadicOperandTraits<CleanupPadInst, /*MINARITY=*/0> {};
 
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value)
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value)
 
 //===----------------------------------------------------------------------===//
 //                               CatchReturnInst Class
@@ -4024,10 +3957,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value)
 class CatchReturnInst : public TerminatorInst {
   CatchReturnInst(const CatchReturnInst &RI);
 
-private:
-  void init(Value *RetVal, BasicBlock *UnwindBB);
-  CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore = nullptr);
-  CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd);
+  void init(CatchPadInst *CatchPad, BasicBlock *BB);
+  CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+                  Instruction *InsertBefore);
+  CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
+                  BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
@@ -4035,20 +3969,34 @@ protected:
   CatchReturnInst *cloneImpl() const;
 
 public:
-  static CatchReturnInst *Create(BasicBlock *BB,
+  static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
                                  Instruction *InsertBefore = nullptr) {
-    return new (1) CatchReturnInst(BB, InsertBefore);
+    assert(CatchPad);
+    assert(BB);
+    return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
   }
-  static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) {
-    return new (1) CatchReturnInst(BB, InsertAtEnd);
+  static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
+                                 BasicBlock *InsertAtEnd) {
+    assert(CatchPad);
+    assert(BB);
+    return new (2) CatchReturnInst(CatchPad, BB, 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; }
+  CatchPadInst *getCatchPad() const { return cast<CatchPadInst>(Op<0>()); }
+  void setCatchPad(CatchPadInst *CatchPad) {
+    assert(CatchPad);
+    Op<0>() = CatchPad;
+  }
+
+  BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<1>()); }
+  void setSuccessor(BasicBlock *NewSucc) {
+    assert(NewSucc);
+    Op<1>() = NewSucc;
+  }
   unsigned getNumSuccessors() const { return 1; }
 
   // Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -4067,10 +4015,190 @@ private:
 
 template <>
 struct OperandTraits<CatchReturnInst>
-    : public FixedNumOperandTraits<CatchReturnInst, /*ARITY=*/1> {};
+    : public FixedNumOperandTraits<CatchReturnInst, 2> {};
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
 
+//===----------------------------------------------------------------------===//
+//                               CleanupEndPadInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupEndPadInst : public TerminatorInst {
+private:
+  CleanupEndPadInst(const CleanupEndPadInst &CEPI);
+
+  void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
+  CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+                    unsigned Values, Instruction *InsertBefore = nullptr);
+  CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+                    unsigned Values, BasicBlock *InsertAtEnd);
+
+protected:
+  // Note: Instruction needs to be a friend here to call cloneImpl.
+  friend class Instruction;
+  CleanupEndPadInst *cloneImpl() const;
+
+public:
+  static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+                                   BasicBlock *UnwindBB = nullptr,
+                                   Instruction *InsertBefore = nullptr) {
+    unsigned Values = UnwindBB ? 2 : 1;
+    return new (Values)
+        CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertBefore);
+  }
+  static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad,
+                                   BasicBlock *UnwindBB,
+                                   BasicBlock *InsertAtEnd) {
+    unsigned Values = UnwindBB ? 2 : 1;
+    return new (Values)
+        CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+  bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+  unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+  /// Convenience accessors
+  CleanupPadInst *getCleanupPad() const {
+    return cast<CleanupPadInst>(Op<-1>());
+  }
+  void setCleanupPad(CleanupPadInst *CleanupPad) {
+    assert(CleanupPad);
+    Op<-1>() = CleanupPad;
+  }
+
+  BasicBlock *getUnwindDest() const {
+    return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr;
+  }
+  void setUnwindDest(BasicBlock *NewDest) {
+    assert(hasUnwindDest());
+    assert(NewDest);
+    Op<-2>() = NewDest;
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::CleanupEndPad);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+
+private:
+  BasicBlock *getSuccessorV(unsigned Idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<CleanupEndPadInst>
+    : public VariadicOperandTraits<CleanupEndPadInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value)
+
+//===----------------------------------------------------------------------===//
+//                               CleanupReturnInst Class
+//===----------------------------------------------------------------------===//
+
+class CleanupReturnInst : public TerminatorInst {
+private:
+  CleanupReturnInst(const CleanupReturnInst &RI);
+
+  void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
+  CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+                    unsigned Values, Instruction *InsertBefore = nullptr);
+  CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
+                    unsigned Values, BasicBlock *InsertAtEnd);
+
+protected:
+  // Note: Instruction needs to be a friend here to call cloneImpl.
+  friend class Instruction;
+  CleanupReturnInst *cloneImpl() const;
+
+public:
+  static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
+                                   BasicBlock *UnwindBB = nullptr,
+                                   Instruction *InsertBefore = nullptr) {
+    assert(CleanupPad);
+    unsigned Values = 1;
+    if (UnwindBB)
+      ++Values;
+    return new (Values)
+        CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore);
+  }
+  static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
+                                   BasicBlock *UnwindBB,
+                                   BasicBlock *InsertAtEnd) {
+    assert(CleanupPad);
+    unsigned Values = 1;
+    if (UnwindBB)
+      ++Values;
+    return new (Values)
+        CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+  bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+  bool unwindsToCaller() const { return !hasUnwindDest(); }
+
+  /// Convenience accessor.
+  CleanupPadInst *getCleanupPad() const {
+    return cast<CleanupPadInst>(Op<-1>());
+  }
+  void setCleanupPad(CleanupPadInst *CleanupPad) {
+    assert(CleanupPad);
+    Op<-1>() = CleanupPad;
+  }
+
+  unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
+
+  BasicBlock *getUnwindDest() const {
+    return hasUnwindDest() ? cast<BasicBlock>(Op<-2>()) : nullptr;
+  }
+  void setUnwindDest(BasicBlock *NewDest) {
+    assert(NewDest);
+    assert(hasUnwindDest());
+    Op<-2>() = NewDest;
+  }
+
+  // Methods for support type inquiry through isa, cast, and dyn_cast:
+  static inline bool classof(const Instruction *I) {
+    return (I->getOpcode() == Instruction::CleanupRet);
+  }
+  static inline bool classof(const Value *V) {
+    return isa<Instruction>(V) && classof(cast<Instruction>(V));
+  }
+
+private:
+  BasicBlock *getSuccessorV(unsigned Idx) const override;
+  unsigned getNumSuccessorsV() const override;
+  void setSuccessorV(unsigned Idx, BasicBlock *B) override;
+
+  // Shadow Instruction::setInstructionSubclassData with a private forwarding
+  // method so that subclasses cannot accidentally use it.
+  void setInstructionSubclassData(unsigned short D) {
+    Instruction::setInstructionSubclassData(D);
+  }
+};
+
+template <>
+struct OperandTraits<CleanupReturnInst>
+    : public VariadicOperandTraits<CleanupReturnInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
+
 //===----------------------------------------------------------------------===//
 //                           UnreachableInst Class
 //===----------------------------------------------------------------------===//