154 changes: 132 additions & 22 deletions mlir/test/Dialect/LLVMIR/mem2reg.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -856,28 +856,6 @@ llvm.func @stores_with_different_types(%arg0: i64, %arg1: f64, %cond: i1) -> f64

// -----

// Verifies that stores with smaller bitsize inputs are not replaced. A trivial
// implementation will be incorrect due to endianness considerations.

// CHECK-LABEL: @stores_with_different_type_sizes
llvm.func @stores_with_different_type_sizes(%arg0: i64, %arg1: f32, %cond: i1) -> f64 {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK: llvm.alloca
%1 = llvm.alloca %0 x i64 {alignment = 4 : i64} : (i32) -> !llvm.ptr
llvm.cond_br %cond, ^bb1, ^bb2
^bb1:
llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr
llvm.br ^bb3
^bb2:
llvm.store %arg1, %1 {alignment = 4 : i64} : f32, !llvm.ptr
llvm.br ^bb3
^bb3:
%2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f64
llvm.return %2 : f64
}

// -----

// CHECK-LABEL: @load_smaller_int
llvm.func @load_smaller_int() -> i16 {
%0 = llvm.mlir.constant(1 : i32) : i32
Expand Down Expand Up @@ -1047,3 +1025,135 @@ llvm.func @scalable_llvm_vector() -> i16 {
%2 = llvm.load %1 : !llvm.ptr -> i16
llvm.return %2 : i16
}

// -----

// CHECK-LABEL: @smaller_store_forwarding
// CHECK-SAME: %[[ARG:.+]]: i16
llvm.func @smaller_store_forwarding(%arg : i16) {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK-NOT: llvm.alloca
// CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i32
%1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr

// CHECK: %[[ZEXT:.+]] = llvm.zext %[[ARG]] : i16 to i32
// CHECK: %[[MASK:.+]] = llvm.mlir.constant(-65536 : i32) : i32
// CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]
// CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]
llvm.store %arg, %1 : i16, !llvm.ptr
llvm.return
}

// -----

module attributes { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.endianness", "big">
>} {
// CHECK-LABEL: @smaller_store_forwarding_big_endian
// CHECK-SAME: %[[ARG:.+]]: i16
llvm.func @smaller_store_forwarding_big_endian(%arg : i16) {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK-NOT: llvm.alloca
// CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i32
%1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr

// CHECK: %[[ZEXT:.+]] = llvm.zext %[[ARG]] : i16 to i32
// CHECK: %[[SHIFT_WIDTH:.+]] = llvm.mlir.constant(16 : i32) : i32
// CHECK: %[[SHIFTED:.+]] = llvm.shl %[[ZEXT]], %[[SHIFT_WIDTH]]
// CHECK: %[[MASK:.+]] = llvm.mlir.constant(65535 : i32) : i32
// CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]
// CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[SHIFTED]]
llvm.store %arg, %1 : i16, !llvm.ptr
llvm.return
}
}

// -----

// CHECK-LABEL: @smaller_store_forwarding_type_mix
// CHECK-SAME: %[[ARG:.+]]: vector<1xi8>
llvm.func @smaller_store_forwarding_type_mix(%arg : vector<1xi8>) {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK-NOT: llvm.alloca
// CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : f32
%1 = llvm.alloca %0 x f32 : (i32) -> !llvm.ptr

// CHECK: %[[CASTED_DEF:.+]] = llvm.bitcast %[[UNDEF]] : f32 to i32
// CHECK: %[[CASTED_ARG:.+]] = llvm.bitcast %[[ARG]] : vector<1xi8> to i8
// CHECK: %[[ZEXT:.+]] = llvm.zext %[[CASTED_ARG]] : i8 to i32
// CHECK: %[[MASK:.+]] = llvm.mlir.constant(-256 : i32) : i32
// CHECK: %[[MASKED:.+]] = llvm.and %[[CASTED_DEF]], %[[MASK]]
// CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]
// CHECK: %[[CASTED_NEW_DEF:.+]] = llvm.bitcast %[[NEW_DEF]] : i32 to f32
llvm.store %arg, %1 : vector<1xi8>, !llvm.ptr
llvm.return
}

// -----

module attributes { dlti.dl_spec = #dlti.dl_spec<
#dlti.dl_entry<"dlti.endianness", "big">
>} {
// CHECK-LABEL: @smaller_store_forwarding_type_mix
// CHECK-SAME: %[[ARG:.+]]: vector<1xi8>
llvm.func @smaller_store_forwarding_type_mix(%arg : vector<1xi8>) {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK-NOT: llvm.alloca
// CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : f32
%1 = llvm.alloca %0 x f32 : (i32) -> !llvm.ptr

// CHECK: %[[CASTED_DEF:.+]] = llvm.bitcast %[[UNDEF]] : f32 to i32
// CHECK: %[[CASTED_ARG:.+]] = llvm.bitcast %[[ARG]] : vector<1xi8> to i8
// CHECK: %[[ZEXT:.+]] = llvm.zext %[[CASTED_ARG]] : i8 to i32
// CHECK: %[[SHIFT_WIDTH:.+]] = llvm.mlir.constant(24 : i32) : i32
// CHECK: %[[SHIFTED:.+]] = llvm.shl %[[ZEXT]], %[[SHIFT_WIDTH]]
// CHECK: %[[MASK:.+]] = llvm.mlir.constant(16777215 : i32) : i32
// CHECK: %[[MASKED:.+]] = llvm.and %[[CASTED_DEF]], %[[MASK]]
// CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[SHIFTED]]
// CHECK: %[[CASTED_NEW_DEF:.+]] = llvm.bitcast %[[NEW_DEF]] : i32 to f32
llvm.store %arg, %1 : vector<1xi8>, !llvm.ptr
llvm.return
}
}

// -----

// CHECK-LABEL: @stores_with_different_types_branches
// CHECK-SAME: %[[ARG0:.+]]: i64
// CHECK-SAME: %[[ARG1:.+]]: f32
llvm.func @stores_with_different_types_branches(%arg0: i64, %arg1: f32, %cond: i1) -> f64 {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK-NOT: llvm.alloca
// CHECK: %[[UNDEF:.+]] = llvm.mlir.undef : i64
%1 = llvm.alloca %0 x i64 {alignment = 4 : i64} : (i32) -> !llvm.ptr
llvm.cond_br %cond, ^bb1, ^bb2
^bb1:
llvm.store %arg0, %1 {alignment = 4 : i64} : i64, !llvm.ptr
// CHECK: llvm.br ^[[BB3:.+]](%[[ARG0]] : i64)
llvm.br ^bb3
^bb2:
llvm.store %arg1, %1 {alignment = 4 : i64} : f32, !llvm.ptr
// CHECK: %[[CAST:.+]] = llvm.bitcast %[[ARG1]] : f32 to i32
// CHECK: %[[ZEXT:.+]] = llvm.zext %[[CAST]] : i32 to i64
// CHECK: %[[MASK:.+]] = llvm.mlir.constant(-4294967296 : i64) : i64
// CHECK: %[[MASKED:.+]] = llvm.and %[[UNDEF]], %[[MASK]]
// CHECK: %[[NEW_DEF:.+]] = llvm.or %[[MASKED]], %[[ZEXT]]
// CHECK: llvm.br ^[[BB3]](%[[NEW_DEF]] : i64)
llvm.br ^bb3
^bb3:
%2 = llvm.load %1 {alignment = 4 : i64} : !llvm.ptr -> f64
llvm.return %2 : f64
}

// -----

// Verifiy that mem2reg does not touch stores with undefined semantics.

// CHECK-LABEL: @store_out_of_bounds
llvm.func @store_out_of_bounds(%arg : i64) {
%0 = llvm.mlir.constant(1 : i32) : i32
// CHECK: llvm.alloca
%1 = llvm.alloca %0 x i32 : (i32) -> !llvm.ptr
llvm.store %arg, %1 : i64, !llvm.ptr
llvm.return
}
43 changes: 43 additions & 0 deletions mlir/test/python/dialects/llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,46 @@ def testSmoke():
)
result = llvm.UndefOp(mat64f32_t)
# CHECK: %0 = llvm.mlir.undef : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)>


