Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llvm/include/llvm/Analysis/ValueTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ struct ConstantDataArraySlice {
/// with an appropriate offset.
LLVM_ABI bool getConstantDataArrayInfo(const Value *V,
ConstantDataArraySlice &Slice,
unsigned ElementSize,
unsigned ElementBitWidth,
uint64_t Offset = 0);

/// This function computes the length of a null-terminated C string pointed to
Expand All @@ -403,7 +403,7 @@ LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str,

/// If we can compute the length of the string pointed to by the specified
/// pointer, return 'len+1'. If we can't, return 0.
LLVM_ABI uint64_t GetStringLength(const Value *V, unsigned CharSize = 8);
LLVM_ABI uint64_t getStringLength(const Value *V, unsigned CharWidth);

/// This function returns call pointer argument that is considered the same by
/// aliasing rules. You CAN'T use it to replace one value with another. If
Expand Down
4 changes: 2 additions & 2 deletions llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ class LibCallSimplifier {
bool hasFloatVersion(const Module *M, StringRef FuncName);

/// Shared code to optimize strlen+wcslen and strnlen+wcsnlen.
Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B, unsigned CharSize,
Value *Bound = nullptr);
Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B,
unsigned CharWidth, Value *Bound = nullptr);
};
} // End llvm namespace

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Analysis/MemoryBuiltins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ llvm::getAllocSize(const CallBase *CB, const TargetLibraryInfo *TLI,

// Handle strdup-like functions separately.
if (FnData->AllocTy == StrDupLike) {
APInt Size(IntTyBits, GetStringLength(Mapper(CB->getArgOperand(0))));
APInt Size(IntTyBits, getStringLength(Mapper(CB->getArgOperand(0)),
DL.getByteWidth()));
if (!Size)
return std::nullopt;

Expand Down
40 changes: 21 additions & 19 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6528,17 +6528,14 @@ llvm::FindInsertedValue(Value *V, ArrayRef<unsigned> idx_range,
}

// If V refers to an initialized global constant, set Slice either to
// 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".
// its initializer if the bit width of its elements equals ElementBitWidth,
// or, for ElementBitWidth == CHAR_BIT, to its representation as an array
// of unsigned char. Return true on success.
// Offset is in the unit "nr of ElementBitWidth sized elements".
bool llvm::getConstantDataArrayInfo(const Value *V,
ConstantDataArraySlice &Slice,
unsigned ElementSize, uint64_t Offset) {
unsigned ElementBitWidth, uint64_t Offset) {
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
Expand All @@ -6550,6 +6547,11 @@ bool llvm::getConstantDataArrayInfo(const Value *V,
return false;

const DataLayout &DL = GV->getDataLayout();
unsigned ByteWidth = DL.getByteWidth();
assert((ElementBitWidth % ByteWidth) == 0 &&
"ElementBitWidth is expected to be a multiple of the byte width");
unsigned ElementSizeInBytes = ElementBitWidth / ByteWidth;

APInt Off(DL.getIndexTypeSizeInBits(V->getType()), 0);

if (GV != V->stripAndAccumulateConstantOffsets(DL, Off,
Expand Down Expand Up @@ -6589,7 +6591,7 @@ bool llvm::getConstantDataArrayInfo(const Value *V,
auto *Init = const_cast<Constant *>(GV->getInitializer());
if (auto *ArrayInit = dyn_cast<ConstantDataArray>(Init)) {
Type *InitElTy = ArrayInit->getElementType();
if (InitElTy->isIntegerTy(ElementSize)) {
if (InitElTy->isIntegerTy(ElementBitWidth)) {
// If Init is an initializer for an array of the expected type
// and size, use it as is.
Array = ArrayInit;
Expand All @@ -6598,7 +6600,7 @@ bool llvm::getConstantDataArrayInfo(const Value *V,
}

if (!Array) {
if (ElementSize != 8)
if (ElementBitWidth != CHAR_BIT)
// TODO: Handle conversions to larger integral types.
return false;

Expand Down Expand Up @@ -6676,9 +6678,9 @@ bool llvm::getConstantStringInfo(const Value *V, StringRef &Str,

/// If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
static uint64_t GetStringLengthH(const Value *V,
SmallPtrSetImpl<const PHINode*> &PHIs,
unsigned CharSize) {
static uint64_t getStringLength(const Value *V,
SmallPtrSetImpl<const PHINode *> &PHIs,
unsigned CharWidth) {
// Look through noop bitcast instructions.
V = V->stripPointerCasts();

Expand All @@ -6691,7 +6693,7 @@ static uint64_t GetStringLengthH(const Value *V,
// If it was new, see if all the input strings are the same length.
uint64_t LenSoFar = ~0ULL;
for (Value *IncValue : PN->incoming_values()) {
uint64_t Len = GetStringLengthH(IncValue, PHIs, CharSize);
uint64_t Len = getStringLength(IncValue, PHIs, CharWidth);
if (Len == 0) return 0; // Unknown length -> unknown.

if (Len == ~0ULL) continue;
Expand All @@ -6707,9 +6709,9 @@ static uint64_t GetStringLengthH(const Value *V,

// strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
if (const SelectInst *SI = dyn_cast<SelectInst>(V)) {
uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs, CharSize);
uint64_t Len1 = getStringLength(SI->getTrueValue(), PHIs, CharWidth);
if (Len1 == 0) return 0;
uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs, CharSize);
uint64_t Len2 = getStringLength(SI->getFalseValue(), PHIs, CharWidth);
if (Len2 == 0) return 0;
if (Len1 == ~0ULL) return Len2;
if (Len2 == ~0ULL) return Len1;
Expand All @@ -6719,7 +6721,7 @@ static uint64_t GetStringLengthH(const Value *V,

// Otherwise, see if we can read the string.
ConstantDataArraySlice Slice;
if (!getConstantDataArrayInfo(V, Slice, CharSize))
if (!getConstantDataArrayInfo(V, Slice, CharWidth))
return 0;

if (Slice.Array == nullptr)
Expand All @@ -6741,12 +6743,12 @@ static uint64_t GetStringLengthH(const Value *V,

/// If we can compute the length of the string pointed to by
/// the specified pointer, return 'len+1'. If we can't, return 0.
uint64_t llvm::GetStringLength(const Value *V, unsigned CharSize) {
uint64_t llvm::getStringLength(const Value *V, unsigned CharWidth) {
if (!V->getType()->isPointerTy())
return 0;

SmallPtrSet<const PHINode*, 32> PHIs;
uint64_t Len = GetStringLengthH(V, PHIs, CharSize);
uint64_t Len = ::getStringLength(V, PHIs, CharWidth);
// If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
// an empty string as a length.
return Len == ~0ULL ? 1 : Len;
Expand Down
12 changes: 7 additions & 5 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
uint64_t Size = MemOpLength->getLimitedValue();
assert(Size && "0-sized memory transferring should be removed already.");

if (Size > 8 || (Size&(Size-1)))
uint64_t MemOpWidth = Size * DL.getByteWidth();
if (MemOpWidth > 64 || (Size & (Size - 1)))
return nullptr; // If not 1/2/4/8 bytes, exit.

// If it is an atomic and alignment is less than the size then we will
Expand All @@ -170,7 +171,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
return nullptr;

// Use an integer load+store unless we can find something better.
IntegerType* IntType = IntegerType::get(MI->getContext(), Size<<3);
IntegerType *IntType = IntegerType::get(MI->getContext(), MemOpWidth);

// If the memcpy has metadata describing the members, see if we can get the
// TBAA, scope and noalias tags describing our copy.
Expand Down Expand Up @@ -246,7 +247,7 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
// Extract the length and alignment and fill if they are constant.
ConstantInt *LenC = dyn_cast<ConstantInt>(MI->getLength());
ConstantInt *FillC = dyn_cast<ConstantInt>(MI->getValue());
if (!LenC || !FillC || !FillC->getType()->isIntegerTy(8))
if (!LenC || !FillC || !FillC->getType()->isIntegerTy(DL.getByteWidth()))
return nullptr;
const uint64_t Len = LenC->getLimitedValue();
assert(Len && "0-sized memory setting should be removed already.");
Expand All @@ -260,12 +261,13 @@ Instruction *InstCombinerImpl::SimplifyAnyMemSet(AnyMemSetInst *MI) {
return nullptr;

// memset(s,c,n) -> store s, c (for n=1,2,4,8)
if (Len <= 8 && isPowerOf2_32((uint32_t)Len)) {
uint64_t MemOpWidth = Len * DL.getByteWidth();
if (MemOpWidth <= 64 && isPowerOf2_32((uint32_t)Len)) {
Value *Dest = MI->getDest();

// Extract the fill value and store.
Constant *FillVal = ConstantInt::get(
MI->getContext(), APInt::getSplat(Len * 8, FillC->getValue()));
MI->getContext(), APInt::getSplat(MemOpWidth, FillC->getValue()));
StoreInst *S = Builder.CreateStore(FillVal, Dest, MI->isVolatile());
S->copyMetadata(*MI, LLVMContext::MD_DIAssignID);
for (DbgVariableRecord *DbgAssign : at::getDVRAssignmentMarkers(S)) {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3252,8 +3252,9 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
if (MadeChange)
return &GEP;

// Canonicalize constant GEPs to i8 type.
if (!GEPEltType->isIntegerTy(8) && GEP.hasAllConstantIndices()) {
// Canonicalize constant GEPs to byte type.
if (!GEPEltType->isIntegerTy(DL.getByteWidth()) &&
GEP.hasAllConstantIndices()) {
APInt Offset(DL.getIndexTypeSizeInBits(GEPType), 0);
if (GEP.accumulateConstantOffset(DL, Offset))
return replaceInstUsesWith(
Expand Down
Loading
Loading