AVX512: Implemented encoding and intrinsics for
[oota-llvm.git] / include / llvm / IR / Instructions.h
index 36cd26e4e110e74d884cc16cb304984157d19e22..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.
@@ -1622,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 {
@@ -2740,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.
@@ -3056,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:
@@ -3156,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:
@@ -3268,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() {
@@ -3282,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.
@@ -3569,124 +3599,19 @@ struct OperandTraits<ResumeInst> :
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
 
-//===----------------------------------------------------------------------===//
-//                               CleanupReturnInst 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));
-  }
-
-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> {};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
-
 //===----------------------------------------------------------------------===//
 //                               CatchEndPadInst Class
 //===----------------------------------------------------------------------===//
 
 class CatchEndPadInst : public TerminatorInst {
+private:
   CatchEndPadInst(const CatchEndPadInst &RI);
 
-private:
   void init(BasicBlock *UnwindBB);
   CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
-                    Instruction *InsertBefore = nullptr);
+                  Instruction *InsertBefore = nullptr);
   CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
-                    BasicBlock *InsertAtEnd);
+                  BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
@@ -3694,14 +3619,13 @@ protected:
   CatchEndPadInst *cloneImpl() const;
 
 public:
-  static CatchEndPadInst *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) CatchEndPadInst(C, UnwindBB, Values, InsertBefore);
   }
   static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
-                                   BasicBlock *InsertAtEnd) {
+                                 BasicBlock *InsertAtEnd) {
     unsigned Values = UnwindBB ? 1 : 0;
     return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd);
   }
@@ -3736,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) {
@@ -3761,14 +3684,12 @@ private:
 
   CatchPadInst(const CatchPadInst &CPI);
 
-  explicit CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
-                          BasicBlock *IfException, ArrayRef<Value *> Args,
-                          unsigned Values, const Twine &NameStr,
-                          Instruction *InsertBefore);
-  explicit CatchPadInst(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.
@@ -3776,20 +3697,19 @@ protected:
   CatchPadInst *cloneImpl() const;
 
 public:
-  static CatchPadInst *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) CatchPadInst(RetTy, IfNormal, IfException, Args,
-                                       Values, NameStr, InsertBefore);
+    return new (Values) CatchPadInst(IfNormal, IfException, Args, Values,
+                                     NameStr, InsertBefore);
   }
-  static CatchPadInst *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) CatchPadInst(RetTy, IfNormal, IfException, Args,
-                                       Values, NameStr, InsertAtEnd);
+    return new (Values)
+        CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
@@ -3821,8 +3741,8 @@ public:
   // 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 catchpad!");
@@ -3831,7 +3751,7 @@ public:
 
   void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
     assert(idx < 2 && "Successor # out of range for catchpad!");
-    *(&Op<-2>() + idx) = reinterpret_cast<Value *>(NewSucc);
+    *(&Op<-2>() + idx) = NewSucc;
   }
 
   unsigned getNumSuccessors() const { return 2; }
@@ -3862,16 +3782,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value)
 
 class TerminatePadInst : public TerminatorInst {
 private:
-  void init(BasicBlock *BB, ArrayRef<Value *> Args, const Twine &NameStr);
+  void init(BasicBlock *BB, ArrayRef<Value *> Args);
 
   TerminatePadInst(const TerminatePadInst &TPI);
 
   explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
-                              ArrayRef<Value *> Args, unsigned Values,
-                              const Twine &NameStr, Instruction *InsertBefore);
+                            ArrayRef<Value *> Args, unsigned Values,
+                            Instruction *InsertBefore);
   explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB,
-                              ArrayRef<Value *> Args, unsigned Values,
-                              const Twine &NameStr, BasicBlock *InsertAtEnd);
+                            ArrayRef<Value *> Args, unsigned Values,
+                            BasicBlock *InsertAtEnd);
 
 protected:
   // Note: Instruction needs to be a friend here to call cloneImpl.
@@ -3880,24 +3800,20 @@ protected:
 
 public:
   static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
-                                    ArrayRef<Value *> Args = {},
-                                    const Twine &NameStr = "",
-                                    Instruction *InsertBefore = nullptr) {
+                                  ArrayRef<Value *> Args = None,
+                                  Instruction *InsertBefore = nullptr) {
     unsigned Values = unsigned(Args.size());
     if (BB)
       ++Values;
-    return new (Values)
-        TerminatePadInst(C, BB, Args, Values, NameStr, InsertBefore);
+    return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore);
   }
   static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB,
-                                    ArrayRef<Value *> Args,
-                                    const Twine &NameStr,
-                                    BasicBlock *InsertAtEnd) {
+                                  ArrayRef<Value *> Args,
+                                  BasicBlock *InsertAtEnd) {
     unsigned Values = unsigned(Args.size());
     if (BB)
       ++Values;
-    return new (Values)
-        TerminatePadInst(C, BB, Args, Values, NameStr, InsertAtEnd);
+    return new (Values) TerminatePadInst(C, BB, Args, Values, InsertAtEnd);
   }
 
   /// Provide fast operand accessors
@@ -3954,7 +3870,7 @@ public:
   }
   void setUnwindDest(BasicBlock *B) {
     assert(B && hasUnwindDest());
-    Op<-1>() = reinterpret_cast<Value *>(B);
+    Op<-1>() = B;
   }
 
   unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
@@ -3995,10 +3911,10 @@ private:
 
   CleanupPadInst(const CleanupPadInst &CPI);
 
-  explicit CleanupPadInst(Type *RetTy, ArrayRef<Value *> Args,
-                            const Twine &NameStr, Instruction *InsertBefore);
-  explicit CleanupPadInst(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.
@@ -4006,17 +3922,14 @@ protected:
   CleanupPadInst *cloneImpl() const;
 
 public:
-  static CleanupPadInst *Create(Type *RetTy, ArrayRef<Value *> Args,
-                                  const Twine &NameStr = "",
-                                  Instruction *InsertBefore = nullptr) {
-    return new (Args.size())
-        CleanupPadInst(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 CleanupPadInst *Create(Type *RetTy, ArrayRef<Value *> Args,
-                                  const Twine &NameStr,
-                                  BasicBlock *InsertAtEnd) {
-    return new (Args.size())
-        CleanupPadInst(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
@@ -4044,10 +3957,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, 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.
@@ -4055,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:
@@ -4087,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
 //===----------------------------------------------------------------------===//