Index: llvm/lib/Transforms/Scalar/SCCP.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SCCP.cpp +++ llvm/lib/Transforms/Scalar/SCCP.cpp @@ -2038,6 +2038,8 @@ for (unsigned i = 0, e = ReturnsToZap.size(); i != e; ++i) { Function *F = ReturnsToZap[i]->getParent()->getParent(); ReturnsToZap[i]->setOperand(0, UndefValue::get(F->getReturnType())); + for (Argument& A : F->args()) + F->removeParamAttr(A.getArgNo(), Attribute::Returned); } // If we inferred constant or undef values for globals variables, we can Index: llvm/test/Transforms/SCCP/ipsccp-clear-returned.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/SCCP/ipsccp-clear-returned.ll @@ -0,0 +1,22 @@ +; if IPSCCP determines a function returns undef, +; then the "returned" attribute of input arguments +; should be cleared. + +; RUN: opt < %s -ipsccp -S | FileCheck %s +define i32 @main() { +; CHECK-LABEL: @main +entry: +; CHECK-NEXT: entry: + %call = call i32 @func_return_undef(i32 1) +; CHECK: {{call.*@func_return_undef}} + ret i32 0 +} + +define internal i32 @func_return_undef(i32 returned %arg) { +; CHECK: {{define.*@func_return_undef}} +; CHECK-NOT: returned +entry: +; CHECK-NEXT: entry: +; CHECK-NEXT: {{ret.*undef}} +ret i32 %arg +}