1171 lines · plain
1// RUN: mlir-opt %s --pass-pipeline="builtin.module(llvm.func(mem2reg{region-simplify=false}))" --split-input-file | FileCheck %s2 3// CHECK-LABEL: llvm.func @default_value4llvm.func @default_value() -> i32 {5 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i326 %0 = llvm.mlir.constant(1 : i32) : i327 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr8 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i329 // CHECK: llvm.return %[[UNDEF]] : i3210 llvm.return %2 : i3211}12 13// -----14 15// CHECK-LABEL: llvm.func @store_of_ptr16llvm.func @store_of_ptr() {17 %0 = llvm.mlir.constant(1 : i32) : i3218 %1 = llvm.mlir.constant(4 : i32) : i3219 %2 = llvm.mlir.zero : !llvm.ptr20 // CHECK: %[[ALLOCA:.*]] = llvm.alloca21 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr22 // CHECK: llvm.store %{{.*}}, %[[ALLOCA]]23 llvm.store %1, %3 {alignment = 4 : i64} : i32, !llvm.ptr24 // CHECK: llvm.store %[[ALLOCA]], %{{.*}}25 llvm.store %3, %2 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr26 llvm.return27}28 29// -----30 31// CHECK-LABEL: llvm.func @unreachable32llvm.func @unreachable() {33 %0 = llvm.mlir.constant(1 : i32) : i3234 %1 = llvm.mlir.constant(0 : i32) : i3235 // CHECK-NOT: = llvm.alloca36 %2 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr37 llvm.return38 39// CHECK: ^{{.*}}:40// CHECK-NEXT: llvm.return41^bb1: // no predecessors42 llvm.store %1, %2 {alignment = 4 : i64} : i32, !llvm.ptr43 llvm.return44}45 46// -----47 48// CHECK-LABEL: llvm.func @unreachable_in_loop49// CHECK-NOT: = llvm.alloca50llvm.func @unreachable_in_loop() -> i32 {51 %0 = llvm.mlir.constant(1 : i32) : i3252 %1 = llvm.mlir.constant(6 : i32) : i3253 %2 = llvm.mlir.constant(5 : i32) : i3254 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr55 llvm.store %1, %3 {alignment = 4 : i64} : i32, !llvm.ptr56 // CHECK: llvm.br ^[[LOOP:.*]]57 llvm.br ^bb158 59// CHECK: ^[[LOOP]]:60^bb1: // 2 preds: ^bb0, ^bb361 // CHECK-NEXT: llvm.br ^[[ENDOFLOOP:.*]]62 llvm.store %2, %3 {alignment = 4 : i64} : i32, !llvm.ptr63 llvm.br ^bb364 65// CHECK: ^[[UNREACHABLE:.*]]:66^bb2: // no predecessors67 // CHECK-NEXT: llvm.br ^[[ENDOFLOOP]]68 llvm.br ^bb369 70// CHECK: ^[[ENDOFLOOP]]:71^bb3: // 2 preds: ^bb1, ^bb272 // CHECK-NEXT: llvm.br ^[[LOOP]]73 llvm.br ^bb174}75 76// -----77 78// CHECK-LABEL: llvm.func @branching79// CHECK-NOT: = llvm.alloca80llvm.func @branching(%arg0: i1, %arg1: i1) -> i32 {81 %0 = llvm.mlir.constant(1 : i32) : i3282 %1 = llvm.mlir.constant(2 : i32) : i3283 %2 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr84 // CHECK: llvm.cond_br %{{.*}}, ^[[BB2:.*]](%{{.*}} : i32), ^{{.*}}85 llvm.cond_br %arg0, ^bb2, ^bb186^bb1: // pred: ^bb087 llvm.store %1, %2 {alignment = 4 : i64} : i32, !llvm.ptr88 // CHECK: llvm.cond_br %{{.*}}, ^[[BB2]](%{{.*}} : i32), ^[[BB2]](%{{.*}} : i32)89 llvm.cond_br %arg1, ^bb2, ^bb290// CHECK: ^[[BB2]](%[[V3:.*]]: i32):91^bb2: // 3 preds: ^bb0, ^bb1, ^bb192 %3 = llvm.load %2 {alignment = 4 : i64} : !llvm.ptr -> i3293 // CHECK: llvm.return %[[V3]] : i3294 llvm.return %3 : i3295}96 97// -----98 99// CHECK-LABEL: llvm.func @recursive_alloca100// CHECK-NOT: = llvm.alloca101llvm.func @recursive_alloca() -> i32 {102 %0 = llvm.mlir.constant(1 : i32) : i32103 %1 = llvm.mlir.constant(0 : i32) : i32104 %2 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr105 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr106 %4 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr107 llvm.store %1, %3 {alignment = 4 : i64} : i32, !llvm.ptr108 llvm.store %3, %4 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr109 %5 = llvm.load %4 {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr110 %6 = llvm.load %5 {alignment = 4 : i64} : !llvm.ptr -> i32111 llvm.store %6, %2 {alignment = 4 : i64} : i32, !llvm.ptr112 %7 = llvm.load %2 {alignment = 4 : i64} : !llvm.ptr -> i32113 llvm.return %7 : i32114}115 116// -----117 118// CHECK-LABEL: llvm.func @reset_in_branch119// CHECK-NOT: = llvm.alloca120// CHECK-NOT: ^{{.*}}({{.*}}):121llvm.func @reset_in_branch(%arg0: i32, %arg1: i1) {122 %0 = llvm.mlir.constant(1 : i32) : i32123 %1 = llvm.mlir.constant(true) : i1124 %2 = llvm.mlir.constant(false) : i1125 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr126 llvm.store %arg0, %3 {alignment = 4 : i64} : i32, !llvm.ptr127 llvm.cond_br %arg1, ^bb1, ^bb2128^bb1: // pred: ^bb0129 llvm.store %arg0, %3 {alignment = 4 : i64} : i32, !llvm.ptr130 %4 = llvm.load %3 {alignment = 4 : i64} : !llvm.ptr -> i32131 llvm.call @reset_in_branch(%4, %2) : (i32, i1) -> ()132 llvm.br ^bb3133^bb2: // pred: ^bb0134 %5 = llvm.load %3 {alignment = 4 : i64} : !llvm.ptr -> i32135 llvm.call @reset_in_branch(%5, %1) : (i32, i1) -> ()136 llvm.br ^bb3137^bb3: // 2 preds: ^bb1, ^bb2138 llvm.return139}140 141// -----142 143// CHECK-LABEL: llvm.func @intertwined_alloca144// CHECK-NOT: = llvm.alloca145llvm.func @intertwined_alloca(%arg0: !llvm.ptr, %arg1: i32) {146 %0 = llvm.mlir.constant(1 : i32) : i32147 %1 = llvm.mlir.constant(0 : i32) : i32148 %2 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr149 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr150 %4 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr151 %5 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr152 %6 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr153 llvm.store %arg0, %2 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr154 llvm.store %arg1, %3 {alignment = 4 : i64} : i32, !llvm.ptr155 llvm.store %1, %4 {alignment = 4 : i64} : i32, !llvm.ptr156 llvm.br ^bb1157^bb1: // 2 preds: ^bb0, ^bb4158 %7 = llvm.load %3 {alignment = 4 : i64} : !llvm.ptr -> i32159 %8 = llvm.add %7, %0 : i32160 %9 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32161 %10 = llvm.icmp "sgt" %8, %9 : i32162 %11 = llvm.zext %10 : i1 to i32163 llvm.cond_br %10, ^bb2, ^bb5164^bb2: // pred: ^bb1165 %12 = llvm.load %6 {alignment = 4 : i64} : !llvm.ptr -> i32166 llvm.store %12, %5 {alignment = 4 : i64} : i32, !llvm.ptr167 llvm.store %1, %6 {alignment = 4 : i64} : i32, !llvm.ptr168 %13 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32169 %14 = llvm.icmp "sgt" %13, %1 : i32170 %15 = llvm.zext %14 : i1 to i32171 llvm.cond_br %14, ^bb3, ^bb4172^bb3: // pred: ^bb2173 %16 = llvm.load %2 {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr174 %17 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32175 %18 = llvm.sub %17, %0 : i32176 %19 = llvm.getelementptr %16[%18] : (!llvm.ptr, i32) -> !llvm.ptr, i8177 %20 = llvm.load %5 {alignment = 4 : i64} : !llvm.ptr -> i32178 %21 = llvm.trunc %20 : i32 to i8179 llvm.store %21, %19 {alignment = 1 : i64} : i8, !llvm.ptr180 llvm.br ^bb4181^bb4: // 2 preds: ^bb2, ^bb3182 %22 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32183 %23 = llvm.add %22, %0 : i32184 llvm.store %23, %4 {alignment = 4 : i64} : i32, !llvm.ptr185 llvm.br ^bb1186^bb5: // pred: ^bb1187 llvm.return188}189 190// -----191 192// CHECK-LABEL: llvm.func @complex_cf193// CHECK-NOT: = llvm.alloca194llvm.func @complex_cf(%arg0: i32, ...) {195 %0 = llvm.mlir.constant(1 : i32) : i32196 %1 = llvm.mlir.constant(false) : i1197 %2 = llvm.mlir.constant(0 : i32) : i32198 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr199 llvm.cond_br %1, ^bb1, ^bb2200^bb1: // pred: ^bb0201 llvm.br ^bb2202^bb2: // 2 preds: ^bb0, ^bb1203 llvm.store %2, %3 {alignment = 4 : i64} : i32, !llvm.ptr204 llvm.br ^bb3205^bb3: // 2 preds: ^bb2, ^bb16206 llvm.cond_br %1, ^bb4, ^bb17207^bb4: // pred: ^bb3208 llvm.cond_br %1, ^bb5, ^bb14209^bb5: // pred: ^bb4210 llvm.cond_br %1, ^bb7, ^bb6211^bb6: // pred: ^bb5212 llvm.br ^bb7213^bb7: // 2 preds: ^bb5, ^bb6214 llvm.cond_br %1, ^bb9, ^bb8215^bb8: // pred: ^bb7216 llvm.br ^bb9217^bb9: // 2 preds: ^bb7, ^bb8218 llvm.cond_br %1, ^bb11, ^bb10219^bb10: // pred: ^bb9220 llvm.br ^bb11221^bb11: // 2 preds: ^bb9, ^bb10222 llvm.cond_br %1, ^bb12, ^bb13223^bb12: // pred: ^bb11224 llvm.br ^bb13225^bb13: // 2 preds: ^bb11, ^bb12226 llvm.br ^bb14227^bb14: // 2 preds: ^bb4, ^bb13228 llvm.cond_br %1, ^bb15, ^bb16229^bb15: // pred: ^bb14230 llvm.br ^bb16231^bb16: // 2 preds: ^bb14, ^bb15232 llvm.br ^bb3233^bb17: // pred: ^bb3234 llvm.br ^bb20235^bb18: // no predecessors236 %4 = llvm.load %3 {alignment = 4 : i64} : !llvm.ptr -> i32237 llvm.br ^bb24238^bb19: // no predecessors239 llvm.br ^bb20240^bb20: // 2 preds: ^bb17, ^bb19241 llvm.cond_br %1, ^bb21, ^bb22242^bb21: // pred: ^bb20243 llvm.br ^bb23244^bb22: // pred: ^bb20245 llvm.br ^bb23246^bb23: // 2 preds: ^bb21, ^bb22247 llvm.br ^bb24248^bb24: // 2 preds: ^bb18, ^bb23249 llvm.br ^bb26250^bb25: // no predecessors251 llvm.br ^bb26252^bb26: // 2 preds: ^bb24, ^bb25253 llvm.return254}255 256// -----257 258// CHECK-LABEL: llvm.func @llvm_crash259llvm.func @llvm_crash() -> i32 {260 %0 = llvm.mlir.constant(1 : i32) : i32261 %1 = llvm.mlir.constant(0 : i32) : i32262 %2 = llvm.mlir.addressof @j : !llvm.ptr263 %3 = llvm.mlir.constant(0 : i8) : i8264 // CHECK-NOT: = llvm.alloca265 // CHECK: %[[VOLATILE_ALLOCA:.*]] = llvm.alloca266 // CHECK-NOT: = llvm.alloca267 %4 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr268 %5 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr269 %6 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr270 %7 = llvm.bitcast %1 : i32 to i32271 // CHECK: llvm.store volatile %{{.*}}, %[[VOLATILE_ALLOCA]]272 llvm.store volatile %1, %5 {alignment = 4 : i64} : i32, !llvm.ptr273 %8 = llvm.call @_setjmp(%2) : (!llvm.ptr) -> i32274 %9 = llvm.icmp "ne" %8, %1 : i32275 %10 = llvm.zext %9 : i1 to i8276 %11 = llvm.icmp "ne" %10, %3 : i8277 llvm.cond_br %11, ^bb1, ^bb2278^bb1: // pred: ^bb0279 // CHECK: = llvm.load volatile %[[VOLATILE_ALLOCA]]280 %12 = llvm.load volatile %5 {alignment = 4 : i64} : !llvm.ptr -> i32281 llvm.store %12, %6 {alignment = 4 : i64} : i32, !llvm.ptr282 llvm.br ^bb3283^bb2: // pred: ^bb0284 // CHECK: llvm.store volatile %{{.*}}, %[[VOLATILE_ALLOCA]]285 llvm.store volatile %0, %5 {alignment = 4 : i64} : i32, !llvm.ptr286 llvm.call @g() : () -> ()287 llvm.store %1, %6 {alignment = 4 : i64} : i32, !llvm.ptr288 llvm.br ^bb3289^bb3: // 2 preds: ^bb1, ^bb2290 %13 = llvm.load %6 {alignment = 4 : i64} : !llvm.ptr -> i32291 llvm.store %13, %4 {alignment = 4 : i64} : i32, !llvm.ptr292 llvm.br ^bb4293^bb4: // pred: ^bb3294 %14 = llvm.load %4 {alignment = 4 : i64} : !llvm.ptr -> i32295 llvm.return %14 : i32296}297llvm.mlir.global external @j() {addr_space = 0 : i32} : !llvm.array<1 x struct<"struct.__jmp_buf_tag", (array<6 x i32>, i32, struct<"struct.__sigset_t", (array<32 x i32>)>)>>298llvm.func @_setjmp(!llvm.ptr) -> i32 attributes {passthrough = ["returns_twice"]}299llvm.func @g()300 301// -----302 303// CHECK-LABEL: llvm.func amdgpu_kernelcc @addrspace_discard304// CHECK-NOT: = llvm.alloca305llvm.func amdgpu_kernelcc @addrspace_discard() {306 %0 = llvm.mlir.constant(1 : i32) : i32307 %1 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr<5>308 %2 = llvm.addrspacecast %1 : !llvm.ptr<5> to !llvm.ptr309 llvm.intr.lifetime.start %2 : !llvm.ptr310 llvm.return311}312 313// -----314 315// CHECK-LABEL: llvm.func @ignore_atomic316// CHECK-SAME: (%[[ARG0:.*]]: i32) -> i32317llvm.func @ignore_atomic(%arg0: i32) -> i32 {318 // CHECK-NOT: = llvm.alloca319 %0 = llvm.mlir.constant(1 : i32) : i32320 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr321 llvm.store %arg0, %1 atomic seq_cst {alignment = 4 : i64} : i32, !llvm.ptr322 %2 = llvm.load %1 atomic seq_cst {alignment = 4 : i64} : !llvm.ptr -> i32323 // CHECK: llvm.return %[[ARG0]] : i32324 llvm.return %2 : i32325}326 327// -----328 329// CHECK: llvm.func @landing_pad330// CHECK-NOT: = llvm.alloca331llvm.func @landing_pad() -> i32 attributes {personality = @__gxx_personality_v0} {332 // CHECK-NOT: = llvm.alloca333 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i32334 // CHECK-NOT: = llvm.alloca335 %0 = llvm.mlir.constant(1 : i32) : i32336 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr337 // CHECK: %[[V2:.*]] = llvm.invoke338 %2 = llvm.invoke @landing_padf() to ^bb1 unwind ^bb3 : () -> i32339// CHECK: ^{{.*}}:340^bb1:// pred: ^bb0341 llvm.store %2, %1 {alignment = 4 : i64} : i32, !llvm.ptr342 // CHECK: llvm.br ^[[BB2:.*]](%[[V2]] : i32)343 llvm.br ^bb2344// CHECK: ^[[BB2]]([[V3:.*]]: i32):345^bb2:// 2 preds: ^bb1, ^bb3346 %3 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32347 // CHECK: llvm.return [[V3]] : i32348 llvm.return %3 : i32349// CHECK: ^{{.*}}:350^bb3:// pred: ^bb0351 %4 = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)>352 // CHECK: llvm.br ^[[BB2:.*]](%[[UNDEF]] : i32)353 llvm.br ^bb2354}355llvm.func @landing_padf() -> i32356llvm.func @__gxx_personality_v0(...) -> i32357 358// -----359 360// CHECK-LABEL: llvm.func @unreachable_defines361llvm.func @unreachable_defines() -> i32 {362 // CHECK-NOT: = llvm.alloca363 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i32364 // CHECK-NOT: = llvm.alloca365 %0 = llvm.mlir.constant(1 : i32) : i32366 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr367 llvm.br ^bb1368^bb1: // 2 preds: ^bb0, ^bb2369 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32370 // CHECK: llvm.return %[[UNDEF]] : i32371 llvm.return %2 : i32372^bb2: // no predecessors373 %3 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32374 llvm.store %3, %1 {alignment = 4 : i64} : i32, !llvm.ptr375 llvm.br ^bb1376}377 378// -----379 380// CHECK-LABEL: llvm.func @unreachable_jumps_to_merge_point381// CHECK-NOT: = llvm.alloca382llvm.func @unreachable_jumps_to_merge_point(%arg0: i1) -> i32 {383 %0 = llvm.mlir.constant(1 : i32) : i32384 %1 = llvm.mlir.constant(6 : i32) : i32385 %2 = llvm.mlir.constant(5 : i32) : i32386 %3 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr387 llvm.cond_br %arg0, ^bb1, ^bb2388^bb1: // 2 preds: ^bb0, ^bb4389 llvm.store %1, %3 {alignment = 4 : i64} : i32, !llvm.ptr390 llvm.br ^bb4391^bb2: // pred: ^bb0392 llvm.store %2, %3 {alignment = 4 : i64} : i32, !llvm.ptr393 llvm.br ^bb4394^bb3: // no predecessors395 llvm.br ^bb4396^bb4: // 3 preds: ^bb1, ^bb2, ^bb3397 %4 = llvm.load %3 {alignment = 4 : i64} : !llvm.ptr -> i32398 llvm.return %4 : i32399}400 401// -----402 403// CHECK-LABEL: llvm.func @ignore_lifetime404// CHECK-NOT: = llvm.alloca405llvm.func @ignore_lifetime() {406 %0 = llvm.mlir.constant(1 : i32) : i32407 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr408 llvm.intr.lifetime.start %1 : !llvm.ptr409 llvm.store %0, %1 {alignment = 4 : i64} : i32, !llvm.ptr410 llvm.intr.lifetime.end %1 : !llvm.ptr411 llvm.return412}413 414// -----415 416// CHECK-LABEL: llvm.func @ignore_invariant_group417// CHECK-NOT: llvm.alloca418llvm.func @ignore_invariant_group() {419 %0 = llvm.mlir.constant(1 : i32) : i32420 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr421 %2 = llvm.intr.launder.invariant.group %1 : !llvm.ptr422 %3 = llvm.intr.strip.invariant.group %2 : !llvm.ptr423 llvm.return424}425 426// -----427 428// CHECK-LABEL: llvm.func @ignore_discardable_tree429// CHECK-NOT: = llvm.alloca430llvm.func @ignore_discardable_tree() {431 %0 = llvm.mlir.constant(1 : i32) : i32432 %1 = llvm.mlir.constant(0 : i16) : i16433 %2 = llvm.mlir.constant(0 : i8) : i8434 %3 = llvm.mlir.undef : !llvm.struct<(i8, i16)>435 %4 = llvm.insertvalue %2, %3[0] : !llvm.struct<(i8, i16)>436 %5 = llvm.insertvalue %1, %4[1] : !llvm.struct<(i8, i16)>437 %6 = llvm.alloca %0 x !llvm.struct<(i8, i16)> {alignment = 8 : i64} : (i32) -> !llvm.ptr438 %7 = llvm.getelementptr %6[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<(i8, i16)>439 llvm.intr.lifetime.start %7 : !llvm.ptr440 llvm.store %5, %6 {alignment = 2 : i64} : !llvm.struct<(i8, i16)>, !llvm.ptr441 llvm.intr.lifetime.end %7 : !llvm.ptr442 llvm.return443}444 445// -----446 447// CHECK-LABEL: llvm.func @store_load_forward448llvm.func @store_load_forward() -> i32 {449 // CHECK-NOT: = llvm.alloca450 %0 = llvm.mlir.constant(1 : i32) : i32451 // CHECK: %[[RES:.*]] = llvm.mlir.constant(0 : i32) : i32452 %1 = llvm.mlir.constant(0 : i32) : i32453 %2 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr454 llvm.store %1, %2 {alignment = 4 : i64} : i32, !llvm.ptr455 %3 = llvm.load %2 {alignment = 4 : i64} : !llvm.ptr -> i32456 // CHECK: llvm.return %[[RES]] : i32457 llvm.return %3 : i32458}459 460// -----461 462// CHECK-LABEL: llvm.func @merge_point_cycle463llvm.func @merge_point_cycle() {464 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i32465 %0 = llvm.mlir.constant(1 : i32) : i32466 %1 = llvm.mlir.constant(7 : i32) : i32467 %2 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr468 // CHECK: llvm.br ^[[BB1:.*]](%[[UNDEF]] : i32)469 llvm.br ^bb1470// CHECK: ^[[BB1]](%[[BARG:.*]]: i32):471^bb1: // 2 preds: ^bb0, ^bb1472 %3 = llvm.load %2 {alignment = 4 : i64} : !llvm.ptr -> i32473 // CHECK: = llvm.call @use(%[[BARG]])474 %4 = llvm.call @use(%3) : (i32) -> i1475 // CHECK: %[[DEF:.*]] = llvm.call @def476 %5 = llvm.call @def(%1) : (i32) -> i32477 llvm.store %5, %2 {alignment = 4 : i64} : i32, !llvm.ptr478 // CHECK: llvm.cond_br %{{.*}}, ^[[BB1]](%[[DEF]] : i32), ^{{.*}}479 llvm.cond_br %4, ^bb1, ^bb2480^bb2: // pred: ^bb1481 llvm.return482}483 484llvm.func @def(i32) -> i32485llvm.func @use(i32) -> i1486 487// -----488 489// CHECK-LABEL: llvm.func @no_unnecessary_arguments490llvm.func @no_unnecessary_arguments() {491 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef : i32492 %0 = llvm.mlir.constant(1 : i32) : i32493 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr494 // CHECK: llvm.br ^[[BB1:.*]]495 llvm.br ^bb1496// CHECK: ^[[BB1]]:497^bb1: // 2 preds: ^bb0, ^bb1498 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32499 // CHECK: = llvm.call @use(%[[UNDEF]])500 %3 = llvm.call @use(%2) : (i32) -> i1501 // CHECK: llvm.cond_br %{{.*}}, ^[[BB1]], ^{{.*}}502 llvm.cond_br %3, ^bb1, ^bb2503^bb2: // pred: ^bb1504 llvm.return505}506 507llvm.func @use(i32) -> i1508 509// -----510 511// CHECK-LABEL: llvm.func @discardable_use_tree512// CHECK-NOT: = llvm.alloca513llvm.func @discardable_use_tree() {514 %0 = llvm.mlir.constant(1 : i32) : i32515 %1 = llvm.mlir.constant(2 : i64) : i64516 %2 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr517 %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr518 %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr519 llvm.intr.lifetime.start %3 : !llvm.ptr520 llvm.intr.lifetime.start %4 : !llvm.ptr521 %5 = llvm.intr.invariant.start 2, %3 : !llvm.ptr522 llvm.intr.invariant.end %5, 2, %3 : !llvm.ptr523 llvm.return524}525 526// -----527 528// CHECK-LABEL: llvm.func @non_discardable_use_tree529llvm.func @non_discardable_use_tree() {530 %0 = llvm.mlir.constant(1 : i32) : i32531 %1 = llvm.mlir.constant(2 : i64) : i64532 // CHECK: = llvm.alloca533 %2 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr534 %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr535 %4 = llvm.bitcast %3 : !llvm.ptr to !llvm.ptr536 llvm.intr.lifetime.start %3 : !llvm.ptr537 llvm.intr.lifetime.start %4 : !llvm.ptr538 llvm.call @use(%4) : (!llvm.ptr) -> i1539 llvm.return540}541llvm.func @use(!llvm.ptr) -> i1542 543// -----544 545// CHECK-LABEL: llvm.func @trivial_get_element_ptr546// CHECK-NOT: = llvm.alloca547llvm.func @trivial_get_element_ptr() {548 %0 = llvm.mlir.constant(1 : i32) : i32549 %1 = llvm.mlir.constant(2 : i64) : i64550 %2 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr551 %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr552 %4 = llvm.getelementptr %3[0] : (!llvm.ptr) -> !llvm.ptr, i8553 llvm.intr.lifetime.start %3 : !llvm.ptr554 llvm.intr.lifetime.start %4 : !llvm.ptr555 llvm.return556}557 558// -----559 560// CHECK-LABEL: llvm.func @nontrivial_get_element_ptr561llvm.func @nontrivial_get_element_ptr() {562 %0 = llvm.mlir.constant(1 : i32) : i32563 %1 = llvm.mlir.constant(2 : i64) : i64564 // CHECK: = llvm.alloca565 %2 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr566 %4 = llvm.getelementptr %2[1] : (!llvm.ptr) -> !llvm.ptr, i8567 llvm.intr.lifetime.start %2 : !llvm.ptr568 llvm.intr.lifetime.start %4 : !llvm.ptr569 llvm.return570}571 572// -----573 574// CHECK-LABEL: llvm.func @dynamic_get_element_ptr575llvm.func @dynamic_get_element_ptr() {576 %0 = llvm.mlir.constant(1 : i32) : i32577 %1 = llvm.mlir.constant(2 : i64) : i64578 // CHECK: = llvm.alloca579 %2 = llvm.alloca %0 x i8 {alignment = 8 : i64} : (i32) -> !llvm.ptr580 %3 = llvm.bitcast %2 : !llvm.ptr to !llvm.ptr581 %4 = llvm.getelementptr %3[%0] : (!llvm.ptr, i32) -> !llvm.ptr, i8582 llvm.intr.lifetime.start %3 : !llvm.ptr583 llvm.intr.lifetime.start %4 : !llvm.ptr584 llvm.return585}586 587// -----588 589// CHECK-LABEL: llvm.func @live_cycle590// CHECK-SAME: (%[[ARG0:.*]]: i64, %{{.*}}: i1, %[[ARG2:.*]]: i64) -> i64591llvm.func @live_cycle(%arg0: i64, %arg1: i1, %arg2: i64) -> i64 {592 %0 = llvm.mlir.constant(1 : i32) : i32593 // CHECK-NOT: = llvm.alloca594 %1 = llvm.alloca %0 x i64 {alignment = 8 : i64} : (i32) -> !llvm.ptr595 llvm.store %arg2, %1 {alignment = 4 : i64} : i64, !llvm.ptr596 // CHECK: llvm.cond_br %{{.*}}, ^[[BB1:.*]](%[[ARG2]] : i64), ^[[BB2:.*]](%[[ARG2]] : i64)597 llvm.cond_br %arg1, ^bb1, ^bb2598// CHECK: ^[[BB1]](%[[V1:.*]]: i64):599^bb1:600 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i64601 // CHECK: llvm.call @use(%[[V1]])602 llvm.call @use(%2) : (i64) -> ()603 llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr604 // CHECK: llvm.br ^[[BB2]](%[[ARG0]] : i64)605 llvm.br ^bb2606// CHECK: ^[[BB2]](%[[V2:.*]]: i64):607^bb2:608 // CHECK: llvm.br ^[[BB1]](%[[V2]] : i64)609 llvm.br ^bb1610}611 612llvm.func @use(i64)613 614// -----615 616// This test should no longer be an issue once promotion within subregions617// is supported.618// CHECK-LABEL: llvm.func @subregion_block_promotion619// CHECK-SAME: (%[[ARG0:.*]]: i64, %[[ARG1:.*]]: i64) -> i64620llvm.func @subregion_block_promotion(%arg0: i64, %arg1: i64) -> i64 {621 %0 = llvm.mlir.constant(1 : i32) : i32622 // CHECK: %[[ALLOCA:.*]] = llvm.alloca623 %1 = llvm.alloca %0 x i64 {alignment = 8 : i64} : (i32) -> !llvm.ptr624 // CHECK: llvm.store %[[ARG1]], %[[ALLOCA]]625 llvm.store %arg1, %1 {alignment = 4 : i64} : i64, !llvm.ptr626 // CHECK: scf.execute_region {627 scf.execute_region {628 // CHECK: llvm.store %[[ARG0]], %[[ALLOCA]]629 llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr630 scf.yield631 }632 // CHECK: }633 // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]634 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i64635 // CHECK: llvm.return %[[RES]] : i64636 llvm.return %2 : i64637}638 639// -----640 641// CHECK-LABEL: llvm.func @subregion_simple_transitive_promotion642// CHECK-SAME: (%[[ARG0:.*]]: i64, %[[ARG1:.*]]: i64) -> i64643llvm.func @subregion_simple_transitive_promotion(%arg0: i64, %arg1: i64) -> i64 {644 %0 = llvm.mlir.constant(1 : i32) : i32645 // CHECK-NOT: = llvm.alloca646 %1 = llvm.alloca %0 x i64 {alignment = 8 : i64} : (i32) -> !llvm.ptr647 llvm.store %arg1, %1 {alignment = 4 : i64} : i64, !llvm.ptr648 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i64649 // CHECK: scf.execute_region {650 scf.execute_region {651 // CHECK: llvm.call @use(%[[ARG1]])652 llvm.call @use(%2) : (i64) -> ()653 scf.yield654 }655 // CHECK: }656 // CHECK: llvm.return %[[ARG1]] : i64657 llvm.return %2 : i64658}659 660llvm.func @use(i64)661 662// -----663 664// This behavior is specific to the LLVM dialect, because LLVM semantics are665// that reaching an alloca multiple times allocates on the stack multiple666// times. Promoting an alloca that is reached multiple times could lead to667// changes in observable behavior. Thus only allocas in the entry block are668// promoted.669 670// CHECK-LABEL: llvm.func @no_inner_alloca_promotion671// CHECK-SAME: (%[[ARG:.*]]: i64) -> i64672llvm.func @no_inner_alloca_promotion(%arg: i64) -> i64 {673 %0 = llvm.mlir.constant(1 : i32) : i32674 llvm.br ^bb1675^bb1:676 // CHECK: %[[ALLOCA:.*]] = llvm.alloca677 %1 = llvm.alloca %0 x i64 {alignment = 8 : i64} : (i32) -> !llvm.ptr678 // CHECK: llvm.store %[[ARG]], %[[ALLOCA]]679 llvm.store %arg, %1 {alignment = 4 : i64} : i64, !llvm.ptr680 // CHECK: %[[RES:.*]] = llvm.load %[[ALLOCA]]681 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i64682 // CHECK: llvm.return %[[RES]] : i64683 llvm.return %2 : i64684}685 686// -----687 688// CHECK-LABEL: @transitive_reaching_def689llvm.func @transitive_reaching_def() -> !llvm.ptr {690 %0 = llvm.mlir.constant(1 : i32) : i32691 // CHECK-NOT: alloca692 %1 = llvm.alloca %0 x !llvm.ptr {alignment = 8 : i64} : (i32) -> !llvm.ptr693 %2 = llvm.load %1 {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr694 llvm.store %2, %1 {alignment = 8 : i64} : !llvm.ptr, !llvm.ptr695 %3 = llvm.load %1 {alignment = 8 : i64} : !llvm.ptr -> !llvm.ptr696 llvm.return %3 : !llvm.ptr697}698 699// -----700 701// CHECK-LABEL: @load_int_from_float702llvm.func @load_int_from_float() -> i32 {703 %0 = llvm.mlir.constant(1 : i32) : i32704 // CHECK-NOT: llvm.alloca705 %1 = llvm.alloca %0 x f32 {alignment = 4 : i64} : (i32) -> !llvm.ptr706 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32707 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef708 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[UNDEF]] : f32 to i32709 // CHECK: llvm.return %[[BITCAST:.*]]710 llvm.return %2 : i32711}712 713// -----714 715// CHECK-LABEL: @load_float_from_int716llvm.func @load_float_from_int() -> f32 {717 %0 = llvm.mlir.constant(1 : i32) : i32718 // CHECK-NOT: llvm.alloca719 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr720 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f32721 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef722 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[UNDEF]] : i32 to f32723 // CHECK: llvm.return %[[BITCAST:.*]]724 llvm.return %2 : f32725}726 727// -----728 729// CHECK-LABEL: @load_int_from_vector730llvm.func @load_int_from_vector() -> i32 {731 %0 = llvm.mlir.constant(1 : i32) : i32732 // CHECK-NOT: llvm.alloca733 %1 = llvm.alloca %0 x vector<2xi16> : (i32) -> !llvm.ptr734 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32735 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef736 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[UNDEF]] : vector<2xi16> to i32737 // CHECK: llvm.return %[[BITCAST:.*]]738 llvm.return %2 : i32739}740 741// -----742 743// LLVM arrays cannot be bitcasted, so the following cannot be promoted.744 745// CHECK-LABEL: @load_int_from_array746llvm.func @load_int_from_array() -> i32 {747 %0 = llvm.mlir.constant(1 : i32) : i32748 // CHECK: llvm.alloca749 %1 = llvm.alloca %0 x !llvm.array<2 x i16> : (i32) -> !llvm.ptr750 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32751 // CHECK-NOT: llvm.bitcast752 llvm.return %2 : i32753}754 755// -----756 757// CHECK-LABEL: @store_int_to_float758// CHECK-SAME: %[[ARG:.*]]: i32759llvm.func @store_int_to_float(%arg: i32) -> i32 {760 %0 = llvm.mlir.constant(1 : i32) : i32761 // CHECK-NOT: llvm.alloca762 %1 = llvm.alloca %0 x f32 {alignment = 4 : i64} : (i32) -> !llvm.ptr763 llvm.store %arg, %1 {alignment = 4 : i64} : i32, !llvm.ptr764 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32765 // CHECK: llvm.return %[[ARG]]766 llvm.return %2 : i32767}768 769// -----770 771// CHECK-LABEL: @store_float_to_int772// CHECK-SAME: %[[ARG:.*]]: f32773llvm.func @store_float_to_int(%arg: f32) -> i32 {774 %0 = llvm.mlir.constant(1 : i32) : i32775 // CHECK-NOT: llvm.alloca776 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr777 llvm.store %arg, %1 {alignment = 4 : i64} : f32, !llvm.ptr778 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i32779 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[ARG]] : f32 to i32780 // CHECK: llvm.return %[[BITCAST]]781 llvm.return %2 : i32782}783 784// -----785 786// CHECK-LABEL: @store_int_to_vector787// CHECK-SAME: %[[ARG:.*]]: i32788llvm.func @store_int_to_vector(%arg: i32) -> vector<4xi8> {789 %0 = llvm.mlir.constant(1 : i32) : i32790 // CHECK-NOT: llvm.alloca791 %1 = llvm.alloca %0 x vector<2xi16> {alignment = 4 : i64} : (i32) -> !llvm.ptr792 llvm.store %arg, %1 {alignment = 4 : i64} : i32, !llvm.ptr793 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> vector<4xi8>794 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[ARG]] : i32 to vector<4xi8>795 // CHECK: llvm.return %[[BITCAST]]796 llvm.return %2 : vector<4xi8>797}798 799// -----800 801// CHECK-LABEL: @load_ptr_from_int802llvm.func @load_ptr_from_int() -> !llvm.ptr {803 %0 = llvm.mlir.constant(1 : i32) : i32804 // CHECK-NOT: llvm.alloca805 %1 = llvm.alloca %0 x i64 {alignment = 4 : i64} : (i32) -> !llvm.ptr806 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> !llvm.ptr807 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef808 // CHECK: %[[CAST:.*]] = llvm.inttoptr %[[UNDEF]] : i64 to !llvm.ptr809 // CHECK: llvm.return %[[CAST:.*]]810 llvm.return %2 : !llvm.ptr811}812 813// -----814 815// CHECK-LABEL: @load_int_from_ptr816llvm.func @load_int_from_ptr() -> i64 {817 %0 = llvm.mlir.constant(1 : i32) : i32818 // CHECK-NOT: llvm.alloca819 %1 = llvm.alloca %0 x !llvm.ptr {alignment = 4 : i64} : (i32) -> !llvm.ptr820 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i64821 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef822 // CHECK: %[[CAST:.*]] = llvm.ptrtoint %[[UNDEF]] : !llvm.ptr to i64823 // CHECK: llvm.return %[[CAST:.*]]824 llvm.return %2 : i64825}826 827// -----828 829// CHECK-LABEL: @load_ptr_addrspace_cast830llvm.func @load_ptr_addrspace_cast() -> !llvm.ptr<2> {831 %0 = llvm.mlir.constant(1 : i32) : i32832 // CHECK-NOT: llvm.alloca833 %1 = llvm.alloca %0 x !llvm.ptr<1> {alignment = 4 : i64} : (i32) -> !llvm.ptr834 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> !llvm.ptr<2>835 // CHECK: %[[UNDEF:.*]] = llvm.mlir.undef836 // CHECK: %[[CAST:.*]] = llvm.addrspacecast %[[UNDEF]] : !llvm.ptr<1> to !llvm.ptr<2>837 // CHECK: llvm.return %[[CAST:.*]]838 llvm.return %2 : !llvm.ptr<2>839}840 841// -----842 843// CHECK-LABEL: @stores_with_different_types844// CHECK-SAME: %[[ARG0:.*]]: i64845// CHECK-SAME: %[[ARG1:.*]]: f64846llvm.func @stores_with_different_types(%arg0: i64, %arg1: f64, %cond: i1) -> f64 {847 %0 = llvm.mlir.constant(1 : i32) : i32848 // CHECK-NOT: llvm.alloca849 %1 = llvm.alloca %0 x i64 {alignment = 4 : i64} : (i32) -> !llvm.ptr850 llvm.cond_br %cond, ^bb1, ^bb2851^bb1:852 llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr853 // CHECK: llvm.br ^[[BB3:.*]](%[[ARG0]]854 llvm.br ^bb3855^bb2:856 llvm.store %arg1, %1 {alignment = 4 : i64} : f64, !llvm.ptr857 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[ARG1]] : f64 to i64858 // CHECK: llvm.br ^[[BB3]](%[[BITCAST]]859 llvm.br ^bb3860// CHECK: ^[[BB3]](%[[BLOCK_ARG:.*]]: i64)861^bb3:862 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f64863 // CHECK: %[[BITCAST:.*]] = llvm.bitcast %[[BLOCK_ARG]] : i64 to f64864 // CHECK: llvm.return %[[BITCAST]]865 llvm.return %2 : f64866}867 868// -----869 870// CHECK-LABEL: @load_smaller_int871llvm.func @load_smaller_int() -> i16 {872 %0 = llvm.mlir.constant(1 : i32) : i32873 // CHECK-NOT: llvm.alloca874 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr875 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> i16876 llvm.return %2 : i16877}878 879// -----880 881// CHECK-LABEL: @load_different_type_same_size882llvm.func @load_different_type_same_size() -> f32 {883 %0 = llvm.mlir.constant(1 : i32) : i32884 // CHECK-NOT: llvm.alloca885 %1 = llvm.alloca %0 x i64 {alignment = 8 : i64} : (i32) -> !llvm.ptr886 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f32887 llvm.return %2 : f32888}889 890// -----891 892// This alloca is too small for the load, still, mem2reg should not touch it.893 894// CHECK-LABEL: @impossible_load895llvm.func @impossible_load() -> f64 {896 %0 = llvm.mlir.constant(1 : i32) : i32897 // CHECK: llvm.alloca898 %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i32) -> !llvm.ptr899 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f64900 llvm.return %2 : f64901}902 903// -----904 905// Verifies that mem2reg does not introduce address space casts of pointers906// with different bitsize.907 908module attributes { dlti.dl_spec = #dlti.dl_spec<909 #dlti.dl_entry<!llvm.ptr<1>, dense<[32, 64, 64]> : vector<3xi64>>,910 #dlti.dl_entry<!llvm.ptr<2>, dense<[64, 64, 64]> : vector<3xi64>>911>} {912 913 // CHECK-LABEL: @load_ptr_addrspace_cast_different_size914 llvm.func @load_ptr_addrspace_cast_different_size() -> !llvm.ptr<2> {915 %0 = llvm.mlir.constant(1 : i32) : i32916 // CHECK: llvm.alloca917 %1 = llvm.alloca %0 x !llvm.ptr<1> {alignment = 4 : i64} : (i32) -> !llvm.ptr918 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> !llvm.ptr<2>919 llvm.return %2 : !llvm.ptr<2>920 }921 922 // CHECK-LABEL: @load_ptr_addrspace_cast_different_size2923 llvm.func @load_ptr_addrspace_cast_different_size2() -> !llvm.ptr<1> {924 %0 = llvm.mlir.constant(1 : i32) : i32925 // CHECK: llvm.alloca926 %1 = llvm.alloca %0 x !llvm.ptr<2> {alignment = 4 : i64} : (i32) -> !llvm.ptr927 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> !llvm.ptr<1>928 llvm.return %2 : !llvm.ptr<1>929 }930}931 932// -----933 934// CHECK-LABEL: @load_smaller_int_type935llvm.func @load_smaller_int_type() -> i32 {936 %0 = llvm.mlir.constant(1 : i32) : i32937 // CHECK-NOT: llvm.alloca938 %1 = llvm.alloca %0 x i64 : (i32) -> !llvm.ptr939 %2 = llvm.load %1 : !llvm.ptr -> i32940 // CHECK: %[[RES:.*]] = llvm.trunc %{{.*}} : i64 to i32941 // CHECK: llvm.return %[[RES]] : i32942 llvm.return %2 : i32943}944 945// -----946 947module attributes { dlti.dl_spec = #dlti.dl_spec<948 #dlti.dl_entry<"dlti.endianness", "big">949>} {950 // CHECK-LABEL: @load_smaller_int_type_big_endian951 llvm.func @load_smaller_int_type_big_endian() -> i8 {952 %0 = llvm.mlir.constant(1 : i32) : i32953 // CHECK-NOT: llvm.alloca954 %1 = llvm.alloca %0 x i64 : (i32) -> !llvm.ptr955 %2 = llvm.load %1 : !llvm.ptr -> i8956 // CHECK: %[[SHIFT_WIDTH:.*]] = llvm.mlir.constant(56 : i64) : i64957 // CHECK: %[[SHIFT:.*]] = llvm.lshr %{{.*}}, %[[SHIFT_WIDTH]]958 // CHECK: %[[RES:.*]] = llvm.trunc %[[SHIFT]] : i64 to i8959 // CHECK: llvm.return %[[RES]] : i8960 llvm.return %2 : i8961 }962}963 964// -----965 966// CHECK-LABEL: @load_different_type_smaller967llvm.func @load_different_type_smaller() -> f32 {968 %0 = llvm.mlir.constant(1 : i32) : i32969 // CHECK-NOT: llvm.alloca970 %1 = llvm.alloca %0 x i64 : (i32) -> !llvm.ptr971 %2 = llvm.load %1 : !llvm.ptr -> f32972 // CHECK: %[[TRUNC:.*]] = llvm.trunc %{{.*}} : i64 to i32973 // CHECK: %[[RES:.*]] = llvm.bitcast %[[TRUNC]] : i32 to f32974 // CHECK: llvm.return %[[RES]] : f32975 llvm.return %2 : f32976}977 978// -----979 980// CHECK-LABEL: @load_smaller_float_type981llvm.func @load_smaller_float_type() -> f32 {982 %0 = llvm.mlir.constant(1 : i32) : i32983 // CHECK-NOT: llvm.alloca984 %1 = llvm.alloca %0 x f64 : (i32) -> !llvm.ptr985 %2 = llvm.load %1 : !llvm.ptr -> f32986 // CHECK: %[[CAST:.*]] = llvm.bitcast %{{.*}} : f64 to i64987 // CHECK: %[[TRUNC:.*]] = llvm.trunc %[[CAST]] : i64 to i32988 // CHECK: %[[RES:.*]] = llvm.bitcast %[[TRUNC]] : i32 to f32989 // CHECK: llvm.return %[[RES]] : f32990 llvm.return %2 : f32991}992 993// -----994 995// CHECK-LABEL: @load_first_vector_elem996llvm.func @load_first_vector_elem() -> i16 {997 %0 = llvm.mlir.constant(1 : i32) : i32998 // CHECK-NOT: llvm.alloca999 %1 = llvm.alloca %0 x vector<4xi16> : (i32) -> !llvm.ptr1000 %2 = llvm.load %1 : !llvm.ptr -> i161001 // CHECK: %[[TRUNC:.*]] = llvm.bitcast %{{.*}} : vector<4xi16> to i641002 // CHECK: %[[RES:.*]] = llvm.trunc %[[TRUNC]] : i64 to i161003 // CHECK: llvm.return %[[RES]] : i161004 llvm.return %2 : i161005}1006 1007// -----1008 1009// CHECK-LABEL: @load_first_llvm_vector_elem1010llvm.func @load_first_llvm_vector_elem() -> i16 {1011 %0 = llvm.mlir.constant(1 : i32) : i321012 // CHECK: llvm.alloca1013 %1 = llvm.alloca %0 x vector<4x!llvm.ptr> : (i32) -> !llvm.ptr1014 %2 = llvm.load %1 : !llvm.ptr -> i161015 llvm.return %2 : i161016}1017 1018// -----1019 1020// CHECK-LABEL: @scalable_vector1021llvm.func @scalable_vector() -> i16 {1022 %0 = llvm.mlir.constant(1 : i32) : i321023 // CHECK: llvm.alloca1024 %1 = llvm.alloca %0 x vector<[4]xi16> : (i32) -> !llvm.ptr1025 %2 = llvm.load %1 : !llvm.ptr -> i161026 llvm.return %2 : i161027}1028 1029// -----1030 1031// CHECK-LABEL: @scalable_llvm_vector1032llvm.func @scalable_llvm_vector() -> i16 {1033 %0 = llvm.mlir.constant(1 : i32) : i321034 // CHECK: llvm.alloca1035 %1 = llvm.alloca %0 x vector<[4] x !llvm.ppc_fp128> : (i32) -> !llvm.ptr1036 %2 = llvm.load %1 : !llvm.ptr -> i161037 llvm.return %2 : i161038}1039 1040// -----1041 1042// CHECK-LABEL: @smaller_store_forwarding1043// CHECK-SAME: %[[ARG:.+]]: i161044llvm.func @smaller_store_forwarding(%arg : i16) {1045 %0 = llvm.mlir.constant(1 : i32) : i321046 // CHECK-NOT: llvm.alloca1047 // CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i321048 %1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr1049 1050 // CHECK: %[[ZEXT:.+]] = llvm.zext %[[ARG]] : i16 to i321051 // CHECK: %[[MASK:.+]] = llvm.mlir.constant(-65536 : i32) : i321052 // CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]1053 // CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]1054 llvm.store %arg, %1 : i16, !llvm.ptr1055 llvm.return1056}1057 1058// -----1059 1060module attributes { dlti.dl_spec = #dlti.dl_spec<1061 #dlti.dl_entry<"dlti.endianness", "big">1062>} {1063 // CHECK-LABEL: @smaller_store_forwarding_big_endian1064 // CHECK-SAME: %[[ARG:.+]]: i161065 llvm.func @smaller_store_forwarding_big_endian(%arg : i16) {1066 %0 = llvm.mlir.constant(1 : i32) : i321067 // CHECK-NOT: llvm.alloca1068 // CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i321069 %1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr1070 1071 // CHECK: %[[ZEXT:.+]] = llvm.zext %[[ARG]] : i16 to i321072 // CHECK: %[[SHIFT_WIDTH:.+]] = llvm.mlir.constant(16 : i32) : i321073 // CHECK: %[[SHIFTED:.+]] = llvm.shl %[[ZEXT]], %[[SHIFT_WIDTH]]1074 // CHECK: %[[MASK:.+]] = llvm.mlir.constant(65535 : i32) : i321075 // CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]1076 // CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[SHIFTED]]1077 llvm.store %arg, %1 : i16, !llvm.ptr1078 llvm.return1079 }1080}1081 1082// -----1083 1084// CHECK-LABEL: @smaller_store_forwarding_type_mix1085// CHECK-SAME: %[[ARG:.+]]: vector<1xi8>1086llvm.func @smaller_store_forwarding_type_mix(%arg : vector<1xi8>) {1087 %0 = llvm.mlir.constant(1 : i32) : i321088 // CHECK-NOT: llvm.alloca1089 // CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : f321090 %1 = llvm.alloca %0 x f32 : (i32) -> !llvm.ptr1091 1092 // CHECK: %[[CASTED_DEF:.+]] = llvm.bitcast %[[UNDEF]] : f32 to i321093 // CHECK: %[[CASTED_ARG:.+]] = llvm.bitcast %[[ARG]] : vector<1xi8> to i81094 // CHECK: %[[ZEXT:.+]] = llvm.zext %[[CASTED_ARG]] : i8 to i321095 // CHECK: %[[MASK:.+]] = llvm.mlir.constant(-256 : i32) : i321096 // CHECK: %[[MASKED:.+]] = llvm.and %[[CASTED_DEF]], %[[MASK]]1097 // CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]1098 // CHECK: %[[CASTED_NEW_DEF:.+]] = llvm.bitcast %[[NEW_DEF]] : i32 to f321099 llvm.store %arg, %1 : vector<1xi8>, !llvm.ptr1100 llvm.return1101}1102 1103// -----1104 1105module attributes { dlti.dl_spec = #dlti.dl_spec<1106 #dlti.dl_entry<"dlti.endianness", "big">1107>} {1108 // CHECK-LABEL: @smaller_store_forwarding_type_mix1109 // CHECK-SAME: %[[ARG:.+]]: vector<1xi8>1110 llvm.func @smaller_store_forwarding_type_mix(%arg : vector<1xi8>) {1111 %0 = llvm.mlir.constant(1 : i32) : i321112 // CHECK-NOT: llvm.alloca1113 // CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : f321114 %1 = llvm.alloca %0 x f32 : (i32) -> !llvm.ptr1115 1116 // CHECK: %[[CASTED_DEF:.+]] = llvm.bitcast %[[UNDEF]] : f32 to i321117 // CHECK: %[[CASTED_ARG:.+]] = llvm.bitcast %[[ARG]] : vector<1xi8> to i81118 // CHECK: %[[ZEXT:.+]] = llvm.zext %[[CASTED_ARG]] : i8 to i321119 // CHECK: %[[SHIFT_WIDTH:.+]] = llvm.mlir.constant(24 : i32) : i321120 // CHECK: %[[SHIFTED:.+]] = llvm.shl %[[ZEXT]], %[[SHIFT_WIDTH]]1121 // CHECK: %[[MASK:.+]] = llvm.mlir.constant(16777215 : i32) : i321122 // CHECK: %[[MASKED:.+]] = llvm.and %[[CASTED_DEF]], %[[MASK]]1123 // CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[SHIFTED]]1124 // CHECK: %[[CASTED_NEW_DEF:.+]] = llvm.bitcast %[[NEW_DEF]] : i32 to f321125 llvm.store %arg, %1 : vector<1xi8>, !llvm.ptr1126 llvm.return1127 }1128}1129 1130// -----1131 1132// CHECK-LABEL: @stores_with_different_types_branches1133// CHECK-SAME: %[[ARG0:.+]]: i641134// CHECK-SAME: %[[ARG1:.+]]: f321135llvm.func @stores_with_different_types_branches(%arg0: i64, %arg1: f32, %cond: i1) -> f64 {1136 %0 = llvm.mlir.constant(1 : i32) : i321137 // CHECK-NOT: llvm.alloca1138 // CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i641139 %1 = llvm.alloca %0 x i64 {alignment = 4 : i64} : (i32) -> !llvm.ptr1140 llvm.cond_br %cond, ^bb1, ^bb21141^bb1:1142 llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr1143 // CHECK: llvm.br ^[[BB3:.+]](%[[ARG0]] : i64)1144 llvm.br ^bb31145^bb2:1146 llvm.store %arg1, %1 {alignment = 4 : i64} : f32, !llvm.ptr1147 // CHECK: %[[CAST:.+]] = llvm.bitcast %[[ARG1]] : f32 to i321148 // CHECK: %[[ZEXT:.+]] = llvm.zext %[[CAST]] : i32 to i641149 // CHECK: %[[MASK:.+]] = llvm.mlir.constant(-4294967296 : i64) : i641150 // CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]1151 // CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]1152 // CHECK: llvm.br ^[[BB3]](%[[NEW_DEF]] : i64)1153 llvm.br ^bb31154^bb3:1155 %2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f641156 llvm.return %2 : f641157}1158 1159// -----1160 1161// Verifiy that mem2reg does not touch stores with undefined semantics.1162 1163// CHECK-LABEL: @store_out_of_bounds1164llvm.func @store_out_of_bounds(%arg : i64) {1165 %0 = llvm.mlir.constant(1 : i32) : i321166 // CHECK: llvm.alloca1167 %1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr1168 llvm.store %arg, %1 : i64, !llvm.ptr1169 llvm.return1170}1171