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.
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;
}
}
; 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(
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 }