diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 42b3cef470c0..d0fb0d32b3ac 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1598,8 +1598,8 @@ Value *LibCallSimplifier::optimizePrintFString(CallInst *CI, IRBuilder<> &B) { if (!CI->use_empty()) return nullptr; - // printf("x") -> putchar('x'), even for '%'. - if (FormatStr.size() == 1) + // printf("x") -> putchar('x'), even for "%" and "%%". + if (FormatStr.size() == 1 || FormatStr == "%%") return emitPutChar(B.getInt32(FormatStr[0]), B, TLI); // printf("%s", "a") --> putchar('a') diff --git a/llvm/test/Transforms/InstCombine/printf-1.ll b/llvm/test/Transforms/InstCombine/printf-1.ll index 75e11ce7b7b4..2a513d0de248 100644 --- a/llvm/test/Transforms/InstCombine/printf-1.ll +++ b/llvm/test/Transforms/InstCombine/printf-1.ll @@ -7,6 +7,7 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3 @hello_world = constant [13 x i8] c"hello world\0A\00" @h = constant [2 x i8] c"h\00" +@h2 = constant [3 x i8] c"%%\00" @percent = constant [2 x i8] c"%\00" @percent_c = constant [3 x i8] c"%c\00" @percent_d = constant [3 x i8] c"%d\00" @@ -38,6 +39,17 @@ define void @test_simplify2() { ; CHECK-NEXT: ret void } +; Special case: printf("%%") -> putchar('%'). + +define void @test_simplify2b() { +; CHECK-LABEL: @test_simplify2b( + %fmt = getelementptr [3 x i8], [3 x i8]* @h2, i32 0, i32 0 + call i32 (i8*, ...) @printf(i8* %fmt) +; CHECK-NEXT: call i32 @putchar(i32 37) + ret void +; CHECK-NEXT: ret void +} + define void @test_simplify3() { ; CHECK-LABEL: @test_simplify3( %fmt = getelementptr [2 x i8], [2 x i8]* @percent, i32 0, i32 0