Index: lib/Transforms/Utils/BuildLibCalls.cpp =================================================================== --- lib/Transforms/Utils/BuildLibCalls.cpp +++ lib/Transforms/Utils/BuildLibCalls.cpp @@ -716,6 +716,11 @@ return B.CreateBitCast(V, B.getInt8PtrTy(AS), "cstr"); } +static Value *castToIntPtr(Value *V, IRBuilder<> &B, const DataLayout &DL) { + assert(V->getType()->isIntegerTy() && "expected integer type"); + return B.CreateIntCast(V, B.getIntPtrTy(DL), false, "len.cast"); +} + Value *llvm::emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc_strlen)) @@ -763,7 +768,9 @@ DL.getIntPtrType(Context)); inferLibFuncAttributes(*M->getFunction("strncmp"), *TLI); CallInst *CI = B.CreateCall( - StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "strncmp"); + StrNCmp, + {castToCStr(Ptr1, B), castToCStr(Ptr2, B), castToIntPtr(Len, B, DL)}, + "strncmp"); if (const Function *F = dyn_cast(StrNCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -793,12 +800,16 @@ return nullptr; Module *M = B.GetInsertBlock()->getModule(); + const DataLayout &DL = M->getDataLayout(); + LLVMContext &Context = M->getContext(); Type *I8Ptr = B.getInt8PtrTy(); Value *StrNCpy = M->getOrInsertFunction(Name, I8Ptr, I8Ptr, I8Ptr, - Len->getType()); + DL.getIntPtrType(Context)); inferLibFuncAttributes(*M->getFunction(Name), *TLI); CallInst *CI = B.CreateCall( - StrNCpy, {castToCStr(Dst, B), castToCStr(Src, B), Len}, "strncpy"); + StrNCpy, + {castToCStr(Dst, B), castToCStr(Src, B), castToIntPtr(Len, B, DL)}, + "strncpy"); if (const Function *F = dyn_cast(StrNCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; @@ -821,7 +832,8 @@ DL.getIntPtrType(Context)); Dst = castToCStr(Dst, B); Src = castToCStr(Src, B); - CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); + CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, castToIntPtr(Len, B, DL), + castToIntPtr(ObjSize, B, DL)}); if (const Function *F = dyn_cast(MemCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; @@ -838,7 +850,8 @@ B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context)); inferLibFuncAttributes(*M->getFunction("memchr"), *TLI); - CallInst *CI = B.CreateCall(MemChr, {castToCStr(Ptr, B), Val, Len}, "memchr"); + CallInst *CI = B.CreateCall( + MemChr, {castToCStr(Ptr, B), Val, castToIntPtr(Len, B, DL)}, "memchr"); if (const Function *F = dyn_cast(MemChr->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); @@ -857,8 +870,11 @@ B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)); inferLibFuncAttributes(*M->getFunction("memcmp"), *TLI); + CallInst *CI = B.CreateCall( - MemCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, "memcmp"); + MemCmp, + {castToCStr(Ptr1, B), castToCStr(Ptr2, B), castToIntPtr(Len, B, DL)}, + "memcmp"); if (const Function *F = dyn_cast(MemCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); Index: test/Transforms/InstCombine/strncmp-wrong-datalayout.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/strncmp-wrong-datalayout.ll @@ -0,0 +1,21 @@ +; Test that the strncpy simplification doesn't crash if datalayout specifies +; 64 bit pointers while length is a 32 bit argument +; +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-p:64:64:64" + +declare i32 @strncmp(i8*, i8*, i32) + +define i32 @test6(i8* %str1, i8* %str2) { +; CHECK-LABEL: @test6( +; CHECK: [[LOAD1:%[a-z]+]] = load i8, i8* %str1, align 1 +; CHECK: [[ZEXT1:%[a-z]+]] = zext i8 [[LOAD1]] to i32 +; CHECK: [[LOAD2:%[a-z]+]] = load i8, i8* %str2, align 1 +; CHECK: [[ZEXT2:%[a-z]+]] = zext i8 [[LOAD2]] to i32 +; CHECK: [[RET:%[a-z]+]] = sub nsw i32 [[ZEXT1]], [[ZEXT2]] +; CHECK: ret i32 [[RET]] + + %temp1 = call i32 @strncmp(i8* %str1, i8* %str2, i32 1) + ret i32 %temp1 +}