<div dir="ltr">I missed a test update in the commit.<div>The test changes the names of some of the instructions (no code is affected)</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 20, 2017 at 10:28 AM, Juergen Ributzka <span dir="ltr"><<a href="mailto:juergen@ributzka.de" target="_blank">juergen@ributzka.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Daniel,<div><br></div><div>this broke a test on green dragon:</div><div><a href="http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental_check/34915/" target="_blank">http://green.lab.llvm.org/<wbr>green/job/clang-stage1-cmake-<wbr>RA-incremental_check/34915/</a></div><div><br></div><div>Could you please take a look?</div><div><br></div><div>Thanks</div><div><br></div><div>Cheers,</div><div>Juergen</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 20, 2017 at 9:08 AM, Daniel Berlin via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dannyb<br>
Date: Mon Mar 20 11:08:29 2017<br>
New Revision: 298262<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=298262&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=298262&view=rev</a><br>
Log:<br>
Templatize parts of VNCoercion, and add constant-only versions of the functions to be used in NewGVN.<br>
NFCI.<br>
<br>
Summary:<br>
This is ground work for the changes to enable coercion in NewGVN.<br>
GVN doesn't care if they end up constant because it eliminates as it goes.<br>
NewGVN cares.<br>
<br>
IRBuilder and ConstantFolder deliberately present the same interface,<br>
so we use this to our advantage to templatize our functions to make<br>
them either constant only or not.<br>
<br>
Reviewers: davide<br>
<br>
Subscribers: llvm-commits, Prazek<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D30928" rel="noreferrer" target="_blank">https://reviews.llvm.org/D3092<wbr>8</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/Transf<wbr>orms/Utils/VNCoercion.h<br>
    llvm/trunk/lib/Transforms/Scal<wbr>ar/GVN.cpp<br>
    llvm/trunk/lib/Transforms/Util<wbr>s/VNCoercion.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Transf<wbr>orms/Utils/VNCoercion.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/VNCoercion.h?rev=298262&r1=298261&r2=298262&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Transforms/Utils/VNCoercion.h?<wbr>rev=298262&r1=298261&r2=<wbr>298262&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/Transf<wbr>orms/Utils/VNCoercion.h (original)<br>
+++ llvm/trunk/include/llvm/Transf<wbr>orms/Utils/VNCoercion.h Mon Mar 20 11:08:29 2017<br>
@@ -76,13 +76,21 @@ int analyzeLoadFromClobberingMemIn<wbr>st(Typ<br>
 /// inserts instructions to do so at InsertPt, and returns the extracted value.<br>
 Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy,<br>
                             Instruction *InsertPt, const DataLayout &DL);<br>
+// This is the same as getStoreValueForLoad, except it performs no insertion<br>
+// It only allows constant inputs.<br>
+Constant *getConstantStoreValueForLoad(<wbr>Constant *SrcVal, unsigned Offset,<br>
+                                       Type *LoadTy, const DataLayout &DL);<br>
<br>
 /// If analyzeLoadFromClobberingLoad returned an offset, this function can be<br>
 /// used to actually perform the extraction of the bits from the load, including<br>
 /// any necessary load widening.  It inserts instructions to do so at InsertPt,<br>
 /// and returns the extracted value.<br>
 Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy,<br>
-                           Instruction *InsertPt);<br>
+                           Instruction *InsertPt, const DataLayout &DL);<br>
+// This is the same as getLoadValueForLoad, except it is given the load value as<br>
+// a constant. It returns nullptr if it would require widening the load.<br>
+Constant *getConstantLoadValueForLoad(C<wbr>onstant *SrcVal, unsigned Offset,<br>
+                                      Type *LoadTy, const DataLayout &DL);<br>
<br>
 /// If analyzeLoadFromClobberingMemIn<wbr>st returned an offset, this function can be<br>
 /// used to actually perform the extraction of the bits from the memory<br>
