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 @@ -306,6 +306,8 @@ AAMDNodes AAInfo; OrigLoad->getAAMetadata(AAInfo); newLoad->setAAMetadata(AAInfo); + // And other metadata. + newLoad->copyMetadata(*OrigLoad, {LLVMContext::MD_range}); Args.push_back(newLoad); ArgAttrVec.push_back(AttributeSet()); diff --git a/llvm/test/Transforms/ArgumentPromotion/metadata.ll b/llvm/test/Transforms/ArgumentPromotion/metadata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/ArgumentPromotion/metadata.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -argpromotion -S | FileCheck %s + +define i32 @should_copy_range({ i32, i32 }* %x) { +; CHECK-LABEL: define i32 @should_copy_range( +; 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, !range !0 +; CHECK-NEXT: %1 = call i32 @f_load_range(i32 %x.idx.val) +; CHECK-NEXT: ret i32 %1 +; + %1 = call i32 @f_load_range({ i32, i32 }* %x) + ret i32 %1 +} + +define internal i32 @f_load_range({ i32, i32 }* %v) { +; CHECK-LABEL: define internal i32 @f_load_range( +; CHECK: ret i32 +; + %1 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %v, i64 0, i32 0 + %2 = load i32, i32* %1, align 4, !range !0 + ret i32 %2 +} + +!0 = !{i32 0, i32 4}