[Analysis] Only use _unlocked stdio functions on linux
authorMartin Storsjo <martin@martin.st>
Thu, 17 May 2018 08:16:08 +0000 (08:16 +0000)
committerMartin Storsjo <martin@martin.st>
Thu, 17 May 2018 08:16:08 +0000 (08:16 +0000)
The existing comment said that the functions were available only
on GNU/Linux (and on certain Android versions), but only checked
T.isGNUEnvironment() which also is true on MinGW (for arch-windows-gnu
triplets), which doesn't have such functions.

Existing checks in the initialize function in TargetLibraryInfo.cpp
also use only T.isOSLinux() to check for glibc features.

This fixes use of stdio on MinGW.

Differential Revision: https://reviews.llvm.org/D47002

llvm-svn: 332581

llvm/lib/Analysis/TargetLibraryInfo.cpp
llvm/test/Transforms/InstCombine/unlocked-stdio-mingw.ll [new file with mode: 0644]

index 05fa201c607f966926bc634a8da45da3ea15202e..b223662bed168b0da8c4ca44b1f87c6a870a98e6 100644 (file)
@@ -482,7 +482,8 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
     TLI.setUnavailable(LibFunc_sinhl_finite);
   }
 
-  if (T.isGNUEnvironment() || (T.isAndroid() && !T.isAndroidVersionLT(28))) {
+  if ((T.isOSLinux() && T.isGNUEnvironment()) ||
+      (T.isAndroid() && !T.isAndroidVersionLT(28))) {
     // available IO unlocked variants on GNU/Linux and Android P or later
     TLI.setAvailable(LibFunc_getc_unlocked);
     TLI.setAvailable(LibFunc_getchar_unlocked);
diff --git a/llvm/test/Transforms/InstCombine/unlocked-stdio-mingw.ll b/llvm/test/Transforms/InstCombine/unlocked-stdio-mingw.ll
new file mode 100644 (file)
index 0000000..f41b866
--- /dev/null
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S -mtriple=x86_64-w64-mingw32 | FileCheck %s
+
+%struct._iobuf = type { i8*, i32, i8*, i32, i32, i32, i32, i8* }
+
+@.str = private unnamed_addr constant [5 x i8] c"file\00", align 1
+@.str.1 = private unnamed_addr constant [2 x i8] c"w\00", align 1
+
+; Check that this still uses the plain fputc instead of fputc_unlocked
+; for MinGW targets.
+define void @external_fputc_test() {
+; CHECK-LABEL: @external_fputc_test(
+; CHECK-NEXT:    [[CALL:%.*]] = call %struct._iobuf* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
+; CHECK-NEXT:    [[CALL1:%.*]] = call i32 @fputc(i32 99, %struct._iobuf* [[CALL]])
+; CHECK-NEXT:    ret void
+;
+  %call = call %struct._iobuf* @fopen(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0))
+  %call1 = call i32 @fputc(i32 99, %struct._iobuf* %call)
+  ret void
+}
+
+declare %struct._iobuf* @fopen(i8*, i8*)
+declare i32 @fputc(i32, %struct._iobuf* nocapture)