@@ -91,6 +99,10 @@ Value *getLoadValueForLoad(LoadInst *Src<br>
 Value *getMemInstValueForLoad(MemInt<wbr>rinsic *SrcInst, unsigned Offset,<br>
                               Type *LoadTy, Instruction *InsertPt,<br>
                               const DataLayout &DL);<br>
+// This is the same as getStoreValueForLoad, except it performs no insertion.<br>
+// It returns nullptr if it cannot produce a constant.<br>
+Constant *getConstantMemInstValueForLoa<wbr>d(MemIntrinsic *SrcInst, unsigned Offset,<br>
+                                         Type *LoadTy, const DataLayout &DL);<br>
 }<br>
 }<br>
 #endif<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scal<wbr>ar/GVN.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=298262&r1=298261&r2=298262&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Transform<wbr>s/Scalar/GVN.cpp?rev=298262&<wbr>r1=298261&r2=298262&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/Scal<wbr>ar/GVN.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scal<wbr>ar/GVN.cpp Mon Mar 20 11:08:29 2017<br>
@@ -750,7 +750,7 @@ Value *AvailableValue::MaterializeAd<wbr>just<br>
     if (Load->getType() == LoadTy && Offset == 0) {<br>
       Res = Load;<br>
     } else {<br>
-      Res = getLoadValueForLoad(Load, Offset, LoadTy, InsertPt);<br>
+      Res = getLoadValueForLoad(Load, Offset, LoadTy, InsertPt, DL);<br>
       // We would like to use gvn.markInstructionForDeletion here, but we can't<br>
       // because the load is already memoized into the leader map table that GVN<br>
       // tracks.  It is potentially possible to remove the load from the table,<br>
<br>
Modified: llvm/trunk/lib/Transforms/Util<wbr>s/VNCoercion.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/VNCoercion.cpp?rev=298262&r1=298261&r2=298262&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Transform<wbr>s/Utils/VNCoercion.cpp?rev=<wbr>298262&r1=298261&r2=298262&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Transforms/Util<wbr>s/VNCoercion.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Util<wbr>s/VNCoercion.cpp Mon Mar 20 11:08:29 2017<br>
@@ -27,17 +27,12 @@ bool canCoerceMustAliasedValueToLoa<wbr>d(Val<br>
   return true;<br>
 }<br>
<br>
-/// If we saw a store of a value to memory, and<br>
-/// then a load from a must-aliased pointer of a different type, try to coerce<br>
-/// the stored value.  LoadedTy is the type of the load we want to replace.<br>
-/// IRB is IRBuilder used to insert new instructions.<br>
-///<br>
-/// If we can't do it, return null.<br>
-Value *coerceAvailableValueToLoadTyp<wbr>e(Value *StoredVal, Type *LoadedTy,<br>
-                                      IRBuilder<> &IRB, const DataLayout &DL) {<br>
+template <class T, class HelperClass><br>
+static T *coerceAvailableValueToLoadTyp<wbr>eHelper(T *StoredVal, Type *LoadedTy,<br>
+                                               HelperClass &Helper,<br>
+                                               const DataLayout &DL) {<br>
   assert(canCoerceMustAliasedVa<wbr>lueToLoad(StoredVal, LoadedTy, DL) &&<br>
          "precondition violation - materialization can't fail");<br>
-<br>
   if (auto *C = dyn_cast<Constant>(StoredVal))<br>
     if (auto *FoldedStoredVal = ConstantFoldConstant(C, DL))<br>
       StoredVal = FoldedStoredVal;<br>
@@ -53,12 +48,12 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
     // Pointer to Pointer -> use bitcast.<br>
     if (StoredValTy->getScalarType()-<wbr>>isPointerTy() &&<br>
         LoadedTy->getScalarType()->is<wbr>PointerTy()) {<br>
-      StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy);<br>
+      StoredVal = Helper.CreateBitCast(StoredVal<wbr>, LoadedTy);<br>
     } else {<br>
       // Convert source pointers to integers, which can be bitcast.<br>
       if (StoredValTy->getScalarType()-<wbr>>isPointerTy()) {<br>
         StoredValTy = DL.getIntPtrType(StoredValTy);<br>
-        StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy);<br>
+        StoredVal = Helper.CreatePtrToInt(StoredVa<wbr>l, StoredValTy);<br>
       }<br>
<br>
       Type *TypeToCastTo = LoadedTy;<br>
@@ -66,11 +61,11 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
         TypeToCastTo = DL.getIntPtrType(TypeToCastTo)<wbr>;<br>
<br>
       if (StoredValTy != TypeToCastTo)<br>
-        StoredVal = IRB.CreateBitCast(StoredVal, TypeToCastTo);<br>
+        StoredVal = Helper.CreateBitCast(StoredVal<wbr>, TypeToCastTo);<br>
<br>
       // Cast to pointer if the load needs a pointer type.<br>
       if (LoadedTy->getScalarType()->is<wbr>PointerTy())<br>
-        StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy);<br>
+        StoredVal = Helper.CreateIntToPtr(StoredVa<wbr>l, LoadedTy);<br>
     }<br>
