diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index a08f3717bc6..1dbe6074195 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/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/test/Transforms/InstCombine/loadstore-metadata.ll b/test/Transforms/InstCombine/loadstore-metadata.ll index ad6a11cf6eb..e5b04494bf1 100644 --- a/test/Transforms/InstCombine/loadstore-metadata.ll +++ b/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 }