diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -608,6 +608,11 @@ if (is_contained(WorkList, User)) continue; + // Do not promote instructions of vector type. It is hard to track their + // users. + if (isa(User) || isa(User)) + return false; + if (CallInst *CI = dyn_cast(User)) { if (!isCallPromotable(CI)) return false; diff --git a/llvm/test/CodeGen/AMDGPU/skip-promote-alloca-vector-users.ll b/llvm/test/CodeGen/AMDGPU/skip-promote-alloca-vector-users.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/skip-promote-alloca-vector-users.ll @@ -0,0 +1,38 @@ +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -amdgpu-promote-alloca < %s | FileCheck %s + +; Do not promote an alloca with users of vector/aggregate type. + +; CHECK-LABEL: @test_insertelement( +; CHECK: %alloca = alloca i16 +; CHECK-NEXT: insertelement <2 x i16*> undef, i16* %alloca, i32 0 +define amdgpu_kernel void @test_insertelement() #0 { +entry: + %alloca = alloca i16, align 4 + %in = insertelement <2 x i16*> undef, i16* %alloca, i32 0 + store volatile <2 x i16*> %in, <2 x i16*>* undef, align 4 + ret void +} + +; CHECK-LABEL: @test_insertvalue( +; CHECK: %alloca = alloca i16 +; CHECK-NEXT: insertvalue { i16* } undef, i16* %alloca, 0 +define amdgpu_kernel void @test_insertvalue() #0 { +entry: + %alloca = alloca i16, align 4 + %in = insertvalue { i16* } undef, i16* %alloca, 0 + store volatile { i16* } %in, { i16* }* undef, align 4 + ret void +} + +; CHECK-LABEL: @test_insertvalue_array( +; CHECK: %alloca = alloca i16 +; CHECK-NEXT: insertvalue [2 x i16*] undef, i16* %alloca, 0 +define amdgpu_kernel void @test_insertvalue_array() #0 { +entry: + %alloca = alloca i16, align 4 + %in = insertvalue [2 x i16*] undef, i16* %alloca, 0 + store volatile [2 x i16*] %in, [2 x i16*]* undef, align 4 + ret void +} + +attributes #0 = { nounwind }