<br>
     if (auto *C = dyn_cast<ConstantExpr>(StoredV<wbr>al))<br>
@@ -79,7 +74,6 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
<br>
     return StoredVal;<br>
   }<br>
-<br>
   // If the loaded value is smaller than the available value, then we can<br>
   // extract out a piece from it.  If the available value is too small, then we<br>
   // can't do anything.<br>
@@ -89,13 +83,13 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
   // Convert source pointers to integers, which can be manipulated.<br>
   if (StoredValTy->getScalarType()-<wbr>>isPointerTy()) {<br>
     StoredValTy = DL.getIntPtrType(StoredValTy);<br>
-    StoredVal = IRB.CreatePtrToInt(StoredVal, StoredValTy);<br>
+    StoredVal = Helper.CreatePtrToInt(StoredVa<wbr>l, StoredValTy);<br>
   }<br>
<br>
   // Convert vectors and fp to integer, which can be manipulated.<br>
   if (!StoredValTy->isIntegerTy()) {<br>
     StoredValTy = IntegerType::get(StoredValTy-><wbr>getContext(), StoredValSize);<br>
-    StoredVal = IRB.CreateBitCast(StoredVal, StoredValTy);<br>
+    StoredVal = Helper.CreateBitCast(StoredVal<wbr>, StoredValTy);<br>
   }<br>
<br>
   // If this is a big-endian system, we need to shift the value down to the low<br>
@@ -103,20 +97,21 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
   if (DL.isBigEndian()) {<br>
     uint64_t ShiftAmt = DL.getTypeStoreSizeInBits(Stor<wbr>edValTy) -<br>
                         DL.getTypeStoreSizeInBits(Loa<wbr>dedTy);<br>
-    StoredVal = IRB.CreateLShr(StoredVal, ShiftAmt, "tmp");<br>
+    StoredVal = Helper.CreateLShr(<br>
+        StoredVal, ConstantInt::get(StoredVal->ge<wbr>tType(), ShiftAmt));<br>
   }<br>
<br>
   // Truncate the integer to the right size now.<br>
   Type *NewIntTy = IntegerType::get(StoredValTy-><wbr>getContext(), LoadedValSize);<br>
-  StoredVal = IRB.CreateTrunc(StoredVal, NewIntTy, "trunc");<br>
+  StoredVal = Helper.CreateTruncOrBitCast(St<wbr>oredVal, NewIntTy);<br>
<br>
   if (LoadedTy != NewIntTy) {<br>
     // If the result is a pointer, inttoptr.<br>
     if (LoadedTy->getScalarType()->is<wbr>PointerTy())<br>
-      StoredVal = IRB.CreateIntToPtr(StoredVal, LoadedTy, "inttoptr");<br>
+      StoredVal = Helper.CreateIntToPtr(StoredVa<wbr>l, LoadedTy);<br>
     else<br>
       // Otherwise, bitcast.<br>
-      StoredVal = IRB.CreateBitCast(StoredVal, LoadedTy, "bitcast");<br>
+      StoredVal = Helper.CreateBitCast(StoredVal<wbr>, LoadedTy);<br>
   }<br>
<br>
   if (auto *C = dyn_cast<Constant>(StoredVal))<br>
@@ -126,10 +121,21 @@ Value *coerceAvailableValueToLoadTyp<wbr>e(Va<br>
   return StoredVal;<br>
 }<br>
