Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -1229,6 +1229,10 @@ // If so, propagate the return value of the callee into this call result. mergeInValue(I, TFRVI->second); } + + // Replacing `musttail` instructions with constant breaks `musttail` semantics + if (CS.isMustTailCall()) + return markOverdefined(I); } void SCCPSolver::Solve() { Index: test/Transforms/SCCP/musttail-call.ll =================================================================== --- /dev/null +++ test/Transforms/SCCP/musttail-call.ll @@ -0,0 +1,27 @@ +; RUN: opt < %s -ipsccp -S | FileCheck %s + +declare i32 @external() + +define i8* @start(i8* %p, i8* %endp, i32 %match) { + %i0 = icmp ne i8* %p, %endp + br i1 %i0, label %b0_has_data, label %b1_no_data +b0_has_data: + %i2 = load i8, i8* %p + switch i8 %i2, label %b2_switch_otherwise [ i8 32, label %b3_case_32 ] +b1_no_data: + %i3 = bitcast i8* (i8*, i8*, i32)* @start to i8* + ret i8* %i3 +b2_switch_otherwise: + %i4 = musttail call i8* @start(i8* %p, i8* %endp, i32 0) + ret i8* %i4 +b3_case_32: + %i5 = musttail call i8* @invoke(i8* %p, i8* %endp, i32 0) + ret i8* %i5 +} + +define internal i8* @invoke(i8* %p, i8* %endp, i32 %match) { + %i1 = call i32 @external() + %i2 = musttail call i8* @start(i8* %p, i8* %endp, i32 0) + ret i8* %i2 +} +