diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -302,12 +302,8 @@ LoadInst *newLoad = IRB.CreateLoad(OrigLoad->getType(), V, V->getName() + ".val"); newLoad->setAlignment(OrigLoad->getAlign()); - // Transfer the AA info too. - AAMDNodes AAInfo; - OrigLoad->getAAMetadata(AAInfo); - newLoad->setAAMetadata(AAInfo); - // And other metadata. - newLoad->copyMetadata(*OrigLoad, {LLVMContext::MD_range}); + // Transfer all metadata too. + newLoad->copyMetadata(*OrigLoad); Args.push_back(newLoad); ArgAttrVec.push_back(AttributeSet()); diff --git a/llvm/test/Transforms/ArgumentPromotion/metadata.ll b/llvm/test/Transforms/ArgumentPromotion/metadata.ll --- a/llvm/test/Transforms/ArgumentPromotion/metadata.ll +++ b/llvm/test/Transforms/ArgumentPromotion/metadata.ll @@ -20,4 +20,25 @@ ret i32 %2 } +define i32* @should_copy_nonnull({ i32*, i32* }* %x) { +; CHECK-LABEL: define i32* @should_copy_nonnull( +; CHECK: %x.idx = getelementptr { i32*, i32* }, { i32*, i32* }* %x, i64 0, i32 0 +; CHECK-NEXT: %x.idx.val = load i32*, i32** %x.idx, align 4, !nonnull !1 +; CHECK-NEXT: %1 = call i32* @f_load_nonnull(i32* %x.idx.val) +; CHECK-NEXT: ret i32* %1 +; + %1 = call i32* @f_load_nonnull({ i32*, i32* }* %x) + ret i32* %1 +} + +define internal i32* @f_load_nonnull({ i32*, i32* }* %v) { +; CHECK-LABEL: define internal i32* @f_load_nonnull( +; CHECK: ret i32* +; + %1 = getelementptr inbounds { i32*, i32* }, { i32*, i32* }* %v, i64 0, i32 0 + %2 = load i32*, i32** %1, align 4, !nonnull !1 + ret i32* %2 +} + !0 = !{i32 0, i32 4} +!1 = !{}