Index: lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- lib/Transforms/Utils/SimplifyLibCalls.cpp +++ lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1837,6 +1837,11 @@ StringRef FormatStr; if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) return nullptr; + // The rest of the function assumes the return value is an integer type. + // If the sprintf function is static, an earlier optimization pass could + // remove the return value and make it void. + if (!isa(CI->getType())) + return nullptr; // If we just have a format string (nothing else crazy) transform it. if (CI->getNumArgOperands() == 2) { Index: test/Transforms/InstCombine/sprintf-void.ll =================================================================== --- /dev/null +++ test/Transforms/InstCombine/sprintf-void.ll @@ -0,0 +1,19 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" + +@hello_world = constant [13 x i8] c"hello world\0A\00" + +declare void @sprintf(i8*, i8*, ...) + +; Check that a sprintf call, that would otherwise be optimized, but with +; optimized out return type, doesn't crash the optimizer. + +define void @test_simplify1(i8* %dst) { +; CHECK-LABEL: @test_simplify1( + %fmt = getelementptr [13 x i8], [13 x i8]* @hello_world, i32 0, i32 0 + call void (i8*, i8*, ...) @sprintf(i8* %dst, i8* %fmt) +; CHECK-NEXT: call void (i8*, i8*, ...) @sprintf(i8* %dst, i8* getelementptr inbounds ([13 x i8], [13 x i8]* @hello_world, i32 0, i32 0)) + ret void +; CHECK-NEXT: ret void +}