From 8c9da718663fc81b78f96947fe839af7ceb365db Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Thu, 17 May 2018 08:16:08 +0000 Subject: [PATCH] [Analysis] Only use _unlocked stdio functions on linux 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 --- lib/Analysis/TargetLibraryInfo.cpp | 3 ++- .../InstCombine/unlocked-stdio-mingw.ll | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/InstCombine/unlocked-stdio-mingw.ll diff --git a/lib/Analysis/TargetLibraryInfo.cpp b/lib/Analysis/TargetLibraryInfo.cpp index 05fa201c607..b223662bed1 100644 --- a/lib/Analysis/TargetLibraryInfo.cpp +++ b/lib/Analysis/TargetLibraryInfo.cpp @@ -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/test/Transforms/InstCombine/unlocked-stdio-mingw.ll b/test/Transforms/InstCombine/unlocked-stdio-mingw.ll new file mode 100644 index 00000000000..f41b86654cb --- /dev/null +++ b/test/Transforms/InstCombine/unlocked-stdio-mingw.ll @@ -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)