<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/121566>121566</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Global variable with Function storage class generated by SPIR-V backend
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jdnk
      </td>
    </tr>
</table>

<pre>
    The SPIR-V backend puts a global variable under the Function storage space.

Original source:

```c
// repr_outside_fn.c

const int values[16] = {-127, -104, -83, -65, -49, -35, -22, -10, 1, 13, 25, 38, 53, 69, 89, 113};

int select_value(unsigned int n) {
    return values[n];
}
```

`clang -S -emit-llvm -O3 repr_outside_fn.c -o repr_outside_fn.ll` generates:

```llvm
; repr_outside_fn.ll

; ModuleID = 'repr_outside_fn.c'
source_filename = "repr_outside_fn.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@values = dso_local local_unnamed_addr constant [16 x i32] [i32 -127, i32 -104, i32 -83, i32 -65, i32 -49, i32 -35, i32 -22, i32 -10, i32 1, i32 13, i32 25, i32 38, i32 53, i32 69, i32 89, i32 113], align 16

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local i32 @select_value(i32 noundef %n) local_unnamed_addr #0 {
entry:
  %idxprom = zext i32 %n to i64
  %arrayidx = getelementptr inbounds [16 x i32], ptr @values, i64 0, i64 %idxprom
  %0 = load i32, ptr %arrayidx, align 4, !tbaa !5
  ret i32 %0
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"PIE Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 2}
!4 = !{!"clang version 19.1.6 (https://github.com/llvm/llvm-project.git e21dc4bd5474d04b8e62d7331362edcc5648d7e5)"}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !7, i64 0}
!7 = !{!"omnipotent char", !8, i64 0}
!8 = !{!"Simple C/C++ TBAA"}
```

`llc -mtriple=spirv64 repr_outside_fn.ll -o repr_outside_fn.spt` generates:

```
; repr_outside_fn.spt

 OpCapability Kernel
        OpCapability Addresses
        OpCapability Linkage
        OpCapability Int64
        %1 = OpExtInstImport "OpenCL.std"
        OpMemoryModel Physical64 OpenCL
        OpSource OpenCL_CPP 100000
        OpName %28 "n"
        OpName %29 "select_value"
        OpName %26 "values"
        OpName %30 "idxprom"
        OpDecorate %29 LinkageAttributes "select_value" Export
        OpDecorate %26 Constant
        OpDecorate %26 Alignment 16
        %2 = OpTypeInt 32 0
        %3 = OpTypeFunction %2 %2
 %4 = OpTypeInt 64 0
        %5 = OpConstant %2 16
        %6 = OpTypeArray %2 %5
        %7 = OpConstant %2 4294967169
        %8 = OpConstant %2 4294967192
        %9 = OpConstant %2 4294967213
        %10 = OpConstant %2 4294967231
        %11 = OpConstant %2 4294967247
        %12 = OpConstant %2 4294967261
        %13 = OpConstant %2 4294967274
        %14 = OpConstant %2 4294967286
        %15 = OpConstant %2 1
        %16 = OpConstant %2 13
        %17 = OpConstant %2 25
        %18 = OpConstant %2 38
        %19 = OpConstant %2 53
        %20 = OpConstant %2 69
 %21 = OpConstant %2 89
        %22 = OpConstant %2 113
        %23 = OpConstantComposite %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 %17 %18 %19 %20 %21 %22
        %24 = OpConstantNull %4
        %25 = OpTypePointer Function %6         ;;; Function storage class outside of function
 %26 = OpVariable %25 Function %23       ;;; Function storage class outside of function
        %27 = OpTypePointer Function %2         ;;; Function storage class outside of function
        %29 = OpFunction %2 Pure %3 ; -- Begin function select_value
        %28 = OpFunctionParameter %2
 %33 = OpLabel
        %30 = OpUConvert %4 %28
        %31 = OpInBoundsPtrAccessChain %27 %26 %24 %30
        %32 = OpLoad %2 %31 Aligned 4
        OpReturnValue %32
        OpFunctionEnd
 ; -- End function
```

The instructions `%25`, `%26` and `%27` have Function storage class despite not being in a function.