<br>
-/// This function is called when we have a<br>
-/// memdep query of a load that ends up being a clobbering memory write (store,<br>
-/// memset, memcpy, memmove).  This means that the write *may* provide bits used<br>
-/// by the load but we can't be sure because the pointers don't mustalias.<br>
+/// If we saw a store of a value to memory, and<br>
+/// then a load from a must-aliased pointer of a different type, try to coerce<br>
+/// the stored value.  LoadedTy is the type of the load we want to replace.<br>
+/// IRB is IRBuilder used to insert new instructions.<br>
+///<br>
+/// If we can't do it, return null.<br>
+Value *coerceAvailableValueToLoadTyp<wbr>e(Value *StoredVal, Type *LoadedTy,<br>
+                                      IRBuilder<> &IRB, const DataLayout &DL) {<br>
+  return coerceAvailableValueToLoadType<wbr>Helper(StoredVal, LoadedTy, IRB, DL);<br>
+}<br>
+<br>
+/// This function is called when we have a memdep query of a load that ends up<br>
+/// being a clobbering memory write (store, memset, memcpy, memmove).  This<br>
+/// means that the write *may* provide bits used by the load but we can't be<br>
+/// sure because the pointers don't must-alias.<br>
 ///<br>
 /// Check this case to see if there is anything more we can do before we give<br>
 /// up.  This returns -1 if we have to give up, or a byte number in the stored<br>
@@ -286,28 +292,20 @@ int analyzeLoadFromClobberingMemIn<wbr>st(Typ<br>
   return -1;<br>
 }<br>
<br>
-/// This function is called when we have a<br>
-/// memdep query of a load that ends up being a clobbering store.  This means<br>
-/// that the store provides bits used by the load but we the pointers don't<br>
-/// mustalias.  Check this case to see if there is anything more we can do<br>
-/// before we give up.<br>
-Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy,<br>
-                            Instruction *InsertPt, const DataLayout &DL) {<br>
+template <class T, class HelperClass><br>
+static T *getStoreValueForLoadHelper(T *SrcVal, unsigned Offset, Type *LoadTy,<br>
+                                     HelperClass &Helper,<br>
+                                     const DataLayout &DL) {<br>
   LLVMContext &Ctx = SrcVal->getType()->getContext(<wbr>);<br>
<br>
   uint64_t StoreSize = (DL.getTypeSizeInBits(SrcVal-><wbr>getType()) + 7) / 8;<br>
   uint64_t LoadSize = (DL.getTypeSizeInBits(LoadTy) + 7) / 8;<br>
-<br>
-  IRBuilder<> Builder(InsertPt);<br>
-<br>
   // Compute which bits of the stored value are being used by the load.  Convert<br>
   // to an integer type to start with.<br>
   if (SrcVal->getType()->getScalarT<wbr>ype()->isPointerTy())<br>
-    SrcVal =<br>
-        Builder.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getTy<wbr>pe()));<br>
+    SrcVal = Helper.CreatePtrToInt(SrcVal, DL.getIntPtrType(SrcVal->getTy<wbr>pe()));<br>
   if (!SrcVal->getType()->isInteger<wbr>Ty())<br>
-    SrcVal =<br>
-        Builder.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8));<br>
+    SrcVal = Helper.CreateBitCast(SrcVal, IntegerType::get(Ctx, StoreSize * 8));<br>
<br>
   // Shift the bits to the least significant depending on endianness.<br>
   unsigned ShiftAmt;<br>
@@ -315,25 +313,42 @@ Value *getStoreValueForLoad(Value *SrcVa<br>
     ShiftAmt = Offset * 8;<br>
   else<br>
     ShiftAmt = (StoreSize - LoadSize - Offset) * 8;<br>
-<br>
   if (ShiftAmt)<br>
-    SrcVal = Builder.CreateLShr(SrcVal, ShiftAmt);<br>
+    SrcVal = Helper.CreateLShr(SrcVal,<br>
+                               ConstantInt::get(SrcVal->getT<wbr>ype(), ShiftAmt));<br>
<br>
   if (LoadSize != StoreSize)<br>
-    SrcVal = Builder.CreateTrunc(SrcVal, IntegerType::get(Ctx, LoadSize * 8));<br>
+    SrcVal = Helper.CreateTruncOrBitCast(Sr<wbr>cVal,<br>
+                                         IntegerType::get(Ctx, LoadSize * 8));<br>
+  return SrcVal;<br>
+}<br>
<br>
-  return coerceAvailableValueToLoadType<wbr>(SrcVal, LoadTy, Builder, DL);<br>
+/// This function is called when we have a memdep query of a load that ends up<br>
+/// being a clobbering store.  This means that the store provides bits used by<br>
+/// the load but the pointers don't must-alias.  Check this case to see if<br>
+/// there is anything more we can do before we give up.<br>
+Value *getStoreValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy,<br>
+                            Instruction *InsertPt, const DataLayout &DL) {<br>
+<br>
+  IRBuilder<> Builder(InsertPt);<br>
+  SrcVal = getStoreValueForLoadHelper(Src<wbr>Val, Offset, LoadTy, Builder, DL);<br>
+  return coerceAvailableValueToLoadType<wbr>Helper(SrcVal, LoadTy, Builder, DL);<br>
 }<br>
