;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2024 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================
; REQUIRES: opaque-ptr-fix, llvm-14-plus

; RUN: igc_opt --opaque-pointers -platformpvc -igc-joint-matrix-resolution -S %s 2>&1 | FileCheck %s
; ------------------------------------------------
; JointMatrixFuncsResolutionPass
; ------------------------------------------------
; This test checks the else branch in the getAcc2x64xFloatElementPtr function, triggered when slice extract/insert is used on matrix,
; which is not result of load instruction. This case is exposed by a combination of fill and apply operations on Matrix C 32x64.

%spirv.JointMatrixINTEL._float_32_64_3_3_2 = type opaque

; CHECK: define spir_kernel void @test(i64 [[IND:%.*]], float [[ARG_R:%.*]]) {
define spir_kernel void @test(i64 %ind, float %_arg_r) {
    ; CHECK:  [[TC:%.*]] = alloca { <64 x float>, <64 x float> }
    ; insertelement instructions from _Z26__spirv_CompositeConstructf are not checked in this test
    ; [[MATRIX_C1]] and [[MATRIX_C2]] are generated by _Z26__spirv_CompositeConstructf, with each storing an vector of <64 x float>, combining for the structure {<64 x float>, <64 x float>}.
    ; CHECK:  [[TMP:%.*]] = insertvalue { <64 x float>, <64 x float> } undef, <64 x float> [[MATRIX_C1:%.*]], 0
    ; CHECK:  [[MATRIX_C:%.*]] = insertvalue { <64 x float>, <64 x float> } [[TMP]], <64 x float> [[MATRIX_C2:%.*]], 1
    %C = call spir_func %spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* @_Z26__spirv_CompositeConstructf(float %_arg_r)

    ; CHECK: store { <64 x float>, <64 x float> } [[MATRIX_C]], { <64 x float>, <64 x float> }* [[TC]]
    ; CHECK: [[TMP1:%.*]] = bitcast { <64 x float>, <64 x float> }* [[TC]] to float*
    ; CHECK: [[TMP2:%.*]] = getelementptr float, float* [[TMP1]], i64 [[IND]]
    ; CHECK: [[TMP3:%.*]] = load float, float* [[TMP2]]
    %1 = call spir_func float @_Z28__spirv_VectorExtractDynamicPU3AS143__spirv_JointMatrixINTEL__float_32_64_3_3_2l(%spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* %C, i64 %ind)

    ; CHECK: [[ADDI:%.*]] = fadd float [[TMP3]], [[ARG_R]]
    %add.i.i = fadd float %1, %_arg_r

    ; CHECK: store { <64 x float>, <64 x float> } [[MATRIX_C]], { <64 x float>, <64 x float> }* [[TC]]
    ; CHECK: [[TMP4:%.*]] = bitcast { <64 x float>, <64 x float> }* [[TC]] to float*
    ; CHECK: [[TMP5:%.*]] = getelementptr float, float* [[TMP4]], i64 [[IND]]
    ; CHECK: store float [[ADDI]], float* [[TMP5]]
    ; CHECK: [[TMP6:%.*]] = load { <64 x float>, <64 x float> }, { <64 x float>, <64 x float> }* [[TC]]
    %call.i36 = call spir_func %spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* @_Z27__spirv_VectorInsertDynamicPU3AS143__spirv_JointMatrixINTEL__float_32_64_3_3_2fl(%spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* %C, float %add.i.i, i64 %ind)

    ; CHECK: ret void
    ret void
}

declare spir_func %spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* @_Z26__spirv_CompositeConstructf(float)
declare spir_func float @_Z28__spirv_VectorExtractDynamicPU3AS143__spirv_JointMatrixINTEL__float_32_64_3_3_2l(%spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)*, i64)
declare spir_func %spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)* @_Z27__spirv_VectorInsertDynamicPU3AS143__spirv_JointMatrixINTEL__float_32_64_3_3_2fl(%spirv.JointMatrixINTEL._float_32_64_3_3_2 addrspace(1)*, float, i64)

!igc.functions = !{!0}
!0 = !{void (i64, float)* @test, !1}
!1 = !{!2, !3}
!2 = !{!"function_type", i32 0}
!3 = !{!"sub_group_size", i32 16}
