[llvm] r298262 - Templatize parts of VNCoercion, and add constant-only versions of the functions to be used in NewGVN.

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 20 11:08:40 PDT 2017


I missed a test update in the commit.
The test changes the names of some of the instructions (no code is affected)


On Mon, Mar 20, 2017 at 10:28 AM, Juergen Ributzka <juergen at ributzka.de>
wrote:

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


More information about the llvm-commits mailing list