# CHECK-LABEL: testPointerType
@constructAndPrintInModule
def testPointerType():
ptr = llvm.PointerType.get()
# CHECK: !llvm.ptr
print(ptr)

ptr_with_addr = llvm.PointerType.get(1)
# CHECK: !llvm.ptr<1>
print(ptr_with_addr)


# CHECK-LABEL: testConstant
@constructAndPrintInModule
def testConstant():
i32 = IntegerType.get_signless(32)
c_128 = llvm.mlir_constant(IntegerAttr.get(i32, 128))
# CHECK: %{{.*}} = llvm.mlir.constant(128 : i32) : i32
print(c_128.owner)


# CHECK-LABEL: testIntrinsics
@constructAndPrintInModule
def testIntrinsics():
i32 = IntegerType.get_signless(32)
ptr = llvm.PointerType.get()
c_128 = llvm.mlir_constant(IntegerAttr.get(i32, 128))
# CHECK: %[[CST128:.*]] = llvm.mlir.constant(128 : i32) : i32
print(c_128.owner)

alloca = llvm.alloca(ptr, c_128, i32)
# CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[CST128]] x i32 : (i32) -> !llvm.ptr
print(alloca.owner)

c_0 = llvm.mlir_constant(IntegerAttr.get(IntegerType.get_signless(8), 0))
# CHECK: %[[CST0:.+]] = llvm.mlir.constant(0 : i8) : i8
print(c_0.owner)

