summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2015-02-13 02:30:01 +0000
committerChandler Carruth <chandlerc@gmail.com>2015-02-13 02:30:01 +0000
commit87fdafc7b2381f76725ec99c2c0901e4600a07bb (patch)
tree94af586c383980ace812a94cd58607721207458a /llvm
parent415f41258fa99d829c35408e2a276cf5f63705d2 (diff)
downloadbcm5719-llvm-87fdafc7b2381f76725ec99c2c0901e4600a07bb.tar.gz
bcm5719-llvm-87fdafc7b2381f76725ec99c2c0901e4600a07bb.zip
[IC] Fix a bug with the instcombine canonicalizing of loads and
propagating of metadata. We were propagating !nonnull metadata even when the newly formed load is no longer of a pointer type. This is clearly broken and results in LLVM failing the verifier and aborting. This patch just restricts the propagation of !nonnull metadata to when we actually have a pointer type. This bug report and the initial version of this patch was provided by Charles Davis! Many thanks for finding this! We still need to add logic to round-trip the metadata correctly if we combine from pointer types to integer types and then back by using range metadata for the integer type loads. But this is the minimal and safe version of the patch, which is important so we can backport it into 3.6. llvm-svn: 229029
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp11
-rw-r--r--llvm/test/Transforms/InstCombine/loadstore-metadata.ll19
2 files changed, 28 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index a08f3717bc6..1dbe6074195 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -330,11 +330,17 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
case LLVMContext::MD_noalias:
case LLVMContext::MD_nontemporal:
case LLVMContext::MD_mem_parallel_loop_access:
- case LLVMContext::MD_nonnull:
// All of these directly apply.
NewLoad->setMetadata(ID, N);
break;
+ case LLVMContext::MD_nonnull:
+ // FIXME: We should translate this into range metadata for integer types
+ // and vice versa.
+ if (NewTy->isPointerTy())
+ NewLoad->setMetadata(ID, N);
+ break;
+
case LLVMContext::MD_range:
// FIXME: It would be nice to propagate this in some way, but the type
// conversions make it hard.
@@ -377,13 +383,14 @@ static StoreInst *combineStoreToNewValue(InstCombiner &IC, StoreInst &SI, Value
case LLVMContext::MD_noalias:
case LLVMContext::MD_nontemporal:
case LLVMContext::MD_mem_parallel_loop_access:
- case LLVMContext::MD_nonnull:
// All of these directly apply.
NewStore->setMetadata(ID, N);
break;
case LLVMContext::MD_invariant_load:
+ case LLVMContext::MD_nonnull:
case LLVMContext::MD_range:
+ // These don't apply for stores.
break;
}
}
diff --git a/llvm/test/Transforms/InstCombine/loadstore-metadata.ll b/llvm/test/Transforms/InstCombine/loadstore-metadata.ll
index ad6a11cf6eb..e5b04494bf1 100644
--- a/llvm/test/Transforms/InstCombine/loadstore-metadata.ll
+++ b/llvm/test/Transforms/InstCombine/loadstore-metadata.ll
@@ -1,5 +1,7 @@
; 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"
+
define i32 @test_load_cast_combine_tbaa(float* %ptr) {
; Ensure (cast (load (...))) -> (load (cast (...))) preserves TBAA.
; CHECK-LABEL: @test_load_cast_combine_tbaa(
@@ -78,6 +80,23 @@ exit:
ret void
}
+define void @test_load_cast_combine_nonnull(float** %ptr) {
+; We can't preserve nonnull metadata when converting a load of a pointer to
+; a load of an integer.
+; FIXME: We should really transform this into range metadata and vice versa.
+;
+; CHECK-LABEL: @test_load_cast_combine_nonnull(
+; CHECK: %[[V:.*]] = load i64* %{{.*}}
+; CHECK-NOT: !nonnull
+; CHECK: store i64 %[[V]], i64*
+entry:
+ %p = load float** %ptr, !nonnull !3
+ %gep = getelementptr float** %ptr, i32 42
+ store float* %p, float** %gep
+
+ ret void
+}
+
!0 = !{ !1, !1, i64 0 }
!1 = !{ !1 }
!2 = !{ !2, !1 }
OpenPOWER on IntegriCloud