<br>
-/// This function is called when we have a<br>
-/// memdep query of a load that ends up being a clobbering load.  This means<br>
-/// that the load *may* provide bits used by the load but we can't be sure<br>
-/// because the pointers don't mustalias.  Check this case to see if there is<br>
-/// anything more we can do before we give up.<br>
-Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy,<br>
-                           Instruction *InsertPt) {<br>
+Constant *getConstantStoreValueForLoad(<wbr>Constant *SrcVal, unsigned Offset,<br>
+                                       Type *LoadTy, const DataLayout &DL) {<br>
+  ConstantFolder F;<br>
+  SrcVal = getStoreValueForLoadHelper(Src<wbr>Val, Offset, LoadTy, F, DL);<br>
+  return coerceAvailableValueToLoadType<wbr>Helper(SrcVal, LoadTy, F, DL);<br>
+}<br>
<br>
-  const DataLayout &DL = SrcVal->getModule()->getDataLa<wbr>yout();<br>
+/// This function is called when we have a memdep query of a load that ends up<br>
+/// being a clobbering load.  This means that the load *may* provide bits used<br>
+/// by the load but we can't be sure because the pointers don't must-alias.<br>
+/// Check this case to see if there is anything more we can do before we give<br>
+/// up.<br>
+Value *getLoadValueForLoad(LoadInst *SrcVal, unsigned Offset, Type *LoadTy,<br>
+                           Instruction *InsertPt, const DataLayout &DL) {<br>
   // If Offset+LoadTy exceeds the size of SrcVal, then we must be wanting to<br>
   // widen SrcVal out to a larger load.<br>
   unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->ge<wbr>tType());<br>
@@ -348,7 +363,6 @@ Value *getLoadValueForLoad(LoadInst *Src<br>
       NewLoadSize = NextPowerOf2(NewLoadSize);<br>
<br>
     Value *PtrVal = SrcVal->getPointerOperand();<br>
-<br>
     // Insert the new load after the old load.  This ensures that subsequent<br>
     // memdep queries will find the new load.  We can't easily remove the old<br>
     // load completely because it is already in the value numbering table.<br>
@@ -379,44 +393,51 @@ Value *getLoadValueForLoad(LoadInst *Src<br>
   return getStoreValueForLoad(SrcVal, Offset, LoadTy, InsertPt, DL);<br>
 }<br>
<br>
-/// This function is called when we have a<br>
-/// memdep query of a load that ends up being a clobbering mem intrinsic.<br>
-Value *getMemInstValueForLoad(MemInt<wbr>rinsic *SrcInst, unsigned Offset,<br>
-                              Type *LoadTy, Instruction *InsertPt,<br>
-                              const DataLayout &DL) {<br>
+Constant *getConstantLoadValueForLoad(C<wbr>onstant *SrcVal, unsigned Offset,<br>
+                                      Type *LoadTy, const DataLayout &DL) {<br>
+  unsigned SrcValStoreSize = DL.getTypeStoreSize(SrcVal->ge<wbr>tType());<br>
+  unsigned LoadSize = DL.getTypeStoreSize(LoadTy);<br>
+  if (Offset + LoadSize > SrcValStoreSize)<br>
+    return nullptr;<br>
+  return getConstantStoreValueForLoad(S<wbr>rcVal, Offset, LoadTy, DL);<br>
+}<br>
+<br>
+template <class T, class HelperClass><br>
+T *getMemInstValueForLoadHelper(<wbr>MemIntrinsic *SrcInst, unsigned Offset,<br>
+                                Type *LoadTy, HelperClass &Helper,<br>
+                                const DataLayout &DL) {<br>
   LLVMContext &Ctx = LoadTy->getContext();<br>
   uint64_t LoadSize = DL.getTypeSizeInBits(LoadTy) / 8;<br>
<br>
-  IRBuilder<> Builder(InsertPt);<br>
-<br>
   // We know that this method is only called when the mem transfer fully<br>
   // provides the bits for the load.<br>
   if (MemSetInst *MSI = dyn_cast<MemSetInst>(SrcInst)) {<br>
     // memset(P, 'x', 1234) -> splat('x'), even if x is a variable, and<br>
     // independently of what the offset is.<br>
-    Value *Val = MSI->getValue();<br>
+    T *Val = cast<T>(MSI->getValue());<br>
     if (LoadSize != 1)<br>
-      Val = Builder.CreateZExt(Val, IntegerType::get(Ctx, LoadSize * 8));<br>
-<br>
-    Value *OneElt = Val;<br>
+      Val =<br>
+          Helper.CreateZExtOrBitCast(Val<wbr>, IntegerType::get(Ctx, LoadSize * 8));<br>
+    T *OneElt = Val;<br>
<br>
     // Splat the value out to the right number of bits.<br>
     for (unsigned NumBytesSet = 1; NumBytesSet != LoadSize;) {<br>
       // If we can double the number of bytes set, do it.<br>
       if (NumBytesSet * 2 <= LoadSize) {<br>
-        Value *ShVal = Builder.CreateShl(Val, NumBytesSet * 8);<br>
-        Val = Builder.CreateOr(Val, ShVal);<br>
+        T *ShVal = Helper.CreateShl(<br>
+            Val, ConstantInt::get(Val->getType(<wbr>), NumBytesSet * 8));<br>
+        Val = Helper.CreateOr(Val, ShVal);<br>
         NumBytesSet <<= 1;<br>
         continue;<br>
       }<br>
<br>
       // Otherwise insert one byte at a time.<br>
-      Value *ShVal = Builder.CreateShl(Val, 1 * 8);<br>
-      Val = Builder.CreateOr(OneElt, ShVal);<br>
+      T *ShVal = Helper.CreateShl(Val, ConstantInt::get(Val->getType(<wbr>), 1 * 8));<br>
+      Val = Helper.CreateOr(OneElt, ShVal);<br>
       ++NumBytesSet;<br>
     }<br>
<br>
-    return coerceAvailableValueToLoadType<wbr>(Val, LoadTy, Builder, DL);<br>
+    return coerceAvailableValueToLoadType<wbr>Helper(Val, LoadTy, Helper, DL);<br>
   }<br>
<br>
   // Otherwise, this is a memcpy/memmove from a constant global.<br>
@@ -435,5 +456,27 @@ Value *getMemInstValueForLoad(MemInt<wbr>rins<br>
   Src = ConstantExpr::getBitCast(Src, PointerType::get(LoadTy, AS));<br>
   return ConstantFoldLoadFromConstPtr(S<wbr>rc, LoadTy, DL);<br>
 }<br>
+<br>
+/// This function is called when we have a<br>
+/// memdep query of a load that ends up being a clobbering mem intrinsic.<br>
+Value *getMemInstValueForLoad(MemInt<wbr>rinsic *SrcInst, unsigned Offset,<br>
+                              Type *LoadTy, Instruction *InsertPt,<br>
+                              const DataLayout &DL) {<br>
+  IRBuilder<> Builder(InsertPt);<br>
+  return getMemInstValueForLoadHelper<V<wbr>alue, IRBuilder<>>(SrcInst, Offset,<br>
+                                                          LoadTy, Builder, DL);<br>
+}<br>
+<br>
+Constant *getConstantMemInstValueForLoa<wbr>d(MemIntrinsic *SrcInst, unsigned Offset,<br>
+                                         Type *LoadTy, const DataLayout &DL) {<br>
+  // The only case analyzeLoadFromClobberingMemIn<wbr>st cannot be converted to a<br>
+  // constant is when it's a memset of a non-constant.<br>
+  if (auto *MSI = dyn_cast<MemSetInst>(SrcInst))<br>
+    if (!isa<Constant>(MSI->getValue(<wbr>)))<br>
+      return nullptr;<br>
+  ConstantFolder F;<br>
+  return getMemInstValueForLoadHelper<C<wbr>onstant, ConstantFolder>(SrcInst, Offset,<br>
+                                                                LoadTy, F, DL);<br>
+}<br>
 } // namespace VNCoercion<br>
 } // namespace llvm<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>