diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp --- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp +++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp @@ -190,6 +190,10 @@ if (Offset.isNegative()) return false; + // We can't bitcast this pointer due to differing address spaces. + if (AS != SrcPtr->getType()->getPointerAddressSpace()) + return false; + // The offset must be a multiple of the scalar element to shuffle cleanly // in the element's size. uint64_t ScalarSizeInBytes = ScalarSize / 8; diff --git a/llvm/test/Transforms/VectorCombine/X86/load-inselt-addrspace.ll b/llvm/test/Transforms/VectorCombine/X86/load-inselt-addrspace.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/VectorCombine/X86/load-inselt-addrspace.ll @@ -0,0 +1,20 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s +; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s + +define <4 x i32> @unsafe_load_i32_insert_v4i32_addrspace(i32* align 16 dereferenceable(16) %v3) { +; CHECK-LABEL: @unsafe_load_i32_insert_v4i32_addrspace( +; CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i32, i32* [[V3:%.*]], i32 1 +; CHECK-NEXT: [[T1:%.*]] = addrspacecast i32* [[T0]] to i32 addrspace(42)* +; CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i32, i32 addrspace(42)* [[T1]], i64 1 +; CHECK-NEXT: [[VAL:%.*]] = load i32, i32 addrspace(42)* [[T2]], align 4 +; CHECK-NEXT: [[INSELT:%.*]] = insertelement <4 x i32> poison, i32 [[VAL]], i32 0 +; CHECK-NEXT: ret <4 x i32> [[INSELT]] +; + %t0 = getelementptr inbounds i32, i32* %v3, i32 1 + %t1 = addrspacecast i32* %t0 to i32 addrspace(42)* + %t2 = getelementptr inbounds i32, i32 addrspace(42)* %t1, i64 1 + %val = load i32, i32 addrspace(42)* %t2, align 4 + %inselt = insertelement <4 x i32> poison, i32 %val, i32 0 + ret <4 x i32> %inselt +}