| // RUN: cir-opt %s -cir-to-llvm -o %t.mlir |
| // RUN: FileCheck --input-file=%t.mlir %s |
| |
| !s32i = !cir.int<s, 32> |
| !u8i = !cir.int<u, 8> |
| !u32i = !cir.int<u, 32> |
| !ty_S = !cir.struct<struct "S" {!u8i, !s32i}> |
| !ty_S2A = !cir.struct<struct "S2A" {!s32i} #cir.record.decl.ast> |
| !ty_S1_ = !cir.struct<struct "S1" {!s32i, !cir.float, !cir.ptr<!s32i>} #cir.record.decl.ast> |
| !ty_S2_ = !cir.struct<struct "S2" {!ty_S2A} #cir.record.decl.ast> |
| !ty_S3_ = !cir.struct<struct "S3" {!s32i} #cir.record.decl.ast> |
| |
| module { |
| cir.func @test() { |
| %1 = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["x"] {alignment = 4 : i64} |
| // CHECK: %[[#ARRSIZE:]] = llvm.mlir.constant(1 : index) : i64 |
| // CHECK: %[[#STRUCT:]] = llvm.alloca %[[#ARRSIZE]] x !llvm.struct<"struct.S", (i8, i32)> |
| %3 = cir.get_member %1[0] {name = "c"} : !cir.ptr<!ty_S> -> !cir.ptr<!u8i> |
| // CHECK: = llvm.getelementptr %[[#STRUCT]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.S", (i8, i32)> |
| %5 = cir.get_member %1[1] {name = "i"} : !cir.ptr<!ty_S> -> !cir.ptr<!s32i> |
| // CHECK: = llvm.getelementptr %[[#STRUCT]][0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.S", (i8, i32)> |
| cir.return |
| } |
| |
| cir.func @shouldConstInitLocalStructsWithConstStructAttr() { |
| %0 = cir.alloca !ty_S2A, !cir.ptr<!ty_S2A>, ["s"] {alignment = 4 : i64} |
| %1 = cir.const #cir.const_struct<{#cir.int<1> : !s32i}> : !ty_S2A |
| cir.store %1, %0 : !ty_S2A, !cir.ptr<!ty_S2A> |
| cir.return |
| } |
| // CHECK: llvm.func @shouldConstInitLocalStructsWithConstStructAttr() |
| // CHECK: %0 = llvm.mlir.constant(1 : index) : i64 |
| // CHECK: %1 = llvm.alloca %0 x !llvm.struct<"struct.S2A", (i32)> {alignment = 4 : i64} : (i64) -> !llvm.ptr |
| // CHECK: %2 = llvm.mlir.undef : !llvm.struct<"struct.S2A", (i32)> |
| // CHECK: %3 = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %4 = llvm.insertvalue %3, %2[0] : !llvm.struct<"struct.S2A", (i32)> |
| // CHECK: llvm.store %4, %1 {{.*}}: !llvm.struct<"struct.S2A", (i32)>, !llvm.ptr |
| // CHECK: llvm.return |
| // CHECK: } |
| |
| // Should lower basic #cir.const_struct initializer. |
| cir.global external @s1 = #cir.const_struct<{#cir.int<1> : !s32i, #cir.fp<1.000000e-01> : !cir.float, #cir.ptr<null> : !cir.ptr<!s32i>}> : !ty_S1_ |
| // CHECK: llvm.mlir.global external @s1() {addr_space = 0 : i32} : !llvm.struct<"struct.S1", (i32, f32, ptr)> { |
| // CHECK: %0 = llvm.mlir.undef : !llvm.struct<"struct.S1", (i32, f32, ptr)> |
| // CHECK: %1 = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %2 = llvm.insertvalue %1, %0[0] : !llvm.struct<"struct.S1", (i32, f32, ptr)> |
| // CHECK: %3 = llvm.mlir.constant(0.099999994 : f32) : f32 |
| // CHECK: %4 = llvm.insertvalue %3, %2[1] : !llvm.struct<"struct.S1", (i32, f32, ptr)> |
| // CHECK: %5 = llvm.mlir.zero : !llvm.ptr |
| // CHECK: %6 = llvm.insertvalue %5, %4[2] : !llvm.struct<"struct.S1", (i32, f32, ptr)> |
| // CHECK: llvm.return %6 : !llvm.struct<"struct.S1", (i32, f32, ptr)> |
| // CHECK: } |
| |
| // Should lower nested #cir.const_struct initializer. |
| cir.global external @s2 = #cir.const_struct<{#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_S2A}> : !ty_S2_ |
| // CHECK: llvm.mlir.global external @s2() {addr_space = 0 : i32} : !llvm.struct<"struct.S2", (struct<"struct.S2A", (i32)>)> { |
| // CHECK: %0 = llvm.mlir.undef : !llvm.struct<"struct.S2", (struct<"struct.S2A", (i32)>)> |
| // CHECK: %1 = llvm.mlir.undef : !llvm.struct<"struct.S2A", (i32)> |
| // CHECK: %2 = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %3 = llvm.insertvalue %2, %1[0] : !llvm.struct<"struct.S2A", (i32)> |
| // CHECK: %4 = llvm.insertvalue %3, %0[0] : !llvm.struct<"struct.S2", (struct<"struct.S2A", (i32)>)> |
| // CHECK: llvm.return %4 : !llvm.struct<"struct.S2", (struct<"struct.S2A", (i32)>)> |
| // CHECK: } |
| |
| cir.global external @s3 = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_S3_, #cir.const_struct<{#cir.int<2> : !s32i}> : !ty_S3_, #cir.const_struct<{#cir.int<3> : !s32i}> : !ty_S3_]> : !cir.array<!ty_S3_ x 3> |
| // CHECK: llvm.mlir.global external @s3() {addr_space = 0 : i32} : !llvm.array<3 x struct<"struct.S3", (i32)>> { |
| // CHECK: %0 = llvm.mlir.undef : !llvm.array<3 x struct<"struct.S3", (i32)>> |
| // CHECK: %1 = llvm.mlir.undef : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %2 = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %3 = llvm.insertvalue %2, %1[0] : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %4 = llvm.insertvalue %3, %0[0] : !llvm.array<3 x struct<"struct.S3", (i32)>> |
| // CHECK: %5 = llvm.mlir.undef : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %6 = llvm.mlir.constant(2 : i32) : i32 |
| // CHECK: %7 = llvm.insertvalue %6, %5[0] : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %8 = llvm.insertvalue %7, %4[1] : !llvm.array<3 x struct<"struct.S3", (i32)>> |
| // CHECK: %9 = llvm.mlir.undef : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %10 = llvm.mlir.constant(3 : i32) : i32 |
| // CHECK: %11 = llvm.insertvalue %10, %9[0] : !llvm.struct<"struct.S3", (i32)> |
| // CHECK: %12 = llvm.insertvalue %11, %8[2] : !llvm.array<3 x struct<"struct.S3", (i32)>> |
| // CHECK: llvm.return %12 : !llvm.array<3 x struct<"struct.S3", (i32)>> |
| // CHECK: } |
| |
| cir.func @shouldLowerStructCopies() { |
| // CHECK: llvm.func @shouldLowerStructCopies() |
| %1 = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["a"] {alignment = 4 : i64} |
| // CHECK: %[[#ONE:]] = llvm.mlir.constant(1 : index) : i64 |
| // CHECK: %[[#SA:]] = llvm.alloca %[[#ONE]] x !llvm.struct<"struct.S", (i8, i32)> {alignment = 4 : i64} : (i64) -> !llvm.ptr |
| %2 = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["b", init] {alignment = 4 : i64} |
| // CHECK: %[[#ONE:]] = llvm.mlir.constant(1 : index) : i64 |
| // CHECK: %[[#SB:]] = llvm.alloca %[[#ONE]] x !llvm.struct<"struct.S", (i8, i32)> {alignment = 4 : i64} : (i64) -> !llvm.ptr |
| cir.copy %1 to %2 : !cir.ptr<!ty_S> |
| // CHECK: %[[#SIZE:]] = llvm.mlir.constant(8 : i32) : i32 |
| // CHECK: "llvm.intr.memcpy"(%[[#SB]], %[[#SA]], %[[#SIZE]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i32) -> () |
| cir.return |
| } |
| } |