1// REQUIRES: asserts 2// RUN: mlir-opt %s --pass-pipeline="builtin.module(llvm.func(sroa))" --split-input-file --mlir-pass-statistics 2>&1 >/dev/null | FileCheck %s 3 4// CHECK: SROA 5// CHECK-NEXT: (S) 1 destructured slots 6// CHECK-NEXT: (S) 2 max subelement number 7// CHECK-NEXT: (S) 1 slots with memory benefit 8llvm.func @basic() -> i32 { 9 %0 = llvm.mlir.constant(1 : i32) : i32 10 %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr 11 %2 = llvm.getelementptr inbounds %1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, i32)> 12 %3 = llvm.load %2 : !llvm.ptr -> i32 13 llvm.return %3 : i32 14} 15 16// ----- 17 18// CHECK: SROA 19// CHECK-NEXT: (S) 1 destructured slots 20// CHECK-NEXT: (S) 2 max subelement number 21// CHECK-NEXT: (S) 0 slots with memory benefit 22llvm.func @basic_no_memory_benefit() -> i32 { 23 %0 = llvm.mlir.constant(1 : i32) : i32 24 %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr 25 %2 = llvm.getelementptr inbounds %1[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, i32)> 26 %3 = llvm.getelementptr inbounds %1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, i32)> 27 %4 = llvm.load %2 : !llvm.ptr -> i32 28 %5 = llvm.load %3 : !llvm.ptr -> i32 29 %6 = llvm.add %4, %5 : i32 30 llvm.return %6 : i32 31} 32 33// ----- 34 35// CHECK: SROA 36// CHECK-NEXT: (S) 1 destructured slots 37// CHECK-NEXT: (S) 10 max subelement number 38// CHECK-NEXT: (S) 1 slots with memory benefit 39llvm.func @basic_array() -> i32 { 40 %0 = llvm.mlir.constant(1 : i32) : i32 41 %1 = llvm.alloca %0 x !llvm.array<10 x i32> {alignment = 8 : i64} : (i32) -> !llvm.ptr 42 %2 = llvm.getelementptr inbounds %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<10 x i32> 43 %3 = llvm.load %2 : !llvm.ptr -> i32 44 llvm.return %3 : i32 45} 46 47// ----- 48 49// SROA is applied repeatedly here, peeling off layers of aggregates one after 50// the other, four times. 51 52// CHECK: SROA 53// CHECK-NEXT: (S) 4 destructured slots 54// CHECK-NEXT: (S) 10 max subelement number 55// CHECK-NEXT: (S) 4 slots with memory benefit 56llvm.func @multi_level_direct() -> i32 { 57 %0 = llvm.mlir.constant(1 : i32) : i32 58 %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, struct<"bar", (i8, array<10 x array<10 x i32>>, i8)>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr 59 %2 = llvm.getelementptr inbounds %1[0, 2, 1, 5, 8] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, struct<"bar", (i8, array<10 x array<10 x i32>>, i8)>)> 60 %3 = llvm.load %2 : !llvm.ptr -> i32 61 llvm.return %3 : i32 62} 63