diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -637,11 +637,20 @@ LibFunc F, const DataLayout *DL) const { LLVMContext &Ctx = FTy.getContext(); - Type *PCharTy = Type::getInt8PtrTy(Ctx); Type *SizeTTy = DL ? DL->getIntPtrType(Ctx, /*AddressSpace=*/0) : nullptr; auto IsSizeTTy = [SizeTTy](Type *Ty) { return SizeTTy ? Ty == SizeTTy : Ty->isIntegerTy(); }; + auto IsCharPtrTy = [DL](Type *Ty) { + if (auto PTy = dyn_cast(Ty)) { + // XXX: should we restrict this to i8* in the default globals AS? + if (DL && + PTy->getPointerAddressSpace() != DL->getDefaultGlobalsAddressSpace()) + return false; + return PTy->getPointerElementType()->isIntegerTy(8); + } + return false; + }; unsigned NumParams = FTy.getNumParams(); switch (F) { @@ -719,7 +728,7 @@ case LibFunc_stpcpy: return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy); + IsCharPtrTy(FTy.getParamType(0))); case LibFunc_strlcat_chk: case LibFunc_strlcpy_chk: @@ -744,8 +753,7 @@ case LibFunc_stpncpy: return (NumParams == 3 && FTy.getReturnType() == FTy.getParamType(0) && FTy.getParamType(0) == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy && - IsSizeTTy(FTy.getParamType(2))); + IsCharPtrTy(FTy.getParamType(0)) && IsSizeTTy(FTy.getParamType(2))); case LibFunc_strxfrm: return (NumParams == 3 && FTy.getParamType(0)->isPointerTy() && @@ -885,7 +893,7 @@ return (FTy.getReturnType()->isPointerTy()); case LibFunc_realloc: case LibFunc_reallocf: - return (NumParams == 2 && FTy.getReturnType() == PCharTy && + return (NumParams == 2 && IsCharPtrTy(FTy.getReturnType()) && FTy.getParamType(0) == FTy.getReturnType() && IsSizeTTy(FTy.getParamType(1))); case LibFunc_read: @@ -1014,7 +1022,7 @@ case LibFunc_getchar_unlocked: return (NumParams == 0 && FTy.getReturnType()->isIntegerTy()); case LibFunc_gets: - return (NumParams == 1 && FTy.getParamType(0) == PCharTy); + return (NumParams == 1 && IsCharPtrTy(FTy.getParamType(0))); case LibFunc_getitimer: return (NumParams == 2 && FTy.getParamType(1)->isPointerTy()); case LibFunc_ungetc: @@ -1470,13 +1478,12 @@ case LibFunc_strnlen: return (NumParams == 2 && FTy.getReturnType() == FTy.getParamType(1) && - FTy.getParamType(0) == PCharTy && - FTy.getParamType(1) == SizeTTy); + IsCharPtrTy(FTy.getParamType(0)) && IsSizeTTy(FTy.getParamType(1))); case LibFunc_posix_memalign: return (NumParams == 3 && FTy.getReturnType()->isIntegerTy(32) && FTy.getParamType(0)->isPointerTy() && - FTy.getParamType(1) == SizeTTy && FTy.getParamType(2) == SizeTTy); + IsSizeTTy(FTy.getParamType(1)) && IsSizeTTy(FTy.getParamType(2))); case LibFunc_wcslen: return (NumParams == 1 && FTy.getParamType(0)->isPointerTy() && diff --git a/llvm/test/Transforms/InstCombine/strcpy-nonzero-as.ll b/llvm/test/Transforms/InstCombine/strcpy-nonzero-as.ll --- a/llvm/test/Transforms/InstCombine/strcpy-nonzero-as.ll +++ b/llvm/test/Transforms/InstCombine/strcpy-nonzero-as.ll @@ -23,7 +23,7 @@ ; CHECK-AS200-LABEL: define {{[^@]+}}@test_strcpy_to_memcpy ; CHECK-AS200-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0:#.*]] { ; CHECK-AS200-NEXT: entry: -; CHECK-AS200-NEXT: [[CALL:%.*]] = call addrspace(200) i8 addrspace(200)* @strcpy(i8 addrspace(200)* [[DST]], i8 addrspace(200)* getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0)) +; CHECK-AS200-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i64(i8 addrspace(200)* align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i64 17, i1 false) ; CHECK-AS200-NEXT: ret void ; entry: @@ -41,7 +41,7 @@ ; CHECK-AS200-LABEL: define {{[^@]+}}@test_stpcpy_to_memcpy ; CHECK-AS200-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0]] { ; CHECK-AS200-NEXT: entry: -; CHECK-AS200-NEXT: [[CALL:%.*]] = call addrspace(200) i8 addrspace(200)* @stpcpy(i8 addrspace(200)* [[DST]], i8 addrspace(200)* getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0)) +; CHECK-AS200-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i128(i8 addrspace(200)* align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i128 17, i1 false) ; CHECK-AS200-NEXT: ret void ; entry: @@ -59,7 +59,7 @@ ; CHECK-AS200-LABEL: define {{[^@]+}}@test_strncpy_to_memcpy ; CHECK-AS200-SAME: (i8 addrspace(200)* [[DST:%.*]]) addrspace(200) [[ATTR0]] { ; CHECK-AS200-NEXT: entry: -; CHECK-AS200-NEXT: [[CALL:%.*]] = call addrspace(200) i8 addrspace(200)* @strncpy(i8 addrspace(200)* [[DST]], i8 addrspace(200)* getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i64 17) +; CHECK-AS200-NEXT: call addrspace(200) void @llvm.memcpy.p200i8.p200i8.i128(i8 addrspace(200)* align 1 dereferenceable(17) [[DST]], i8 addrspace(200)* align 1 dereferenceable(17) getelementptr inbounds ([17 x i8], [17 x i8] addrspace(200)* @str, i64 0, i64 0), i128 17, i1 false) ; CHECK-AS200-NEXT: ret void ; entry: