; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2023 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================

; RUN: igc_opt %s --opaque-pointers -S -o - -types-legalization-pass | FileCheck %s
; REQUIRES: llvm-14-plus

define spir_kernel void @f0(ptr addrspace(1) %arg) {
; CHECK-LABEL: define spir_kernel void @f0(
; CHECK-SAME: ptr addrspace(1) [[ARG:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[PTR:%.*]] = load ptr addrspace(1), ptr addrspace(1) [[ARG]], align 8
; CHECK-NEXT:    call void @llvm.memset.p1.i64(ptr addrspace(1) align 8 [[PTR]], i8 0, i64 960032, i1 false)
; CHECK-NEXT:    ret void
;
entry:
  %ptr = load ptr addrspace(1), ptr addrspace(1) %arg, align 8
  store [120004 x double] zeroinitializer, ptr addrspace(1) %ptr, align 8
  ret void
}


define spir_kernel void @f1([10 x double] addrspace(1)* %arg) {
; CHECK-LABEL: define spir_kernel void @f1(
; CHECK-SAME: ptr addrspace(1) [[ARG:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 0
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP0]], align 8
; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 1
; CHECK-NEXT:    store double 2.000000e+00, ptr addrspace(1) [[TMP1]], align 8
; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 2
; CHECK-NEXT:    store double 3.000000e+00, ptr addrspace(1) [[TMP2]], align 8
; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 3
; CHECK-NEXT:    store double 4.000000e+00, ptr addrspace(1) [[TMP3]], align 8
; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 4
; CHECK-NEXT:    store double 5.000000e+00, ptr addrspace(1) [[TMP4]], align 8
; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 5
; CHECK-NEXT:    store double 6.000000e+00, ptr addrspace(1) [[TMP5]], align 8
; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 6
; CHECK-NEXT:    store double 7.000000e+00, ptr addrspace(1) [[TMP6]], align 8
; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 7
; CHECK-NEXT:    store double 8.000000e+00, ptr addrspace(1) [[TMP7]], align 8
; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 8
; CHECK-NEXT:    store double 9.000000e+00, ptr addrspace(1) [[TMP8]], align 8
; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 9
; CHECK-NEXT:    store double 1.000000e+01, ptr addrspace(1) [[TMP9]], align 8
; CHECK-NEXT:    ret void
;
entry:
  store [10 x double] [double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00, double 5.000000e+00, double 6.000000e+00, double 7.000000e+00, double 8.000000e+00, double 9.000000e+00, double 10.000000e+00], ptr addrspace(1) %arg, align 8
  ret void
}

define spir_kernel void @f2(ptr addrspace(1) %arg) {
; CHECK-LABEL: define spir_kernel void @f2(
; CHECK-SAME: ptr addrspace(1) [[ARG:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 0
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP0]], align 8
; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 1
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP1]], align 8
; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 2
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP2]], align 8
; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 3
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP3]], align 8
; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 4
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP4]], align 8
; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 5
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP5]], align 8
; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 6
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP6]], align 8
; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 7
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP7]], align 8
; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 8
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP8]], align 8
; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr [10 x double], ptr addrspace(1) [[ARG]], i32 0, i32 9
; CHECK-NEXT:    store double 1.000000e+00, ptr addrspace(1) [[TMP9]], align 8
; CHECK-NEXT:    ret void
;
entry:
  store [10 x double] [double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00, double 1.000000e+00], ptr addrspace(1) %arg, align 8
  ret void
}

define spir_kernel void @f3(ptr addrspace(1) %arg) {
; CHECK-LABEL: define spir_kernel void @f3(
; CHECK-SAME: ptr addrspace(1) [[ARG:%.*]]) {
; CHECK-NEXT:  [[ENTRY:.*:]]
; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 0
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP0]], align 8
; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 1
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP1]], align 8
; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 2
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP2]], align 8
; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 3
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP3]], align 8
; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 4
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP4]], align 8
; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 5
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP5]], align 8
; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 6
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP6]], align 8
; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr [8 x <2 x double>], ptr addrspace(1) [[ARG]], i32 0, i32 7
; CHECK-NEXT:    store <2 x double> zeroinitializer, ptr addrspace(1) [[TMP7]], align 8
; CHECK-NEXT:    ret void
;
entry:
  store [8 x <2 x double>] [<2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>, <2 x double> <double 0.000000e+00, double 0.000000e+00>], ptr addrspace(1) %arg, align 8
  ret void
}

%simple.struct.type = type { i64, float }
%nested.struct.type = type { i32, %simple.struct.type }
%double.nested.struct.type = type { i32, %nested.struct.type }

; shouldn't create dead loads

define float @cover.dead.loads(%double.nested.struct.type* byval(%double.nested.struct.type) %struct.instance) #0
; CHECK-LABEL: define float @cover.dead.loads(
; CHECK-SAME: ptr byval([[DOUBLE_NESTED_STRUCT_TYPE:%.*]]) [[STRUCT_INSTANCE:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT:    [[PTR_TO_INNER_STRUCT:%.*]] = getelementptr [[DOUBLE_NESTED_STRUCT_TYPE]], ptr [[STRUCT_INSTANCE]], i32 0, i32 1
; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr [[NESTLE_STRUCT_TYPE:%.*]], ptr [[PTR_TO_INNER_STRUCT]], i32 0, i32 1, i32 1
; CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[TMP1]], align 4
; CHECK-NEXT:    [[RESULT:%.*]] = fmul float [[TMP2]], 4.000000e+00
; CHECK-NEXT:    ret float [[RESULT]]
;
{
  %ptr.to.inner.struct = getelementptr %double.nested.struct.type, %double.nested.struct.type* %struct.instance, i32 0, i32 1
  %inner.struct.value = load %nested.struct.type, %nested.struct.type* %ptr.to.inner.struct
  %inner.struct.value.float = extractvalue %nested.struct.type %inner.struct.value, 1, 1
  %result = fmul float %inner.struct.value.float, 4.0
  ret float %result
}

attributes #0 = { optnone noinline }
