diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -874,12 +874,17 @@ if (Function *F = dyn_cast(&AnchorValue)) { for (const Use &U : F->uses()) if (CallBase *CB = dyn_cast(U.getUser())) - if (CB->isCallee(&U)) - Changed = ReplaceCallSiteUsersWith(*CB, *RVC) | Changed; + if (CB->isCallee(&U)) { + Constant *RVCCast = + ConstantExpr::getTruncOrBitCast(RVC, CB->getType()); + Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed; + } } else { assert(isa(AnchorValue) && "Expcected a function or call base anchor!"); - Changed = ReplaceCallSiteUsersWith(cast(AnchorValue), *RVC); + Constant *RVCCast = + ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType()); + Changed = ReplaceCallSiteUsersWith(cast(AnchorValue), *RVCCast); } if (Changed == ChangeStatus::CHANGED) STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn, diff --git a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll --- a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll +++ b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll @@ -827,6 +827,17 @@ ret i32 %add3 } +@G = external global i8 +define i32* @ret_const() { + %bc = bitcast i8* @G to i32* + ret i32* %bc +} +define i32* @use_const() { + %c = call i32* @ret_const() + ; CHECK: ret i32* bitcast (i8* @G to i32*) + ret i32* %c +} + attributes #0 = { noinline nounwind uwtable } ; BOTH-NOT: attributes #