diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4232,10 +4232,14 @@ // its initializer if the size of its elements equals ElementSize, or, // for ElementSize == 8, to its representation as an array of unsiged // char. Return true on success. +// Offset is in the unit "nr of ElementSize sized elements". bool llvm::getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, unsigned ElementSize, uint64_t Offset) { - assert(V); + assert(V && "V should not be null."); + assert((ElementSize % 8) == 0 && + "ElementSize expected to be a multiple of the size of a byte."); + unsigned ElementSizeInBytes = ElementSize / 8; // Drill down into the pointer expression V, ignoring any intervening // casts, and determine the identity of the object it references along @@ -4259,7 +4263,11 @@ // Fail if the constant offset is excessive. return false; - Offset += StartIdx; + // Off/StartIdx is in the unit of bytes. So we need to convert to number of + // elements. + assert((StartIdx % ElementSizeInBytes) == 0 && + "Constant offset not a multiple of the ElementSize."); + Offset += StartIdx / ElementSizeInBytes; ConstantDataArray *Array = nullptr; ArrayType *ArrayTy = nullptr; @@ -4267,7 +4275,7 @@ if (GV->getInitializer()->isNullValue()) { Type *GVTy = GV->getValueType(); uint64_t SizeInBytes = DL.getTypeStoreSize(GVTy).getFixedSize(); - uint64_t Length = SizeInBytes / (ElementSize / 8); + uint64_t Length = SizeInBytes / ElementSizeInBytes; Slice.Array = nullptr; Slice.Offset = 0; diff --git a/llvm/test/Transforms/InstCombine/wcslen-7.ll b/llvm/test/Transforms/InstCombine/wcslen-7.ll --- a/llvm/test/Transforms/InstCombine/wcslen-7.ll +++ b/llvm/test/Transforms/InstCombine/wcslen-7.ll @@ -11,10 +11,9 @@ ; Fold wcslen(ws + 2) => 7. -; FIXME: This fold is faulty, result should be 7 not 1. define dso_local i64 @fold_wcslen_1() { ; CHECK-LABEL: @fold_wcslen_1( -; CHECK-NEXT: ret i64 1 +; CHECK-NEXT: ret i64 7 ; %ps3_pi = getelementptr inbounds [10 x i32], ptr @ws, i64 0, i64 2 %len = tail call i64 @wcslen(ptr %ps3_pi)