;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2026 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================

; REQUIRES: llvm-16-plus, regkeys
; RUN: igc_opt -S --opaque-pointers --igc-vector-coalescer --regkey=VectorizerLog=1 --regkey=VectorizerLogToErr=1 -dce < %s 2>&1 | FileCheck %s

; CHECK:  %coalesced_input = shufflevector <8 x float> %in1, <8 x float> %in2, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
; CHECK:  %coalesced_intrinsic = call <16 x float> @llvm.exp2.v16f32(<16 x float> %coalesced_input)
; CHECK:  %coalesced_output1 = shufflevector <16 x float> %coalesced_intrinsic, <16 x float> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
; CHECK:  %coalesced_output = shufflevector <16 x float> %coalesced_intrinsic, <16 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
; CHECK:  %coalesced_input2 = shufflevector <8 x float> %in3, <8 x float> %in3, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
; CHECK:  %coalesced_intrinsic3 = call <16 x float> @llvm.exp2.v16f32(<16 x float> %coalesced_input2)
; CHECK:  %coalesced_output5 = shufflevector <16 x float> %coalesced_intrinsic3, <16 x float> undef, <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
; CHECK:  %coalesced_output4 = shufflevector <16 x float> %coalesced_intrinsic3, <16 x float> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>

; Function Attrs: convergent nounwind
define spir_kernel void @foo(<8 x float> %in1, <8 x float> %in2, <8 x float> %in3, <8 x float> %in4) #0 {
cond-add:
  br label %._crit_edge4000

._crit_edge4000:                                  ; preds = %._crit_edge4000, %cond-add
  %vectorized_intrinsic0 = call <8 x float> @llvm.exp2.v8f32(<8 x float> %in1)
  %vectorized_intrinsic1 = call <8 x float> @llvm.exp2.v8f32(<8 x float> %in2)

  %vectorized_intrinsic2 = call <8 x float> @llvm.exp2.v8f32(<8 x float> %in3)
  %vectorized_intrinsic3 = call <8 x float> @llvm.exp2.v8f32(<8 x float> %in3)
  br label %end

end:                                      ; No predecessors!
  call void @llvm.genx.GenISA.LSC2DBlockWrite.v8f32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x float> %vectorized_intrinsic0)
  call void @llvm.genx.GenISA.LSC2DBlockWrite.v8f32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x float> %vectorized_intrinsic1)
  call void @llvm.genx.GenISA.LSC2DBlockWrite.v8f32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x float> %vectorized_intrinsic2)
  call void @llvm.genx.GenISA.LSC2DBlockWrite.v8f32(i64 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i1 false, i1 false, i32 0, <8 x float> %vectorized_intrinsic3)
  ret void
}

declare void @llvm.genx.GenISA.LSC2DBlockWrite.v8f32(i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i1, i1, i32, <8 x float>)

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare <8 x float> @llvm.exp2.v8f32(<8 x float>) #1

attributes #0 = { convergent nounwind }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

!igc.functions = !{!0}

!0 = !{ptr @foo, !1}
!1 = !{!2}
!2 = !{!"function_type", i32 0}

!3 = !{!"requiredSubGroupSize", i32 16}
!4 = !{!"FuncMDValue[0]", !3}
!5 = !{!"FuncMDMap[0]", ptr @foo}
!6 = !{!"FuncMD", !5, !4}
!7 = !{!"ModuleMD", !6}
!IGCMetadata = !{!7}