Used LLVM 19.1.6 and x86_64 (see repr_outside_fn.ll for details).
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysWN1u47gOfhr1RnBg07-5yEWSTg-K09kpdmbntlBsJtGOLBuS3Kb79AeSbCd20i4OdoPApqyPFMUfkTbTmh8k4oqkG5Le37HOHBu1-rOSv-52TfW--nFE-v358ffgJ92x8hfKirad0ZTRg2h2TNBXpjjbCaSdrFBRc0T60MnS8EZSbRrFDkh1y0pckHBNwvU3xQ9cMkF106kSSbz2z0kW-n9pB_BA4IEqbNVL0xnNK3zZy0XpoWUjtaFcGvrKRIeapJsoI-k9JfE9JfkmiCAnsKVBFCbuXsTulqXulizdLfYjgB5qb5G7ODS46biw19Q9yRxf4a5RFJP8nsQbr5HVRaPA0rw4lQgUnXSWrZyeksDSakbCNaWUKjSdkmftJUkHWfn9pS1G05SCyQMNvtMAa24CIV5rGnyLry1Eg-bqoRAkC-kBJSpmUF-b3Iqz43hzi9dj4w392lSdwMfezpBfuwdyEq69Y1_2XKBkNfZouIEGEq4NUwc0tGKGCfbedGbAY1CTeI1BC3lI4nUM7mKH0XRoqSxxl4CPRAQFidcRFMG-CHtKukfZwJ4lwXcLu9TDKN6KUedTkb1kSdDJX7J5k4HgsjsFB9l5FvtPQu9Fx1Hp5kU0JRPUXV86aQ1QvbCqUtRFLZOGunClJ8pjcEGbbngMdAhaT_vAdbQPXkf6AHakD2JHxuenPph7EQMZjcQoCUYWH-CWSsfZbJRdjJQN-PTejpjgB0mj7BwXY76vjVE2vGjdadOq5qBQayqbvUKkslFYdkpbSr_Lksqmk29cVvSNC9GnRI11o94JFLKRaJOmezP2dCHhusI9l3hhY6sWScJZ3tmnVnKFe0ogdZl3wxsE4rDPSJRGvfukoJaFV6dWNbXz6F94Mn4hSCU1DbUB1uOYUuydVycHPKBBgTVK0xpFudxZFfTM19Z8dnqMGmfdLKHhQJyXH1YJnXjRsMoJGSSclz_7xMUMgcjsGLP31MlQOO4gPJ8w4ZoZo_iuMzZ2nTH84fnv-84mUs1lIPDARPCKpWlU8MYrc7RpFN8TgJCAVRBkExjF2pbLQ1CzC4BR1rkOow0rfwWtaoyXtOv2e1SB5n_hCC96rE_qoGy7cepUZEGWTOf3yEynrDt6EIFNWTevBLaWOhWe2J-08lRdnzyhNY4EeOpU5IP0TuJkbXcE89JND24gENnjd1G7w3WxF-yg--MnsvEJPpEJRFF_h_4e9zJ6AbxCaaacyeUq4cXceCzYIcBbeWTqZbBgn_HJKD6acRZnzufHLX3CVxQXjDAywowxv2T88glj_DHjcCDcYkum2ycAvm6-otL2fIqWi2iRUQLF0ZjWFULXaBy4OXa7RdnUBB5cMfQ3G2V_YmkWB24oQlSVya5KkzypwmRXYAZVHsdRnAFWZZlmSVHlmBJYWuUGndKpTlm_k-yc-gMyu9KeS9Pvk0CUX3PkVxxNLXnbGBsJ1qdn7uKau7ji_s5rW_y2BB5sJBPY0B-b9fq8nau-RIiSBrUvmiS-1y1Xr1lyo4u41Zfo1vxNY_JBU2IZHZB-a7esZTsuuHmn_0UlUfQ9lv1NZtdVZY801B8Bnrj8xQ740fSjNP3Z738EUp8Y39ovJ_MotXms20YZm_nfWpTbp4U2le8UzgK_ukPya1OhoM_Hd81LJrKEeoYJ8rtro_qZl-3zM41C-5uAfnMNFqRQuONzvto4vXQn56RSfoC06QFDdbqNscUCYKhTM9A9lo31Zr9sb9T1ZbGZK0K_nKzhPhaT0W3fPH2GWdsiaCuwb04u_AS9n368t_goDY2BhlNEfIEY2xnPCanbIIE0mYlx2TQRk_aI7djrWRFzdbILOWtbxceV0ikwvykugWWyzPIoW07RxafoJUzRy8_QtrhMIz38FB5HM3j0KTzJZ3D4FJ7NpcefwvN5liafwouZd6IPnDhDZbdRc7vddiHMHB3d9l1czGC3nZbOFoXbzvLxYsnb3ilm8QS3vRLN9whzd2ybum0094mZ9YHs4tOFnY8mHyTe996l3lPeAd7A3n7ePH73fnN-C1bDmSZzT__WCeEyd4ZLLzLwueHSoKKXaZ_RER1v_P_6q0YpmNa0L0u02dN9jxjMPITIz-ETiV96cr7E_3Cdi03lf7Mp-MebulhsiMTpAs-dwuE43dAgoBs8cDnKmH4jmQosZgKfmWI12j1cnMDxEGpPbDep9H1VcnN_bBv5iq4Qp4mXPUMO8f8oN-417dmodVmi1tsj43IwZl8MXVRZ8TMhQ3Y82Vez4QCPI1-GsKLJpFb97t6RftqNe-7J7LDpL7JyO_XG-yKrS_PPuq8fR6RcaqM6B9DUztgAc_ftMMxsi8VkNYxzOz6y1xuf6bzvK9StzV3ZGLpDLg-US8pGRfrPeH9orOjT08-vQ1Ntl_CfS2x_rRFvNYH7RtEKDeNCE1gu7qpVXC3jJbvDVZTH6TIs8jy9O66WuzypgMUFRHm8z2GfJ_sc8qiIqyRNGd7xFYSQhlEYR3bL6SLM0x0UOcM0hBDLJUlCrBkXC_du1KjDHde6w1UEUZpld8LGj3ZfPQEkvlE3a3uZ9P5OrVzzv-sOmiSh4NrosxjDjcDVf2YfP9-4OX5k0KG_rejuffYt9a5TYvX_vYsQeHC6agIP_WZeV_C_AAAA__8MfwVS">