Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -379,6 +379,11 @@ Value *StartPtr, Value *ByteVal) { if (!DL) return nullptr; + // FIXME: memcpy / memset for address spaces >= 256 are not supported in the + // code generator + if (cast(StartPtr->getType())->getAddressSpace() >= 256) + return nullptr; + // Okay, so we now have a single store that can be splatable. Scan to find // all subsequent stores of the same value to offset from the same pointer. // Join these together into ranges, so we can decide whether contiguous blocks Index: test/Transforms/MemCpyOpt/addrspace-256.ll =================================================================== --- /dev/null +++ test/Transforms/MemCpyOpt/addrspace-256.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -memcpyopt -S | FileCheck %s + +; Memcpy / memset for address spaces >= 256 are not supported in the code +; generator. This test makes sure this pass doesn't create new memsets (memcpys +; are always formed from existing ones). + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +%test = type { i8*, i8*, i8*, i8* } + +define void @store_nulls(%test addrspace(256)* %x) { + %1 = getelementptr inbounds %test addrspace(256)* %x, i32 0, i32 0 + store i8* null, i8* addrspace(256)* %1 + %2 = getelementptr inbounds %test addrspace(256)* %x, i32 0, i32 1 + store i8* null, i8* addrspace(256)* %2 + %3 = getelementptr inbounds %test addrspace(256)* %x, i32 0, i32 2 + store i8* null, i8* addrspace(256)* %3 + %4 = getelementptr inbounds %test addrspace(256)* %x, i32 0, i32 3 + store i8* null, i8* addrspace(256)* %4 +; CHECK-LABEL: @store_nulls( +; CHECK-NOT: memset + ret void +}