summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Steinbrink <bsteinbr@gmail.com>2015-07-10 06:55:44 +0000
committerBjorn Steinbrink <bsteinbr@gmail.com>2015-07-10 06:55:44 +0000
commita91fd0998fcf39b8eb1920f358671cbe82b0ef1c (patch)
tree1709c050b0736e8fe714cb0c9b4ea9d5070c2c16
parent7dc6b500473d01ac8751f03c4ffb60d1e10e10be (diff)
downloadbcm5719-llvm-a91fd0998fcf39b8eb1920f358671cbe82b0ef1c.tar.gz
bcm5719-llvm-a91fd0998fcf39b8eb1920f358671cbe82b0ef1c.zip
[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. llvm-svn: 241886
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp19
-rw-r--r--llvm/test/Transforms/InstCombine/load-combine-metadata.ll31
2 files changed, 49 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index e7a45330d95..224e3321926 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/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<LoadInst>(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<GetElementPtrInst>(Op)) {
diff --git a/llvm/test/Transforms/InstCombine/load-combine-metadata.ll b/llvm/test/Transforms/InstCombine/load-combine-metadata.ll
new file mode 100644
index 00000000000..d67f83c1ebc
--- /dev/null
+++ b/llvm/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 }
OpenPOWER on IntegriCloud