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

    <tr>
        <th>Summary</th>
        <td>
            [MLIR] mlir-translate emits global struct init on address of
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            mlir
      </td>
    </tr>

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

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

<pre>
    I have tested this on llvm 18 and 19.
For each function where `addressof` is generated for a global variable of struct type, mlir-translate also generates the body of the init region of the struct.

Take this program:
```
struct MyStruct {
        char f0[20];
        int f1;
        int* f2;
};

int x, y;
struct MyStruct global = {"abcdefg", 20, &x};

int foo(struct MyStruct *S) {
    return &global == S;
}

int main() {
    int x = foo(&global);
    struct MyStruct *P = &global;
    return 0;
}
```
emitting LLVM IR with clang produces following code:
```
; ModuleID = 'experiment.c'
source_filename = "experiment.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-solus-linux"

%struct.MyStruct = type { [20 x i8], i32, ptr }

@x = dso_local global i32 0, align 4
@global = dso_local global %struct.MyStruct { [20 x i8] c"abcdefg\00\00\00\00\00\00\00\00\00\00\00\00\00", i32 20, ptr @x }, align 8
@y = dso_local global i32 0, align 4

; Function Attrs: noinline nounwind optnone sspstrong uwtable
define dso_local i32 @foo(ptr noundef %0) #0 {
  %2 = alloca ptr, align 8
  store ptr %0, ptr %2, align 8
  %3 = load ptr, ptr %2, align 8
  %4 = icmp eq ptr @global, %3
  %5 = zext i1 %4 to i32
  ret i32 %5
}

; Function Attrs: noinline nounwind optnone sspstrong uwtable
define dso_local i32 @main() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  %3 = alloca ptr, align 8
  store i32 0, ptr %1, align 4
  %4 = call i32 @foo(ptr noundef @global)
  store i32 %4, ptr %2, align 4
  store ptr @global, ptr %3, align 8
  ret i32 0
}

attributes #0 = { noinline nounwind optnone sspstrong uwtable "frame-pointer"="all" "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, !4}
!llvm.ident = !{!5}

!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 = !{i32 7, !"frame-pointer", i32 2}
!5 = !{!"clang version 18.1.8"}
```
Which is okay.
Loading this into mlir using `mlir-translate -import-llvm` produces following code:
```
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} {
  llvm.mlir.global external @x(0 : i32) {addr_space = 0 : i32, alignment = 4 : i64, dso_local} : i32
  llvm.mlir.global external @global() {addr_space = 0 : i32, alignment = 8 : i64, dso_local} : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> {
    %0 = llvm.mlir.constant(0 : i32) : i32
    %1 = llvm.mlir.addressof @x : !llvm.ptr
    %2 = llvm.mlir.constant(20 : i32) : i32
    %3 = llvm.mlir.constant("abcdefg\00\00\00\00\00\00\00\00\00\00\00\00\00") : !llvm.array<20 x i8>
    %4 = llvm.mlir.undef : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)>
    %5 = llvm.insertvalue %3, %4[0] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %6 = llvm.insertvalue %2, %5[1] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %7 = llvm.insertvalue %1, %6[2] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    llvm.return %7 : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)>
  }
  llvm.mlir.global external @y(0 : i32) {addr_space = 0 : i32, alignment = 4 : i64, dso_local} : i32
  llvm.func @foo(%arg0: !llvm.ptr {llvm.noundef}) -> i32 attributes {frame_pointer = #llvm.framePointerKind<all>, passthrough = ["noinline", "nounwind", "optnone", "sspstrong", ["uwtable", "2"], ["min-legal-vector-width", "0"], ["no-trapping-math", "true"], ["stack-protector-buffer-size", "8"], ["target-cpu", "x86-64"], ["tune-cpu", "generic"]], target_cpu = "x86-64", target_features = #llvm.target_features<["+cmov", "+cx8", "+fxsr", "+mmx", "+sse", "+sse2", "+x87"]>} {
    %0 = llvm.mlir.constant(1 : i32) : i32
 %1 = llvm.mlir.constant(0 : i32) : i32
    %2 = llvm.mlir.addressof @x : !llvm.ptr
    %3 = llvm.mlir.constant(20 : i32) : i32
    %4 = llvm.mlir.constant("abcdefg\00\00\00\00\00\00\00\00\00\00\00\00\00") : !llvm.array<20 x i8>
    %5 = llvm.mlir.undef : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)>
    %6 = llvm.insertvalue %4, %5[0] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %7 = llvm.insertvalue %3, %6[1] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %8 = llvm.insertvalue %2, %7[2] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %9 = llvm.mlir.addressof @global : !llvm.ptr
 %10 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr
    llvm.store %arg0, %10 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr
    %11 = llvm.load %10 {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr
    %12 = llvm.icmp "eq" %9, %11 : !llvm.ptr
    %13 = llvm.zext %12 : i1 to i32
    llvm.return %13 : i32
  }
  llvm.func @main() -> i32 attributes {frame_pointer = #llvm.framePointerKind<all>, passthrough = ["noinline", "nounwind", "optnone", "sspstrong", ["uwtable", "2"], ["min-legal-vector-width", "0"], ["no-trapping-math", "true"], ["stack-protector-buffer-size", "8"], ["target-cpu", "x86-64"], ["tune-cpu", "generic"]], target_cpu = "x86-64", target_features = #llvm.target_features<["+cmov", "+cx8", "+fxsr", "+mmx", "+sse", "+sse2", "+x87"]>} {
    %0 = llvm.mlir.constant(1 : i32) : i32
    %1 = llvm.mlir.constant(0 : i32) : i32
    %2 = llvm.mlir.addressof @x : !llvm.ptr
    %3 = llvm.mlir.constant(20 : i32) : i32
    %4 = llvm.mlir.constant("abcdefg\00\00\00\00\00\00\00\00\00\00\00\00\00") : !llvm.array<20 x i8>
    %5 = llvm.mlir.undef : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)>
    %6 = llvm.insertvalue %4, %5[0] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %7 = llvm.insertvalue %3, %6[1] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %8 = llvm.insertvalue %2, %7[2] : !llvm.struct<"struct.MyStruct", (array<20 x i8>, i32, ptr)> 
    %9 = llvm.mlir.addressof @global : !llvm.ptr
 %10 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr
 %11 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr
 %12 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr
    llvm.store %1, %10 {alignment = 4 : i64} : i32, !llvm.ptr
    %13 = llvm.call @foo(%9) : (!llvm.ptr) -> i32
 llvm.store %13, %11 {alignment = 4 : i64} : i32, !llvm.ptr
    llvm.store %9, %12 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr
    llvm.return %1 : i32
  }
}
```
Both `foo` and `main` have the contents of the init region, even though it serves no purpose there.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWt1u2zoSfhrmhrAhkZIsX_gidhqguy1QnC52LwNGomxuaVKHpBynT7_gj35tJ03T5OwBGgQyTc0MZ4bDmW8kE63ZVlC6AukapDdXpDE7qVb_oN8b9U1e3cvycfUR7siBQkO1oSU0O6ahFJDzwx7GOSSihPFyDqIbEF3fSgUpKXawakRhmBTwYUcVhSCLSFkqqrWsQBZBpuGWCqqIlVhJBQnccnlPODwQxcg9p1BWUBvVFAaax5oCtIF7ztTMKCI0J4ZCwrXspGhodhRadS2jHTPBDFR0a5UIU15eUNVf_0W-UW9SreRWkT3A4Q7IovDvvgZdPj9-9QOwWLdylsWOKFhFIF2jCKQ3APe3mDCwiiczAF3DCvWTiyGLvVquozX5sbsxXT-4C-AbpwpC5L4oabUFCFlGFNkrQNnxvPRKSoDyE6PQ9VeAlr1xEEKoqGmUsLL6Ne2yX0cGTOTvCRMA5SfCnGVOa69BJxWgZSfPEp5R7Yu3tuPAp0pGZ3Qa7yPdM2OY2MJPn_79GX78Az4ws4MFJ2JrQ6BsCqphJTmXD5aqkCW9FBIAr-FnWTacfrwJqi3osaaK7akw8wKgRdg72aiC3lWMU0H2NNCiMS3ytIaoLTWwJIZw8igb01HPbGzSWY0WEcDXGLmL_RqPv9pRlrjLjHWDGOUAX8con1V5FEbCTWUte5bMvlqyiSpGsZp3Sh_z7C5LZlryRs84E82xow9XlIZz1u8dvnGH2IYCdKcEHiHL7VFBG8iwi9jaKDgJJJBEPlZKLe-4LAhvw55hBF2EE862AiYd_eBYnDCd02yqECwGRyndRNGrLv4sWmX9eXQ2OqMWN732eaf944us7YLwtk2218YoDfA1FJIJzgSFQjbigYkSytoIKSjUutZGSbGFzYOxidaLKWllyful7ZogifwptXpbSSWtrBcjd6wRjoZnG6AUOfUJtxKsrScm2mMtFfV-cHI27RidIQYoxU4kl6RsBT5Nnzh6VuxrSP9s_d1mmI2TOKBOHfV3ejSQxZ7dSBeQgUZR4z2B0vRsrntj9w_T6Km_46G_wzEahcjprlykwj-6d10who2Iz8vzG1EQ_lQo9VuzPF3ECjm_4cmZaBrucuDAZ2xoNzQ6u5vEGMXuGwsnvLt9dX3JftocWSmyp7NaMmGoskkA39iswjlA1iy0Z2LG6Zbw2YEWRqrZAyvNriOMApmQFu3UNRPb2Z4MCIxqaKDRhhTfZrWSxku6b6qKqplm32lHngdan89nRd10t455NsuS8f2KEtMoqjsigNbFXh4A2tjRMfeD6qiVH-33Rz_QmnYD5EfHfNFKbwQdre2gGyvc7cmhQrFFl_O9K67zipOtDvUndmAnDugmjsMnCp84fCa9xCCLlVSYsZD0dNloQGHDpJUPEHqwKO-udWxI66N14glz3jN_-biBn-iB8mFJGPKiCe9iyPvhaV58mbdNMhc4k8ucJzF8jj8dOxQg5IHUgSptE2Kcz-O5AxQX0Nh_dqzY2W5AfiOPAZh_kqS00MuhciaMdMAfNtpOgiyatAEztq-lMjO7y7a1eCGI8zEGhyd_sS65YfOS3-maFsFEPJwDeDOYocKoR4A3lQNPG1hSoSnAGwe5PkBbEPw5B3iDjg6SfbD_ztenUvLo9ULaqA-JvBXmuMaykmdlsXgo4me0Yb_EMSx_tR5Z8ow3fsSWbGRK9srdwRuH2D-8fpt8ZW9lWET_asXiiWJnhD6vWPUGHot-iWK_IBwAQm6KipIRIajWIVcChDgzxufeZ9ldGb9zWMX2g0FGjHKnT6_E4mYIAX2R5EzNQ6NAj4YqYVudJDoClEee3UaG68NJWao7XZPCt3OD2wEo7dsimXQLWw-1sNStH1h-RIcWkuUvXj9_cv02HHw75_04ae26bciJUsT6um3y_Gb0Xad78vBh_JjCNie-8-jMK6TQhti9mbh17I8BMO95u2dfofsbmGAVGLKiy8uiZ9fFl5l_dVu7HFlxxsdDvZKJXgH-v81OjlZO-5WZ0FSZA-EN7boD12Ok68h2_m8WWEN9sov6BKlpCtJ1_G76LC7qE6BvmoF0jd5HHye6e9zodHvTCOlQ6TNp7PEdU2nViKLvlgFKidpGk4Rh13fj0Ei7p0lLOLPetBh9DGYdkr8LSL5Fs34te-eLv_FPJkqAN7ZJ9U6ridZmp2Sz3XmmdO16Ut8J91WubYn7mdAb9xNdk9xOOVHj3gQg-4nCM0FPcblP9gzRlOFcx-xJQ8s8on6md_aM-ZRr3EV7oq6NHlMOOl5P17e8ltDTenl3Rd0MHrEGaf3ttikf7d_knj0bbuGuYW_Xbfv2wXffvg8mXBc_-O6a-fF3NJrwrb173zEFJs8V0PhyITtTPV9Seafl8wWV94ni-XzlnVa4_5fKm_5llfdypUsGle79Ku_lSocHle79Km_-LBJYvF_lBShdPnVyutcq546PPbKDwx6eIbsMcJyWrUsovwP2eThkrpidParBDVI5Z7ny6P0VRz-0wujJyKVkEA-SkHv78BPyn7DBShukKve-AiBE__QPS9Nla1L8ZMqKBznLvcVo5V5DFk9eZZzAK8c8ymRTPNRikcFbiN8Y4zfG-NtjjPNN-m-Y8Rtm_IYZf1OY4V4YT4tz8mJ4Man8b7YG-qvgUvwEVjoxJezkj6AP96J_-Nhi2WeQfIS5egwRhE0UxAPo8yoNx3I7RHVmD38KJE7R1EUwdend51qaHQSZc1kWud9RgsxjrSwKP7ncUVhIYagw-szvGq1u9EAFNDsHoZiBmqoD1VBIWDeqltrJUHR-Va5wucRLckVX8QIjHCfREl_tVnGyIChZ5ousRAhnRUYTRKpFUlVZjvH98oqtUISSOEb2L8Z4HmdVQSlelIs8xikuQBLRPWF87jwi1faKad3QVRwvcL684uSecr0KaIsz5Qv6lVpZ-tl9s9UgiTjTRvcSDDPc_Sb186ePf9jcNHnpS_fM6PbnUeGngs4xUsCQUaCsrhrFVztjag3wNUC3AN1umdk19_NC7gG6da-M_YeFaP-lNrndOu01QLfBgMMK_S8AAP__kE72jw">