Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -335,10 +335,20 @@ 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); + else { + // If it's integral, translate it to !range metadata. + auto *ITy = dyn_cast(NewTy); + if (!ITy) break; + Metadata *Range[] = { + ConstantAsMetadata::get(IC.Builder->getIntN(ITy->getBitWidth(), 1)), + ConstantAsMetadata::get(IC.Builder->getIntN(ITy->getBitWidth(), + ITy->getBitMask())) + }; + NewLoad->setMetadata(LLVMContext::MD_range, + MDTuple::get(NewLoad->getContext(), Range)); + } break; case LLVMContext::MD_range: Index: test/Transforms/InstCombine/loadstore-metadata.ll =================================================================== --- test/Transforms/InstCombine/loadstore-metadata.ll +++ test/Transforms/InstCombine/loadstore-metadata.ll @@ -83,10 +83,9 @@ 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: %[[V:.*]] = load i64* %{{.*}}, !range ; CHECK-NOT: !nonnull ; CHECK: store i64 %[[V]], i64* entry: