Change memcpy/memset/memmove to have dest and source alignments.
[oota-llvm.git] / include / llvm / IR / IRBuilder.h
index a9e040b825c013cd6d83df512098547a4135190f..4936ccb417d1791ce39d180d2f22f25e0c3fe994 100644 (file)
@@ -362,34 +362,56 @@ public:
   /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
   /// specified, it will be added to the instruction. Likewise with alias.scope
   /// and noalias tags.
-  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size,
+                         unsigned DstAlign,
                          bool isVolatile = false, MDNode *TBAATag = nullptr,
                          MDNode *ScopeTag = nullptr,
                          MDNode *NoAliasTag = nullptr) {
-    return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile,
+    return CreateMemSet(Ptr, Val, getInt64(Size), DstAlign, isVolatile,
                         TBAATag, ScopeTag, NoAliasTag);
   }
 
-  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
+  CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned DstAlign,
                          bool isVolatile = false, MDNode *TBAATag = nullptr,
                          MDNode *ScopeTag = nullptr,
                          MDNode *NoAliasTag = nullptr);
 
-  /// \brief Create and insert a memcpy between the specified pointers.
+  /// Create and insert a memcpy between the specified pointers.
   ///
   /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
   /// specified, it will be added to the instruction. Likewise with alias.scope
   /// and noalias tags.
-  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+  ///
+  /// Note!  This is very temporary.  It is only intended to catch calls to
+  /// CreateMemCpy in out of tree code which would otherwise silently pass the
+  /// volatile flag to source alignment.
+  class IntegerAlignment {
+  private:
+    uint64_t Align;
+
+    IntegerAlignment() = delete;
+    IntegerAlignment(bool) = delete;
+  public:
+    IntegerAlignment(int Align) : Align(Align) { }
+    IntegerAlignment(long long Align) : Align(Align) { }
+    IntegerAlignment(unsigned Align) : Align(Align) { }
+    IntegerAlignment(uint64_t Align) : Align(Align) { }
+
+    operator unsigned() { return Align; }
+  };
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size,
+                         unsigned DstAlign, IntegerAlignment SrcAlign,
                          bool isVolatile = false, MDNode *TBAATag = nullptr,
                          MDNode *TBAAStructTag = nullptr,
                          MDNode *ScopeTag = nullptr,
                          MDNode *NoAliasTag = nullptr) {
-    return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag,
+    return CreateMemCpy(Dst, Src, getInt64(Size), DstAlign, SrcAlign,
+                        isVolatile, TBAATag,
                         TBAAStructTag, ScopeTag, NoAliasTag);
   }
 
-  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
+  CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size,
+                         unsigned DstAlign, IntegerAlignment SrcAlign,
                          bool isVolatile = false, MDNode *TBAATag = nullptr,
                          MDNode *TBAAStructTag = nullptr,
                          MDNode *ScopeTag = nullptr,
@@ -401,15 +423,18 @@ public:
   /// If the pointers aren't i8*, they will be converted.  If a TBAA tag is
   /// specified, it will be added to the instruction. Likewise with alias.scope
   /// and noalias tags.
-  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
+  CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size,
+                          unsigned DstAlign, IntegerAlignment SrcAlign,
                           bool isVolatile = false, MDNode *TBAATag = nullptr,
                           MDNode *ScopeTag = nullptr,
                           MDNode *NoAliasTag = nullptr) {
-    return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile,
+    return CreateMemMove(Dst, Src, getInt64(Size), DstAlign, SrcAlign,
+                         isVolatile,
                          TBAATag, ScopeTag, NoAliasTag);
   }
 
-  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
+  CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size,
+                          unsigned DstAlign, IntegerAlignment SrcAlign,
                           bool isVolatile = false, MDNode *TBAATag = nullptr,
                           MDNode *ScopeTag = nullptr,
                           MDNode *NoAliasTag = nullptr);