Issue 117389
Summary [MLIR] mlir-translate emits global struct init on address of
Labels mlir
Assignees
Reporter Jezurko
    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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to