summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/TargetLibraryInfo.h8
-rw-r--r--llvm/lib/Analysis/TargetLibraryInfo.cpp11
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp3
-rw-r--r--llvm/test/Transforms/InstCombine/wcslen-1.ll3
-rw-r--r--llvm/test/Transforms/InstCombine/wcslen-2.ll3
-rw-r--r--llvm/test/Transforms/InstCombine/wcslen-4.ll20
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
+}
OpenPOWER on IntegriCloud