Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -43,6 +43,10 @@ cl::desc("Enable unsafe double to float " "shrinking for math lib calls")); +static cl::opt + EnableUnlockedIO("enable-io-unlocked", cl::Hidden, + cl::init(false), + cl::desc("Enable transformation to unlocked IO lib calls")); //===----------------------------------------------------------------------===// // Helper Functions @@ -130,6 +134,9 @@ static bool isLocallyOpenedFile(Value *File, CallInst *CI, IRBuilder<> &B, const TargetLibraryInfo *TLI) { + if (!EnableUnlockedIO) + return false; + CallInst *FOpen = dyn_cast(File); if (!FOpen) return false; Index: test/Transforms/InstCombine/no-unlocked-stdio.ll =================================================================== --- test/Transforms/InstCombine/no-unlocked-stdio.ll +++ test/Transforms/InstCombine/no-unlocked-stdio.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S -mtriple=x86_64-unknown-linux-gnu | 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 + +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) Index: test/Transforms/InstCombine/unlocked-stdio-mingw.ll =================================================================== --- test/Transforms/InstCombine/unlocked-stdio-mingw.ll +++ test/Transforms/InstCombine/unlocked-stdio-mingw.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S -mtriple=x86_64-w64-mingw32 | FileCheck %s +; RUN: opt < %s -instcombine -S -enable-io-unlocked -mtriple=x86_64-w64-mingw32 | FileCheck %s %struct._iobuf = type { i8*, i32, i8*, i32, i32, i32, i32, i8* } Index: test/Transforms/InstCombine/unlocked-stdio.ll =================================================================== --- test/Transforms/InstCombine/unlocked-stdio.ll +++ test/Transforms/InstCombine/unlocked-stdio.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -instcombine -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s +; RUN: opt < %s -instcombine -enable-io-unlocked -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s %struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] } %struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }