From ad4d73941a5f46443f899d77758b6124a4cd219c Mon Sep 17 00:00:00 2001 From: Bjorn Steinbrink Date: Fri, 10 Jul 2015 06:55:44 +0000 Subject: [PATCH] [InstCombine] Properly combine metadata when replacing a load with another Not doing this can lead to misoptimizations down the line, e.g. because of range metadata on the replacing load excluding values that are valid for the load that is being replaced. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241886 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombineLoadStoreAlloca.cpp | 19 +++++++++++- .../InstCombine/load-combine-metadata.ll | 31 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/Transforms/InstCombine/load-combine-metadata.ll diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index e7a45330d95..224e3321926 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -749,10 +749,27 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { // where there are several consecutive memory accesses to the same location, // separated by a few arithmetic operations. BasicBlock::iterator BBI = &LI; - if (Value *AvailableVal = FindAvailableLoadedValue(Op, LI.getParent(), BBI,6)) + AAMDNodes AATags; + if (Value *AvailableVal = FindAvailableLoadedValue(Op, LI.getParent(), BBI, + 6, nullptr, &AATags)) { + if (LoadInst *NLI = dyn_cast(AvailableVal)) { + unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, + LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, + LLVMContext::MD_range, + LLVMContext::MD_invariant_load, + LLVMContext::MD_nonnull, + }; + combineMetadata(NLI, &LI, KnownIDs); + if (AATags) + NLI->setAAMetadata(AATags); + }; + return ReplaceInstUsesWith( LI, Builder->CreateBitOrPointerCast(AvailableVal, LI.getType(), LI.getName() + ".cast")); + } // load(gep null, ...) -> unreachable if (GetElementPtrInst *GEPI = dyn_cast(Op)) { diff --git a/test/Transforms/InstCombine/load-combine-metadata.ll b/test/Transforms/InstCombine/load-combine-metadata.ll new file mode 100644 index 00000000000..d67f83c1ebc --- /dev/null +++ b/test/Transforms/InstCombine/load-combine-metadata.ll @@ -0,0 +1,31 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +target datalayout = "e-m:e-p:64:64:64-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK-LABEL: @test_load_load_combine_metadata( +; Check that range metadata is combined and AA metadata is preserved +; CHECK: %[[V:.*]] = load i32, i32* %0 +; CHECK-SAME: !tbaa !{{[0-9]+}} +; CHECK-SAME: !range ![[RANGE:[0-9]+]] +; CHECK-SAME: !alias.scope !{{[0-9]+}} +; CHECK-SAME: !noalias !{{[0-9]+}} +; CHECK: store i32 %[[V]], i32* %1 +; CHECK: store i32 %[[V]], i32* %2 +define void @test_load_load_combine_metadata(i32*, i32*, i32*) { + %a = load i32, i32* %0, !tbaa !8, !range !0, !alias.scope !5, !noalias !6 + %b = load i32, i32* %0, !range !1 + store i32 %a, i32* %1 + store i32 %b, i32* %2 + ret void +} + +; CHECK: ![[RANGE]] = !{i32 0, i32 1, i32 8, i32 9} +!0 = !{ i32 0, i32 1 } +!1 = !{ i32 8, i32 9 } +!2 = !{!2} +!3 = !{!3, !2} +!4 = !{!4, !2} +!5 = !{!3} +!6 = !{!4} +!7 = !{ !"tbaa root" } +!8 = !{ !7, !7, i64 0 } -- 2.34.1