Index: include/llvm/Analysis/TargetLibraryInfo.h =================================================================== --- include/llvm/Analysis/TargetLibraryInfo.h +++ include/llvm/Analysis/TargetLibraryInfo.h @@ -193,13 +193,9 @@ ShouldSignExtI32Param = Val; } - /// Returns the size of the wchar_t type in bytes. + /// Returns the size of the wchar_t type in bytes or 0 if the size is unknown. + /// This queries the 'wchar_size' metadata. unsigned getWCharSize(const Module &M) const; - - /// Returns size of the default wchar_t type on target \p T. This is mostly - /// intended to verify that the size in the frontend matches LLVM. All other - /// queries should use getWCharSize() instead. - static unsigned getTargetWCharSize(const Triple &T); }; /// Provides information about what library functions are available for Index: lib/Analysis/TargetLibraryInfo.cpp =================================================================== --- lib/Analysis/TargetLibraryInfo.cpp +++ lib/Analysis/TargetLibraryInfo.cpp @@ -1519,20 +1519,11 @@ return *Impl; } -unsigned TargetLibraryInfoImpl::getTargetWCharSize(const Triple &T) { - // See also clang/lib/Basic/Targets.cpp. - if (T.isPS4() || T.isOSWindows() || T.isArch16Bit()) - return 2; - if (T.getArch() == Triple::xcore) - return 1; - return 4; -} - unsigned TargetLibraryInfoImpl::getWCharSize(const Module &M) const { if (auto *ShortWChar = cast_or_null( M.getModuleFlag("wchar_size"))) return cast(ShortWChar->getValue())->getZExtValue(); - return getTargetWCharSize(Triple(M.getTargetTriple())); + return 0; } TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -508,6 +508,9 @@ Value *LibCallSimplifier::optimizeWcslen(CallInst *CI, IRBuilder<> &B) { Module &M = *CI->getParent()->getParent()->getParent(); unsigned WCharSize = TLI->getWCharSize(M) * 8; + // We cannot perform this optimization without wchar_size metadata. + if (WCharSize == 0) + return nullptr; return optimizeStringLength(CI, B, WCharSize); } Index: test/Transforms/InstCombine/wcslen-1.ll =================================================================== --- test/Transforms/InstCombine/wcslen-1.ll +++ test/Transforms/InstCombine/wcslen-1.ll @@ -7,6 +7,9 @@ declare i64 @wcslen(i32*) +!0 = !{i32 1, !"wchar_size", i32 4} +!llvm.module.flags = !{!0} + @hello = constant [6 x i32] [i32 104, i32 101, i32 108, i32 108, i32 111, i32 0] @longer = constant [7 x i32] [i32 108, i32 111, i32 110, i32 103, i32 101, i32 114, i32 0] @null = constant [1 x i32] zeroinitializer Index: test/Transforms/InstCombine/wcslen-2.ll =================================================================== --- test/Transforms/InstCombine/wcslen-2.ll +++ test/Transforms/InstCombine/wcslen-2.ll @@ -4,6 +4,9 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +!0 = !{i32 1, !"wchar_size", i32 4} +!llvm.module.flags = !{!0} + @hello = constant [6 x i32] [i32 104, i32 101, i32 108, i32 108, i32 111, i32 0] declare i64 @wcslen(i32*, i32) Index: test/Transforms/InstCombine/wcslen-4.ll =================================================================== --- test/Transforms/InstCombine/wcslen-4.ll +++ test/Transforms/InstCombine/wcslen-4.ll @@ -4,15 +4,17 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +; Without the wchar_size metadata we should see no optimization happening. + @hello = constant [6 x i32] [i32 104, i32 101, i32 108, i32 108, i32 111, i32 0] -declare i64 @wcslen(i32*, i32) +declare i64 @wcslen(i32*) define i64 @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( +; CHECK-NEXT: %hello_l = call i64 @wcslen(i32* getelementptr inbounds ([6 x i32], [6 x i32]* @hello, i64 0, i64 0)) +; CHECK-NEXT: ret i64 %hello_l %hello_p = getelementptr [6 x i32], [6 x i32]* @hello, i64 0, i64 0 - %hello_l = call i64 @wcslen(i32* %hello_p, i32 187) -; CHECK-NEXT: %hello_l = call i64 @wcslen + %hello_l = call i64 @wcslen(i32* %hello_p) ret i64 %hello_l -; CHECK-NEXT: ret i64 %hello_l }