brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.2 KiB · 1674bbd Raw
451 lines · plain
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(llvm.func(sroa))" --split-input-file | FileCheck %s2 3// CHECK-LABEL: llvm.func @basic_struct4llvm.func @basic_struct() -> i32 {5  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)6  %0 = llvm.mlir.constant(1 : i32) : i327  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i328  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr9  %2 = llvm.getelementptr inbounds %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>10  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]11  %3 = llvm.load %2 : !llvm.ptr -> i3212  // CHECK: llvm.return %[[RES]] : i3213  llvm.return %3 : i3214}15 16// -----17 18// CHECK-LABEL: llvm.func @basic_array19llvm.func @basic_array() -> i32 {20  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)21  %0 = llvm.mlir.constant(1 : i32) : i3222  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i3223  %1 = llvm.alloca %0 x !llvm.array<10 x i32> {alignment = 8 : i64} : (i32) -> !llvm.ptr24  %2 = llvm.getelementptr inbounds %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<10 x i32>25  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]26  %3 = llvm.load %2 : !llvm.ptr -> i3227  // CHECK: llvm.return %[[RES]] : i3228  llvm.return %3 : i3229}30 31// -----32 33// CHECK-LABEL: llvm.func @multi_level_direct34llvm.func @multi_level_direct() -> i32 {35  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)36  %0 = llvm.mlir.constant(1 : i32) : i3237  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i3238  %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.ptr39  %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)>)>40  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]41  %3 = llvm.load %2 : !llvm.ptr -> i3242  // CHECK: llvm.return %[[RES]] : i3243  llvm.return %3 : i3244}45 46// -----47 48// The first application of SROA would generate a GEP with indices [0, 0]. This49// test ensures this GEP is not eliminated during the first application. Even50// though doing it would be correct, it would prevent the second application51// of SROA to eliminate the array. GEPs should be eliminated only when they are52// truly trivial (with indices [0]).53 54// CHECK-LABEL: llvm.func @multi_level_direct_two_applications55llvm.func @multi_level_direct_two_applications() -> i32 {56  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)57  %0 = llvm.mlir.constant(1 : i32) : i3258  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i3259  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, array<10 x i32>, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr60  %2 = llvm.getelementptr inbounds %1[0, 2, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, array<10 x i32>, i8)>61  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]62  %3 = llvm.load %2 : !llvm.ptr -> i3263  // CHECK: llvm.return %[[RES]] : i3264  llvm.return %3 : i3265}66 67// -----68 69// CHECK-LABEL: llvm.func @multi_level_indirect70llvm.func @multi_level_indirect() -> i32 {71  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)72  %0 = llvm.mlir.constant(1 : i32) : i3273  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i3274  %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.ptr75  %2 = llvm.getelementptr inbounds %1[0, 2, 1, 5] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, struct<"bar", (i8, array<10 x array<10 x i32>>, i8)>)>76  %3 = llvm.getelementptr inbounds %2[0, 8] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<10 x i32>77  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]78  %4 = llvm.load %3 : !llvm.ptr -> i3279  // CHECK: llvm.return %[[RES]] : i3280  llvm.return %4 : i3281}82 83// -----84 85// This verifies that a nested GEP's users are checked properly. In this case86// the load goes over the bounds of the memory slot and thus should block the87// splitting of the alloca.88 89// CHECK-LABEL: llvm.func @nested_access_over_slot_bound90llvm.func @nested_access_over_slot_bound() -> i64 {91  %0 = llvm.mlir.constant(1 : i32) : i3292  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<(i32, struct<(93  %1 = llvm.alloca %0 x !llvm.struct<(i32, struct<(array<10 x i32>)>, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr94  // CHECK: %[[GEP0:.*]] = llvm.getelementptr inbounds %[[ALLOCA]]95  %2 = llvm.getelementptr inbounds %1[0, 1, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, struct<(array<10 x i32>)>, i32)>96  // CHECK: %[[GEP1:.*]] = llvm.getelementptr inbounds %[[GEP0]]97  %3 = llvm.getelementptr inbounds %2[0, 9] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<10 x i32>98  // CHECK: %[[RES:.*]] = llvm.load %[[GEP1]]99  %4 = llvm.load %3 : !llvm.ptr -> i64100  // CHECK: llvm.return %[[RES]] : i64101  llvm.return %4 : i64102}103 104// -----105 106// CHECK-LABEL: llvm.func @resolve_alias107// CHECK-SAME: (%[[ARG:.*]]: i32)108llvm.func @resolve_alias(%arg: i32) -> i32 {109  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)110  %0 = llvm.mlir.constant(1 : i32) : i32111  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i32112  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr113  %2 = llvm.getelementptr %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>114  %3 = llvm.getelementptr inbounds %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>115  // CHECK: llvm.store %[[ARG]], %[[ALLOCA]]116  llvm.store %arg, %2 : i32, !llvm.ptr117  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]118  %4 = llvm.load %3 : !llvm.ptr -> i32119  // CHECK: llvm.return %[[RES]] : i32120  llvm.return %4 : i32121}122 123// -----124 125// CHECK-LABEL: llvm.func @no_non_single_support126llvm.func @no_non_single_support() -> i32 {127  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant128  %0 = llvm.mlir.constant(2 : i32) : i32129  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr130  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr131  // CHECK-NOT: = llvm.alloca132  %2 = llvm.getelementptr inbounds %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>133  %3 = llvm.load %2 : !llvm.ptr -> i32134  llvm.return %3 : i32135}136 137// -----138 139// CHECK-LABEL: llvm.func @no_pointer_indexing140llvm.func @no_pointer_indexing() -> i32 {141  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)142  %0 = llvm.mlir.constant(1 : i32) : i32143  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr144  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr145  // CHECK-NOT: = llvm.alloca146  %2 = llvm.getelementptr %1[1, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>147  %3 = llvm.load %2 : !llvm.ptr -> i32148  llvm.return %3 : i32149}150 151// -----152 153// CHECK-LABEL: llvm.func @no_direct_use154llvm.func @no_direct_use() -> i32 {155  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)156  %0 = llvm.mlir.constant(1 : i32) : i32157  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr158  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr159  // CHECK-NOT: = llvm.alloca160  %2 = llvm.getelementptr %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>161  %3 = llvm.load %2 : !llvm.ptr -> i32162  llvm.call @use(%1) : (!llvm.ptr) -> ()163  llvm.return %3 : i32164}165 166llvm.func @use(!llvm.ptr)167 168// -----169 170// CHECK-LABEL: llvm.func @direct_promotable_use_is_fine171llvm.func @direct_promotable_use_is_fine() -> i32 {172  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)173  %0 = llvm.mlir.constant(1 : i32) : i32174  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i32175  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr176  %2 = llvm.getelementptr %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>177  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]178  %3 = llvm.load %2 : !llvm.ptr -> i32179  // This is a direct use of the slot but it can be removed because it implements PromotableOpInterface.180  llvm.intr.lifetime.start %1 : !llvm.ptr181  // CHECK: llvm.return %[[RES]] : i32182  llvm.return %3 : i32183}184 185// -----186 187// CHECK-LABEL: llvm.func @direct_promotable_use_is_fine_on_accessor188llvm.func @direct_promotable_use_is_fine_on_accessor() -> i32 {189  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)190  %0 = llvm.mlir.constant(1 : i32) : i32191  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x i32192  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, f64, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr193  %2 = llvm.getelementptr %1[0, 2] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"foo", (i32, f64, i32)>194  // This does not provide side-effect info but it can be removed because it implements PromotableOpInterface.195  %3 = llvm.intr.invariant.start 2, %2 : !llvm.ptr196  // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]197  %4 = llvm.load %2 : !llvm.ptr -> i32198  // This does not provide side-effect info but it can be removed because it implements PromotableOpInterface.199  llvm.intr.invariant.end %3, 2, %2 : !llvm.ptr200  // CHECK: llvm.return %[[RES]] : i32201  llvm.return %4 : i32202}203 204// -----205 206// CHECK-LABEL: llvm.func @no_dynamic_indexing207// CHECK-SAME: (%[[ARG:.*]]: i32)208llvm.func @no_dynamic_indexing(%arg: i32) -> i32 {209  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)210  %0 = llvm.mlir.constant(1 : i32) : i32211  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.array<10 x i32> {alignment = 8 : i64} : (i32) -> !llvm.ptr212  %1 = llvm.alloca %0 x !llvm.array<10 x i32> {alignment = 8 : i64} : (i32) -> !llvm.ptr213  // CHECK-NOT: = llvm.alloca214  // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA]][0, %[[ARG]]]215  %2 = llvm.getelementptr %1[0, %arg] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.array<10 x i32>216  // CHECK: %[[RES:.*]] = llvm.load %[[GEP]]217  %3 = llvm.load %2 : !llvm.ptr -> i32218  // CHECK: llvm.return %[[RES]] : i32219  llvm.return %3 : i32220}221 222// -----223 224// CHECK-LABEL: llvm.func @no_nested_dynamic_indexing225// CHECK-SAME: (%[[ARG:.*]]: i32)226llvm.func @no_nested_dynamic_indexing(%arg: i32) -> i32 {227  // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32)228  %0 = llvm.mlir.constant(1 : i32) : i32229  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[SIZE]] x !llvm.struct<(array<10 x i32>, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr230  %1 = llvm.alloca %0 x !llvm.struct<(array<10 x i32>, i32)> {alignment = 8 : i64} : (i32) -> !llvm.ptr231  // CHECK-NOT: = llvm.alloca232  // CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA]][0, 0, %[[ARG]]]233  %2 = llvm.getelementptr %1[0, 0, %arg] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(array<10 x i32>, i32)>234  // CHECK: %[[RES:.*]] = llvm.load %[[GEP]]235  %3 = llvm.load %2 : !llvm.ptr -> i32236  // CHECK: llvm.return %[[RES]] : i32237  llvm.return %3 : i32238}239 240// -----241 242// CHECK-LABEL: llvm.func @store_first_field243llvm.func @store_first_field(%arg: i32) {244  %0 = llvm.mlir.constant(1 : i32) : i32245  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32246  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32, i32)> : (i32) -> !llvm.ptr247  // CHECK-NEXT: llvm.store %{{.*}}, %[[ALLOCA]] : i32248  llvm.store %arg, %1 : i32, !llvm.ptr249  llvm.return250}251 252// -----253 254// CHECK-LABEL: llvm.func @store_first_field_different_type255// CHECK-SAME: (%[[ARG:.*]]: f32)256llvm.func @store_first_field_different_type(%arg: f32) {257  %0 = llvm.mlir.constant(1 : i32) : i32258  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32259  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32, i32)> : (i32) -> !llvm.ptr260  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]] : f32261  llvm.store %arg, %1 : f32, !llvm.ptr262  llvm.return263}264 265// -----266 267// CHECK-LABEL: llvm.func @store_sub_field268// CHECK-SAME: (%[[ARG:.*]]: f32)269llvm.func @store_sub_field(%arg: f32) {270  %0 = llvm.mlir.constant(1 : i32) : i32271  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i64272  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i64, i32)> : (i32) -> !llvm.ptr273  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]] : f32274  llvm.store %arg, %1 : f32, !llvm.ptr275  llvm.return276}277 278// -----279 280// CHECK-LABEL: llvm.func @load_first_field281llvm.func @load_first_field() -> i32 {282  %0 = llvm.mlir.constant(1 : i32) : i32283  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32284  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32, i32)> : (i32) -> !llvm.ptr285  // CHECK-NEXT: %[[RES:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr -> i32286  %2 = llvm.load %1 : !llvm.ptr -> i32287  // CHECK: llvm.return %[[RES]] : i32288  llvm.return %2 : i32289}290 291// -----292 293// CHECK-LABEL: llvm.func @load_first_field_different_type294llvm.func @load_first_field_different_type() -> f32 {295  %0 = llvm.mlir.constant(1 : i32) : i32296  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32297  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32, i32)> : (i32) -> !llvm.ptr298  // CHECK-NEXT: %[[RES:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr -> f32299  %2 = llvm.load %1 : !llvm.ptr -> f32300  // CHECK: llvm.return %[[RES]] : f32301  llvm.return %2 : f32302}303 304// -----305 306// CHECK-LABEL: llvm.func @load_sub_field307llvm.func @load_sub_field() -> i32 {308  %0 = llvm.mlir.constant(1 : i32) : i32309  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i64 : (i32) -> !llvm.ptr310  %1 = llvm.alloca %0 x !llvm.struct<(i64, i32)> : (i32) -> !llvm.ptr311  // CHECK-NEXT: %[[RES:.*]] = llvm.load %[[ALLOCA]]312  %res = llvm.load %1 : !llvm.ptr -> i32313  // CHECK: llvm.return %[[RES]] : i32314  llvm.return %res : i32315}316 317// -----318 319// CHECK-LABEL: llvm.func @vector_store_type_mismatch320// CHECK-SAME: %[[ARG:.*]]: vector<4xi32>321llvm.func @vector_store_type_mismatch(%arg: vector<4xi32>) {322  %0 = llvm.mlir.constant(1 : i32) : i32323  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x vector<4xf32>324  %1 = llvm.alloca %0 x !llvm.struct<"foo", (vector<4xf32>)> : (i32) -> !llvm.ptr325  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]]326  llvm.store %arg, %1 : vector<4xi32>, !llvm.ptr327  llvm.return328}329 330// -----331 332// CHECK-LABEL: llvm.func @store_to_memory333// CHECK-SAME: %[[ARG:.*]]: !llvm.ptr334llvm.func @store_to_memory(%arg: !llvm.ptr) {335  %0 = llvm.mlir.constant(1 : i32) : i32336  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<337  %1 = llvm.alloca %0 x !llvm.struct<"foo", (vector<4xf32>)> : (i32) -> !llvm.ptr338  // CHECK-NEXT: llvm.store %[[ALLOCA]], %[[ARG]]339  llvm.store %1, %arg : !llvm.ptr, !llvm.ptr340  llvm.return341}342 343// -----344 345// CHECK-LABEL: llvm.func @type_mismatch_array_access346// CHECK-SAME: %[[ARG:.*]]: i32347llvm.func @type_mismatch_array_access(%arg: i32) {348  %0 = llvm.mlir.constant(1 : i32) : i32349  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32350  %1 = llvm.alloca %0 x !llvm.struct<(i32, i32, i32)> : (i32) -> !llvm.ptr351  %2 = llvm.getelementptr %1[8] : (!llvm.ptr) -> !llvm.ptr, i8352  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]]353  llvm.store %arg, %2 : i32, !llvm.ptr354  llvm.return355}356 357// -----358 359// CHECK-LABEL: llvm.func @type_mismatch_struct_access360// CHECK-SAME: %[[ARG:.*]]: i32361llvm.func @type_mismatch_struct_access(%arg: i32) {362  %0 = llvm.mlir.constant(1 : i32) : i32363  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32364  %1 = llvm.alloca %0 x !llvm.struct<(i32, i32, i32)> : (i32) -> !llvm.ptr365  %2 = llvm.getelementptr %1[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i32, i32)>366  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]]367  llvm.store %arg, %2 : i32, !llvm.ptr368  llvm.return369}370 371// -----372 373// CHECK-LABEL: llvm.func @index_in_final_padding374llvm.func @index_in_final_padding(%arg: i32) {375  %0 = llvm.mlir.constant(1 : i32) : i32376  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<"foo", (i32, i8)>377  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i8)> : (i32) -> !llvm.ptr378  // CHECK: = llvm.getelementptr %[[ALLOCA]][7] : (!llvm.ptr) -> !llvm.ptr, i8379  %2 = llvm.getelementptr %1[7] : (!llvm.ptr) -> !llvm.ptr, i8380  llvm.store %arg, %2 : i32, !llvm.ptr381  llvm.return382}383 384// -----385 386// CHECK-LABEL: llvm.func @index_out_of_bounds387llvm.func @index_out_of_bounds(%arg: i32) {388  %0 = llvm.mlir.constant(1 : i32) : i32389  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<"foo", (i32, i32)>390  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32)> : (i32) -> !llvm.ptr391  // CHECK: = llvm.getelementptr %[[ALLOCA]][9] : (!llvm.ptr) -> !llvm.ptr, i8392  %2 = llvm.getelementptr %1[9] : (!llvm.ptr) -> !llvm.ptr, i8393  llvm.store %arg, %2 : i32, !llvm.ptr394  llvm.return395}396 397// -----398 399// CHECK-LABEL: llvm.func @index_in_padding400llvm.func @index_in_padding(%arg: i16) {401  %0 = llvm.mlir.constant(1 : i32) : i32402  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<"foo", (i16, i32)>403  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i16, i32)> : (i32) -> !llvm.ptr404  // CHECK: = llvm.getelementptr %[[ALLOCA]][2] : (!llvm.ptr) -> !llvm.ptr, i8405  %2 = llvm.getelementptr %1[2] : (!llvm.ptr) -> !llvm.ptr, i8406  llvm.store %arg, %2 : i16, !llvm.ptr407  llvm.return408}409 410// -----411 412// CHECK-LABEL: llvm.func @index_not_in_padding_because_packed413// CHECK-SAME: %[[ARG:.*]]: i16414llvm.func @index_not_in_padding_because_packed(%arg: i16) {415  %0 = llvm.mlir.constant(1 : i32) : i32416  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32417  %1 = llvm.alloca %0 x !llvm.struct<"foo", packed (i16, i32)> : (i32) -> !llvm.ptr418  %2 = llvm.getelementptr %1[2] : (!llvm.ptr) -> !llvm.ptr, i8419  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]]420  llvm.store %arg, %2 : i16, !llvm.ptr421  llvm.return422}423 424// -----425 426// CHECK-LABEL: llvm.func @no_crash_on_negative_gep_index427// CHECK-SAME: %[[ARG:.*]]: f16428llvm.func @no_crash_on_negative_gep_index(%arg: f16) {429  %0 = llvm.mlir.constant(1 : i32) : i32430  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x !llvm.struct<"foo", (i32, i32, i32)>431  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32, i32)> : (i32) -> !llvm.ptr432  // CHECK: llvm.getelementptr %[[ALLOCA]][-1] : (!llvm.ptr) -> !llvm.ptr, f32433  %2 = llvm.getelementptr %1[-1] : (!llvm.ptr) -> !llvm.ptr, f32434  llvm.store %arg, %2 : f16, !llvm.ptr435  llvm.return436}437 438// -----439 440// CHECK-LABEL: llvm.func @out_of_bound_gep_array_access441// CHECK-SAME: %[[ARG:.*]]: i32442llvm.func @out_of_bound_gep_array_access(%arg: i32) {443  %0 = llvm.mlir.constant(1 : i32) : i32444  // CHECK: %[[ALLOCA:.*]] = llvm.alloca %{{.*}} x i32445  %1 = llvm.alloca %0 x !llvm.struct<"foo", (i32, i32)> : (i32) -> !llvm.ptr446  %2 = llvm.getelementptr %1[0, 4] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<4 x i8>447  // CHECK-NEXT: llvm.store %[[ARG]], %[[ALLOCA]]448  llvm.store %arg, %2 : i32, !llvm.ptr449  llvm.return450}451