diff options
| -rw-r--r-- | llvm/include/llvm/Analysis/TargetLibraryInfo.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Analysis/TargetLibraryInfo.cpp | 11 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 3 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/wcslen-1.ll | 3 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/wcslen-2.ll | 3 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/wcslen-4.ll | 20 |
6 files changed, 32 insertions, 16 deletions
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h index d75e7833279..a3fe834022f 100644 --- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h +++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h @@ -193,13 +193,9 @@ public: 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 diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp index 2be5d5caf7c..47a84bd382a 100644 --- a/llvm/lib/Analysis/TargetLibraryInfo.cpp +++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp @@ -1519,20 +1519,11 @@ TargetLibraryInfoImpl &TargetLibraryAnalysis::lookupInfoImpl(const Triple &T) { 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<ConstantAsMetadata>( M.getModuleFlag("wchar_size"))) return cast<ConstantInt>(ShortWChar->getValue())->getZExtValue(); - return getTargetWCharSize(Triple(M.getTargetTriple())); + return 0; } TargetLibraryInfoWrapperPass::TargetLibraryInfoWrapperPass() diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 37cfc2cbbc1..22c078a8d2f 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -508,6 +508,9 @@ Value *LibCallSimplifier::optimizeStrLen(CallInst *CI, IRBuilder<> &B) { 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); } diff --git a/llvm/test/Transforms/InstCombine/wcslen-1.ll b/llvm/test/Transforms/InstCombine/wcslen-1.ll index cdde1bfbde4..22da95ef4ad 100644 --- a/llvm/test/Transforms/InstCombine/wcslen-1.ll +++ b/llvm/test/Transforms/InstCombine/wcslen-1.ll @@ -7,6 +7,9 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 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 diff --git a/llvm/test/Transforms/InstCombine/wcslen-2.ll b/llvm/test/Transforms/InstCombine/wcslen-2.ll index c1a70312a2b..15f1fdbb1ad 100644 --- a/llvm/test/Transforms/InstCombine/wcslen-2.ll +++ b/llvm/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) diff --git a/llvm/test/Transforms/InstCombine/wcslen-4.ll b/llvm/test/Transforms/InstCombine/wcslen-4.ll new file mode 100644 index 00000000000..07832288965 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/wcslen-4.ll @@ -0,0 +1,20 @@ +; Test that the wcslen library call simplifier works correctly. +; +; RUN: opt < %s -instcombine -S | FileCheck %s + +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*) + +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) + ret i64 %hello_l +} |