result = llvm.intr_memset(alloca, c_0, c_128, False)
# CHECK: "llvm.intr.memset"(%[[ALLOCA]], %[[CST0]], %[[CST128]]) <{isVolatile = false}> : (!llvm.ptr, i8, i32) -> ()
print(result)
27 changes: 27 additions & 0 deletions utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ cc_binary(
name = "llvm-min-tblgen",
srcs = [
"utils/TableGen/Attributes.cpp",
"utils/TableGen/ARMTargetDefEmitter.cpp",
"utils/TableGen/Basic/CodeGenIntrinsics.cpp",
"utils/TableGen/Basic/CodeGenIntrinsics.h",
"utils/TableGen/Basic/SDNodeProperties.cpp",
Expand Down Expand Up @@ -1231,6 +1232,30 @@ cc_library(
],
)

gentbl(
name = "ARMTargetParserDefGen",
tbl_outs = [("-gen-arm-target-def", "include/llvm/TargetParser/ARMTargetParserDef.inc")],
tblgen = ":llvm-min-tblgen",
td_file = "lib/Target/ARM/ARM.td",
td_srcs = [
":common_target_td_sources",
] + glob([
"lib/Target/ARM/**/*.td",
]),
)

gentbl(
name = "AArch64TargetParserDefGen",
tbl_outs = [("-gen-arm-target-def", "include/llvm/TargetParser/AArch64TargetParserDef.inc")],
tblgen = ":llvm-min-tblgen",
td_file = "lib/Target/AArch64/AArch64.td",
td_srcs = [
":common_target_td_sources",
] + glob([
"lib/Target/AArch64/**/*.td",
]),
)

gentbl(
name = "RISCVTargetParserDefGen",
tbl_outs = [("-gen-riscv-target-def", "include/llvm/TargetParser/RISCVTargetParserDef.inc")],
Expand Down Expand Up @@ -1261,6 +1286,8 @@ cc_library(
copts = llvm_copts,
includes = ["include"],
textual_hdrs = [
"include/llvm/TargetParser/ARMTargetParserDef.inc",
"include/llvm/TargetParser/AArch64TargetParserDef.inc",
"include/llvm/TargetParser/RISCVTargetParserDef.inc",
] + glob([
"include/llvm/TargetParser/*.def",
Expand Down