Adding i32/i64/f32 min/max ops. These cover a large number of ops in common loops and will be easy to lower to native machine instructions.
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/StandardToVM/ConvertStandardToVM.cpp b/compiler/src/iree/compiler/Dialect/VM/Conversion/StandardToVM/ConvertStandardToVM.cpp index a6b46b3..0383473 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/StandardToVM/ConvertStandardToVM.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/StandardToVM/ConvertStandardToVM.cpp
@@ -1107,6 +1107,14 @@ IREE::VM::RemI64SOp>, BinaryArithmeticOpConversion<arith::RemUIOp, IREE::VM::RemI32UOp, IREE::VM::RemI64UOp>, + BinaryArithmeticOpConversion<arith::MinSIOp, IREE::VM::MinI32SOp, + IREE::VM::MinI64SOp>, + BinaryArithmeticOpConversion<arith::MinUIOp, IREE::VM::MinI32UOp, + IREE::VM::MinI64UOp>, + BinaryArithmeticOpConversion<arith::MaxSIOp, IREE::VM::MaxI32SOp, + IREE::VM::MaxI64SOp>, + BinaryArithmeticOpConversion<arith::MaxUIOp, IREE::VM::MaxI32UOp, + IREE::VM::MaxI64UOp>, BinaryArithmeticOpConversion<arith::SubIOp, IREE::VM::SubI32Op, IREE::VM::SubI64Op>, BinaryArithmeticOpConversion<arith::AndIOp, IREE::VM::AndI32Op, @@ -1136,7 +1144,11 @@ BinaryArithmeticOpConversion<arith::RemFOp, IREE::VM::RemF32Op, IREE::VM::RemF64Op>, BinaryArithmeticOpConversion<arith::SubFOp, IREE::VM::SubF32Op, - IREE::VM::SubF64Op>>(typeConverter, + IREE::VM::SubF64Op>, + BinaryArithmeticOpConversion<arith::MinFOp, IREE::VM::MinF32Op, + IREE::VM::MinF64Op>, + BinaryArithmeticOpConversion<arith::MaxFOp, IREE::VM::MaxF32Op, + IREE::VM::MaxF64Op>>(typeConverter, context); // Floating-point conversion ops.
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp index d387070..2030dd8 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/ConvertVMToEmitC.cpp
@@ -4312,6 +4312,14 @@ "vm_fma_i32"); patterns.add<GenericOpConversion<IREE::VM::AbsI32Op>>(typeConverter, context, "vm_abs_i32"); + patterns.add<GenericOpConversion<IREE::VM::MinI32SOp>>(typeConverter, context, + "vm_min_i32s"); + patterns.add<GenericOpConversion<IREE::VM::MinI32UOp>>(typeConverter, context, + "vm_min_i32u"); + patterns.add<GenericOpConversion<IREE::VM::MaxI32SOp>>(typeConverter, context, + "vm_max_i32s"); + patterns.add<GenericOpConversion<IREE::VM::MaxI32UOp>>(typeConverter, context, + "vm_max_i32u"); patterns.add<GenericOpConversion<IREE::VM::NotI32Op>>(typeConverter, context, "vm_not_i32"); patterns.add<GenericOpConversion<IREE::VM::AndI32Op>>(typeConverter, context, @@ -4413,6 +4421,10 @@ typeConverter, context, "vm_floor_f32"); patterns.add<GenericOpConversion<IREE::VM::RoundF32Op>>( typeConverter, context, "vm_round_f32"); + patterns.add<GenericOpConversion<IREE::VM::MinF32Op>>(typeConverter, context, + "vm_min_f32"); + patterns.add<GenericOpConversion<IREE::VM::MaxF32Op>>(typeConverter, context, + "vm_max_f32"); patterns.add<GenericOpConversion<IREE::VM::AtanF32Op>>(typeConverter, context, "vm_atan_f32"); @@ -4534,6 +4546,14 @@ "vm_fma_i64"); patterns.add<GenericOpConversion<IREE::VM::AbsI64Op>>(typeConverter, context, "vm_abs_i64"); + patterns.add<GenericOpConversion<IREE::VM::MinI64SOp>>(typeConverter, context, + "vm_min_i64s"); + patterns.add<GenericOpConversion<IREE::VM::MinI64UOp>>(typeConverter, context, + "vm_min_i64u"); + patterns.add<GenericOpConversion<IREE::VM::MaxI64SOp>>(typeConverter, context, + "vm_max_i64s"); + patterns.add<GenericOpConversion<IREE::VM::MaxI64UOp>>(typeConverter, context, + "vm_max_i64u"); patterns.add<GenericOpConversion<IREE::VM::NotI64Op>>(typeConverter, context, "vm_not_i64"); patterns.add<GenericOpConversion<IREE::VM::AndI64Op>>(typeConverter, context,
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops.mlir b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops.mlir index 6ef3fcd..c1ff692 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops.mlir +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops.mlir
@@ -99,6 +99,17 @@ // ----- +// CHECK-LABEL: @my_module_min_i32_s +vm.module @my_module { + vm.func @min_i32_s(%arg0: i32, %arg1: i32) { + // CHECK: %0 = emitc.call "vm_min_i32s"(%arg3, %arg4) : (i32, i32) -> i32 + %0 = vm.min.i32.s %arg0, %arg1 : i32 + vm.return %0 : i32 + } +} + +// ----- + // CHECK-LABEL: @my_module_not_i32 vm.module @my_module { vm.func @not_i32(%arg0 : i32) -> i32 {
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_f32.mlir b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_f32.mlir index 93ad88d..d54b9b9 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_f32.mlir +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_f32.mlir
@@ -110,6 +110,28 @@ // ----- +// CHECK-LABEL: @my_module_min_f32 +vm.module @my_module { + vm.func @min_f32(%arg0 : f32, %arg1 : f32) -> f32 { + // CHECK-NEXT: %0 = emitc.call "vm_min_f32"(%arg3, %arg4) : (f32, f32) -> f32 + %0 = vm.min.f32 %arg0, %arg1 : f32 + vm.return %0 : f32 + } +} + +// ----- + +// CHECK-LABEL: @my_module_max_f32 +vm.module @my_module { + vm.func @max_f32(%arg0 : f32, %arg1 : f32) -> f32 { + // CHECK-NEXT: %0 = emitc.call "vm_max_f32"(%arg3, %arg4) : (f32, f32) -> f32 + %0 = vm.max.f32 %arg0, %arg1 : f32 + vm.return %0 : f32 + } +} + +// ----- + // CHECK-LABEL: @my_module_atan_f32 vm.module @my_module { vm.func @atan_f32(%arg0 : f32) -> f32 {
diff --git a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_i64.mlir b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_i64.mlir index c76c84c..dd1341d 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_i64.mlir +++ b/compiler/src/iree/compiler/Dialect/VM/Conversion/VMToEmitC/test/arithmetic_ops_i64.mlir
@@ -99,6 +99,17 @@ // ----- +// CHECK-LABEL: @my_module_min_i64_s +vm.module @my_module { + vm.func @min_i64_s(%arg0: i64, %arg1: i64) { + // CHECK: %0 = emitc.call "vm_min_i64s"(%arg3, %arg4) : (i64, i64) -> i64 + %0 = vm.min.i64.s %arg0, %arg1 : i64 + vm.return %0 : i64 + } +} + +// ----- + // CHECK-LABEL: @my_module_not_i64 vm.module @my_module { vm.func @not_i64(%arg0 : i64) -> i64 {
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpFolders.cpp b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpFolders.cpp index 20b2551..6fae72b 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpFolders.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpFolders.cpp
@@ -955,6 +955,70 @@ [](const APInt &a) { return a.abs(); }); } +OpFoldResult MinI32SOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::smin(lhs, rhs); + }); +} + +OpFoldResult MinI64SOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::smin(lhs, rhs); + }); +} + +OpFoldResult MinI32UOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::umin(lhs, rhs); + }); +} + +OpFoldResult MinI64UOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::umin(lhs, rhs); + }); +} + +OpFoldResult MaxI32SOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::smax(lhs, rhs); + }); +} + +OpFoldResult MaxI64SOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::smax(lhs, rhs); + }); +} + +OpFoldResult MaxI32UOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::umax(lhs, rhs); + }); +} + +OpFoldResult MaxI64UOp::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<IntegerAttr>(operands.getLhs(), operands.getRhs(), + [](const APInt &lhs, const APInt &rhs) { + return llvm::APIntOps::umax(lhs, rhs); + }); +} + //===----------------------------------------------------------------------===// // Floating-point arithmetic //===----------------------------------------------------------------------===// @@ -1165,6 +1229,32 @@ }); } +OpFoldResult MinF32Op::fold(FoldAdaptor operands) { + return constFoldBinaryOp<FloatAttr>( + operands.getLhs(), operands.getRhs(), + [](const APFloat &a, const APFloat &b) { return llvm::minnum(a, b); }); +} + +OpFoldResult MinF64Op::fold(FoldAdaptor operands) { + return constFoldBinaryOp<FloatAttr>( + operands.getLhs(), operands.getRhs(), + [](const APFloat &a, const APFloat &b) { return llvm::minnum(a, b); }); +} + +OpFoldResult MaxF32Op::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<FloatAttr>( + operands.getLhs(), operands.getRhs(), + [](const APFloat &a, const APFloat &b) { return llvm::maxnum(a, b); }); +} + +OpFoldResult MaxF64Op::fold(FoldAdaptor operands) { + if (getLhs() == getRhs()) return getLhs(); + return constFoldBinaryOp<FloatAttr>( + operands.getLhs(), operands.getRhs(), + [](const APFloat &a, const APFloat &b) { return llvm::maxnum(a, b); }); +} + //===----------------------------------------------------------------------===// // Floating-point math //===----------------------------------------------------------------------===//
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesCore.td b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesCore.td index b271b5c..901983c 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesCore.td +++ b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesCore.td
@@ -47,7 +47,7 @@ string opcodeEnumTag = enumTag; } -// Next available opcode: 0x7A +// Next available opcode: 0x82 // Globals: def VM_OPC_GlobalLoadI32 : VM_OPC<0x00, "GlobalLoadI32">; @@ -107,6 +107,10 @@ def VM_OPC_RemI32U : VM_OPC<0x28, "RemI32U">; def VM_OPC_FMAI32 : VM_OPC<0x29, "FMAI32">; def VM_OPC_AbsI32 : VM_OPC<0x77, "AbsI32">; +def VM_OPC_MinI32S : VM_OPC<0x7A, "MinI32S">; +def VM_OPC_MinI32U : VM_OPC<0x7B, "MinI32U">; +def VM_OPC_MaxI32S : VM_OPC<0x7C, "MaxI32S">; +def VM_OPC_MaxI32U : VM_OPC<0x7D, "MaxI32U">; // 64-bit integer arithmetic: def VM_OPC_AddI64 : VM_OPC<0x2A, "AddI64">; @@ -118,6 +122,10 @@ def VM_OPC_RemI64U : VM_OPC<0x30, "RemI64U">; def VM_OPC_FMAI64 : VM_OPC<0x31, "FMAI64">; def VM_OPC_AbsI64 : VM_OPC<0x78, "AbsI64">; +def VM_OPC_MinI64S : VM_OPC<0x7E, "MinI64S">; +def VM_OPC_MinI64U : VM_OPC<0x7F, "MinI64U">; +def VM_OPC_MaxI64S : VM_OPC<0x80, "MaxI64S">; +def VM_OPC_MaxI64U : VM_OPC<0x81, "MaxI64U">; // 32-bit integer bit manipulation: def VM_OPC_NotI32 : VM_OPC<0x32, "NotI32">; @@ -272,6 +280,10 @@ VM_OPC_RemI32U, VM_OPC_FMAI32, VM_OPC_AbsI32, + VM_OPC_MinI32S, + VM_OPC_MinI32U, + VM_OPC_MaxI32S, + VM_OPC_MaxI32U, VM_OPC_AddI64, VM_OPC_SubI64, @@ -282,6 +294,10 @@ VM_OPC_RemI64U, VM_OPC_FMAI64, VM_OPC_AbsI64, + VM_OPC_MinI64S, + VM_OPC_MinI64U, + VM_OPC_MaxI64S, + VM_OPC_MaxI64U, VM_OPC_NotI32, VM_OPC_AndI32,
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF32.td b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF32.td index 1ef5d4e..11ffe5c 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF32.td +++ b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF32.td
@@ -40,6 +40,8 @@ def VM_OPC_CeilF32 : VM_OPC<0x12, "CeilF32">; def VM_OPC_FloorF32 : VM_OPC<0x13, "FloorF32">; def VM_OPC_RoundF32 : VM_OPC<0x36, "RoundF32">; +def VM_OPC_MinF32 : VM_OPC<0x37, "MinF32">; +def VM_OPC_MaxF32 : VM_OPC<0x38, "MaxF32">; def VM_OPC_CastSI32F32 : VM_OPC<0x14, "CastSI32F32">; def VM_OPC_CastUI32F32 : VM_OPC<0x15, "CastUI32F32">; @@ -111,6 +113,8 @@ VM_OPC_CeilF32, VM_OPC_FloorF32, VM_OPC_RoundF32, + VM_OPC_MinF32, + VM_OPC_MaxF32, VM_OPC_CastSI32F32, VM_OPC_CastUI32F32,
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF64.td b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF64.td index 133c3ce..626ca57 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF64.td +++ b/compiler/src/iree/compiler/Dialect/VM/IR/VMOpcodesF64.td
@@ -42,6 +42,8 @@ def VM_OPC_RoundF64 : VM_OPC<0x3C, "RoundF64">; def VM_OPC_TruncF64F32 : VM_OPC<0x14, "TruncF64F32">; def VM_OPC_ExtF32F64 : VM_OPC<0x15, "ExtF32F64">; +def VM_OPC_MinF64 : VM_OPC<0x3D, "MinF64">; +def VM_OPC_MaxF64 : VM_OPC<0x3E, "MaxF64">; def VM_OPC_CastSI32F64 : VM_OPC<0x16, "CastSI32F64">; def VM_OPC_CastUI32F64 : VM_OPC<0x17, "CastUI32F64">; @@ -118,6 +120,8 @@ VM_OPC_CeilF64, VM_OPC_FloorF64, VM_OPC_RoundF64, + VM_OPC_MinF64, + VM_OPC_MaxF64, VM_OPC_TruncF64F32, VM_OPC_ExtF32F64,
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/VMOps.td b/compiler/src/iree/compiler/Dialect/VM/IR/VMOps.td index 5f916c0..f008f56 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/VMOps.td +++ b/compiler/src/iree/compiler/Dialect/VM/IR/VMOps.td
@@ -2211,6 +2211,54 @@ let hasFolder = 1; } +def VM_MinI32SOp : + VM_BinaryArithmeticOp<I32, "min.i32.s", VM_OPC_MinI32S, [Commutative]> { + let summary = [{signed integer minimum operation}]; + let hasFolder = 1; +} + +def VM_MinI32UOp : + VM_BinaryArithmeticOp<I32, "min.i32.u", VM_OPC_MinI32U, [Commutative]> { + let summary = [{unsigned integer minimum operation}]; + let hasFolder = 1; +} + +def VM_MinI64SOp : + VM_BinaryArithmeticOp<I64, "min.i64.s", VM_OPC_MinI64S, [Commutative]> { + let summary = [{signed integer minimum operation}]; + let hasFolder = 1; +} + +def VM_MinI64UOp : + VM_BinaryArithmeticOp<I64, "min.i64.u", VM_OPC_MinI64U, [Commutative]> { + let summary = [{unsigned integer minimum operation}]; + let hasFolder = 1; +} + +def VM_MaxI32SOp : + VM_BinaryArithmeticOp<I32, "max.i32.s", VM_OPC_MaxI32S, [Commutative]> { + let summary = [{signed integer maximum operation}]; + let hasFolder = 1; +} + +def VM_MaxI32UOp : + VM_BinaryArithmeticOp<I32, "max.i32.u", VM_OPC_MaxI32U, [Commutative]> { + let summary = [{unsigned integer maximum operation}]; + let hasFolder = 1; +} + +def VM_MaxI64SOp : + VM_BinaryArithmeticOp<I64, "max.i64.s", VM_OPC_MaxI64S, [Commutative]> { + let summary = [{signed integer maximum operation}]; + let hasFolder = 1; +} + +def VM_MaxI64UOp : + VM_BinaryArithmeticOp<I64, "max.i64.u", VM_OPC_MaxI64U, [Commutative]> { + let summary = [{unsigned integer maximum operation}]; + let hasFolder = 1; +} + //===----------------------------------------------------------------------===// // Floating-point arithmetic //===----------------------------------------------------------------------===// @@ -2371,6 +2419,34 @@ let summary = [{rounds the value to the nearest integer away from zero}]; } +def VM_MinF32Op : + VM_TotalBinaryArithmeticOp<F32, "min.f32", VM_OPC_MinF32, + [VM_ExtF32, Commutative]> { + let summary = [{floating point minimum operation}]; + let hasFolder = 1; +} + +def VM_MinF64Op : + VM_TotalBinaryArithmeticOp<F64, "min.f64", VM_OPC_MinF64, + [VM_ExtF64, Commutative]> { + let summary = [{floating point minimum operation}]; + let hasFolder = 1; +} + +def VM_MaxF32Op : + VM_TotalBinaryArithmeticOp<F32, "max.f32", VM_OPC_MaxF32, + [VM_ExtF32, Commutative]> { + let summary = [{floating point maximum operation}]; + let hasFolder = 1; +} + +def VM_MaxF64Op : + VM_TotalBinaryArithmeticOp<F64, "max.f64", VM_OPC_MaxF64, + [VM_ExtF32, Commutative]> { + let summary = [{floating point maximum operation}]; + let hasFolder = 1; +} + //===----------------------------------------------------------------------===// // Floating-point math //===----------------------------------------------------------------------===//
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_folding.mlir b/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_folding.mlir index 35080c1..d83f6a6 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_folding.mlir +++ b/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_folding.mlir
@@ -284,6 +284,46 @@ // ----- +// CHECK-LABEL: @min_i32_folds +vm.module @min_i32_folds { + // CHECK-LABEL: @min_i32_cst_y + vm.func @min_i32_cst_y(%arg0: i32) -> i32 { + %c123 = vm.const.i32 123 + // CHECK: vm.min.i32.s %arg0, %c123 : i32 + %0 = vm.min.i32.s %c123, %arg0 : i32 + vm.return %0 : i32 + } + + // CHECK-LABEL: @min_i32_x_x + vm.func @min_i32_x_x(%arg0: i32) -> i32 { + // CHECK: vm.return %arg0 : i32 + %0 = vm.min.i32.s %arg0, %arg0 : i32 + vm.return %0 : i32 + } + + // CHECK-LABEL: @min_i32_s_const + vm.func @min_i32_s_const() -> i32 { + // CHECK: %[[CST:.+]] = vm.const.i32 -5 + // CHECK-NEXT: vm.return %[[CST]] : i32 + %cn5 = vm.const.i32 -5 + %c4 = vm.const.i32 4 + %0 = vm.min.i32.s %cn5, %c4 : i32 + vm.return %0 : i32 + } + + // CHECK-LABEL: @min_i32_u_const + vm.func @min_i32_u_const() -> i32 { + // CHECK: %[[CST:.+]] = vm.const.i32 2147483647 + // CHECK-NEXT: vm.return %[[CST]] : i32 + %c7f = vm.const.i32 0x7FFFFFFF + %c80 = vm.const.i32 0x80000000 + %0 = vm.min.i32.u %c7f, %c80 : i32 + vm.return %0 : i32 + } +} + +// ----- + // CHECK-LABEL: @not_i32_folds vm.module @not_i32_folds { // CHECK-LABEL: @not_i32_const
diff --git a/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_ops.mlir b/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_ops.mlir index 2787cf1..a2c8a2e 100644 --- a/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_ops.mlir +++ b/compiler/src/iree/compiler/Dialect/VM/IR/test/arithmetic_ops.mlir
@@ -151,3 +151,25 @@ vm.return %0 : i32 } } + +// ----- + +// CHECK-LABEL: @min_i32_s +vm.module @my_module { + vm.func @min_i32_s(%arg0 : i32, %arg1 : i32) -> i32 { + // CHECK: %0 = vm.min.i32.s %arg0, %arg1 : i32 + %0 = vm.min.i32.s %arg0, %arg1 : i32 + vm.return %0 : i32 + } +} + +// ----- + +// CHECK-LABEL: @max_i32_s +vm.module @my_module { + vm.func @max_i32_s(%arg0 : i32, %arg1 : i32) -> i32 { + // CHECK: %0 = vm.max.i32.s %arg0, %arg1 : i32 + %0 = vm.max.i32.s %arg0, %arg1 : i32 + vm.return %0 : i32 + } +}
diff --git a/compiler/src/iree/compiler/Dialect/VM/Transforms/Conversion.cpp b/compiler/src/iree/compiler/Dialect/VM/Transforms/Conversion.cpp index c54785a..f34866f 100644 --- a/compiler/src/iree/compiler/Dialect/VM/Transforms/Conversion.cpp +++ b/compiler/src/iree/compiler/Dialect/VM/Transforms/Conversion.cpp
@@ -150,12 +150,7 @@ patterns); populateUtilToVMPatterns(context, conversionTarget, typeConverter, patterns); - arith::populateArithExpandOpsPatterns(patterns); - patterns.add<MaxMinIOpConverter<arith::MaxSIOp, arith::CmpIPredicate::sgt>, - MaxMinIOpConverter<arith::MaxUIOp, arith::CmpIPredicate::ugt>, - MaxMinIOpConverter<arith::MinSIOp, arith::CmpIPredicate::slt>, - MaxMinIOpConverter<arith::MinUIOp, arith::CmpIPredicate::ult>>( - context); + arith::populateCeilFloorDivExpandOpsPatterns(patterns); populateStandardToVMPatterns(context, typeConverter, patterns); populateMathToVMPatterns(context, typeConverter, patterns); populateAffineToStdConversionPatterns(patterns);
diff --git a/runtime/src/iree/vm/bytecode/disassembler.c b/runtime/src/iree/vm/bytecode/disassembler.c index e0fbab0..1c7bce8 100644 --- a/runtime/src/iree/vm/bytecode/disassembler.c +++ b/runtime/src/iree/vm/bytecode/disassembler.c
@@ -1320,6 +1320,10 @@ DISASM_OP_CORE_BINARY_I32(RemI32U, "vm.rem.i32.u"); DISASM_OP_CORE_TERNARY_I32(FMAI32, "vm.fma.i32"); DISASM_OP_CORE_UNARY_I32(AbsI32, "vm.abs.i32"); + DISASM_OP_CORE_BINARY_I32(MinI32S, "vm.min.i32.s"); + DISASM_OP_CORE_BINARY_I32(MinI32U, "vm.min.i32.u"); + DISASM_OP_CORE_BINARY_I32(MaxI32S, "vm.max.i32.s"); + DISASM_OP_CORE_BINARY_I32(MaxI32U, "vm.max.i32.u"); DISASM_OP_CORE_UNARY_I32(NotI32, "vm.not.i32"); DISASM_OP_CORE_BINARY_I32(AndI32, "vm.and.i32"); DISASM_OP_CORE_BINARY_I32(OrI32, "vm.or.i32"); @@ -1335,6 +1339,10 @@ DISASM_OP_CORE_BINARY_I64(RemI64U, "vm.rem.i64.u"); DISASM_OP_CORE_TERNARY_I64(FMAI64, "vm.fma.i64"); DISASM_OP_CORE_UNARY_I64(AbsI64, "vm.abs.i64"); + DISASM_OP_CORE_BINARY_I64(MinI64S, "vm.min.i64.s"); + DISASM_OP_CORE_BINARY_I64(MinI64U, "vm.min.i64.u"); + DISASM_OP_CORE_BINARY_I64(MaxI64S, "vm.max.i64.s"); + DISASM_OP_CORE_BINARY_I64(MaxI64U, "vm.max.i64.u"); DISASM_OP_CORE_UNARY_I64(NotI64, "vm.not.i64"); DISASM_OP_CORE_BINARY_I64(AndI64, "vm.and.i64"); DISASM_OP_CORE_BINARY_I64(OrI64, "vm.or.i64"); @@ -1939,6 +1947,9 @@ DISASM_OP_EXT_F32_UNARY_F32(NegF32, "vm.neg.f32"); DISASM_OP_EXT_F32_UNARY_F32(CeilF32, "vm.ceil.f32"); DISASM_OP_EXT_F32_UNARY_F32(FloorF32, "vm.floor.f32"); + DISASM_OP_EXT_F32_UNARY_F32(RoundF32, "vm.round.f32"); + DISASM_OP_EXT_F32_BINARY_F32(MinF32, "vm.min.f32"); + DISASM_OP_EXT_F32_BINARY_F32(MaxF32, "vm.max.f32"); DISASM_OP_EXT_F32_UNARY_F32(AtanF32, "vm.atan.f32"); DISASM_OP_EXT_F32_BINARY_F32(Atan2F32, "vm.atan2.f32");
diff --git a/runtime/src/iree/vm/bytecode/dispatch.c b/runtime/src/iree/vm/bytecode/dispatch.c index 220f9c5..ff1744c 100644 --- a/runtime/src/iree/vm/bytecode/dispatch.c +++ b/runtime/src/iree/vm/bytecode/dispatch.c
@@ -1428,6 +1428,10 @@ DISPATCH_OP_CORE_BINARY_I32(RemI32U, vm_rem_i32u); DISPATCH_OP_CORE_TERNARY_I32(FMAI32, vm_fma_i32); DISPATCH_OP_CORE_UNARY_I32(AbsI32, vm_abs_i32); + DISPATCH_OP_CORE_BINARY_I32(MinI32S, vm_min_i32s); + DISPATCH_OP_CORE_BINARY_I32(MinI32U, vm_min_i32u); + DISPATCH_OP_CORE_BINARY_I32(MaxI32S, vm_max_i32s); + DISPATCH_OP_CORE_BINARY_I32(MaxI32U, vm_max_i32u); DISPATCH_OP_CORE_UNARY_I32(NotI32, vm_not_i32); DISPATCH_OP_CORE_BINARY_I32(AndI32, vm_and_i32); DISPATCH_OP_CORE_BINARY_I32(OrI32, vm_or_i32); @@ -1443,6 +1447,10 @@ DISPATCH_OP_CORE_BINARY_I64(RemI64U, vm_rem_i64u); DISPATCH_OP_CORE_TERNARY_I64(FMAI64, vm_fma_i64); DISPATCH_OP_CORE_UNARY_I64(AbsI64, vm_abs_i64); + DISPATCH_OP_CORE_BINARY_I64(MinI64S, vm_min_i64s); + DISPATCH_OP_CORE_BINARY_I64(MinI64U, vm_min_i64u); + DISPATCH_OP_CORE_BINARY_I64(MaxI64S, vm_max_i64s); + DISPATCH_OP_CORE_BINARY_I64(MaxI64U, vm_max_i64u); DISPATCH_OP_CORE_UNARY_I64(NotI64, vm_not_i64); DISPATCH_OP_CORE_BINARY_I64(AndI64, vm_and_i64); DISPATCH_OP_CORE_BINARY_I64(OrI64, vm_or_i64); @@ -1926,6 +1934,8 @@ DISPATCH_OP_EXT_F32_UNARY_F32(CeilF32, vm_ceil_f32); DISPATCH_OP_EXT_F32_UNARY_F32(FloorF32, vm_floor_f32); DISPATCH_OP_EXT_F32_UNARY_F32(RoundF32, vm_round_f32); + DISPATCH_OP_EXT_F32_BINARY_F32(MinF32, vm_min_f32); + DISPATCH_OP_EXT_F32_BINARY_F32(MaxF32, vm_max_f32); DISPATCH_OP_EXT_F32_UNARY_F32(AtanF32, vm_atan_f32); DISPATCH_OP_EXT_F32_BINARY_F32(Atan2F32, vm_atan2_f32);
diff --git a/runtime/src/iree/vm/bytecode/dispatch_test.cc b/runtime/src/iree/vm/bytecode/dispatch_test.cc index c47df1b..d397611 100644 --- a/runtime/src/iree/vm/bytecode/dispatch_test.cc +++ b/runtime/src/iree/vm/bytecode/dispatch_test.cc
@@ -102,7 +102,10 @@ bytecode_module_, IREE_VM_FUNCTION_LINKAGE_EXPORT, iree_make_cstring_view(function_name), &function)); - return iree_vm_invoke(context_, function, IREE_VM_INVOCATION_FLAG_NONE, + iree_vm_invocation_flags_t flags = IREE_VM_INVOCATION_FLAG_NONE; + // NOTE: adding this bit makes it easy to debug issues on stdout: + // flags |= IREE_VM_INVOCATION_FLAG_TRACE_EXECUTION; + return iree_vm_invoke(context_, function, flags, /*policy=*/nullptr, /*inputs=*/nullptr, /*outputs=*/nullptr, iree_allocator_system()); }
diff --git a/runtime/src/iree/vm/bytecode/utils/generated/op_table.h b/runtime/src/iree/vm/bytecode/utils/generated/op_table.h index 3ad3c5b..7fe629b 100644 --- a/runtime/src/iree/vm/bytecode/utils/generated/op_table.h +++ b/runtime/src/iree/vm/bytecode/utils/generated/op_table.h
@@ -129,14 +129,14 @@ IREE_VM_OP_CORE_AbsI32 = 0x77, IREE_VM_OP_CORE_AbsI64 = 0x78, IREE_VM_OP_CORE_Block = 0x79, - IREE_VM_OP_CORE_RSV_0x7A, - IREE_VM_OP_CORE_RSV_0x7B, - IREE_VM_OP_CORE_RSV_0x7C, - IREE_VM_OP_CORE_RSV_0x7D, - IREE_VM_OP_CORE_RSV_0x7E, - IREE_VM_OP_CORE_RSV_0x7F, - IREE_VM_OP_CORE_RSV_0x80, - IREE_VM_OP_CORE_RSV_0x81, + IREE_VM_OP_CORE_MinI32S = 0x7A, + IREE_VM_OP_CORE_MinI32U = 0x7B, + IREE_VM_OP_CORE_MaxI32S = 0x7C, + IREE_VM_OP_CORE_MaxI32U = 0x7D, + IREE_VM_OP_CORE_MinI64S = 0x7E, + IREE_VM_OP_CORE_MinI64U = 0x7F, + IREE_VM_OP_CORE_MaxI64S = 0x80, + IREE_VM_OP_CORE_MaxI64U = 0x81, IREE_VM_OP_CORE_RSV_0x82, IREE_VM_OP_CORE_RSV_0x83, IREE_VM_OP_CORE_RSV_0x84, @@ -388,14 +388,14 @@ OPC(0x77, AbsI32) \ OPC(0x78, AbsI64) \ OPC(0x79, Block) \ - RSV(0x7A) \ - RSV(0x7B) \ - RSV(0x7C) \ - RSV(0x7D) \ - RSV(0x7E) \ - RSV(0x7F) \ - RSV(0x80) \ - RSV(0x81) \ + OPC(0x7A, MinI64S) \ + OPC(0x7B, MinI64U) \ + OPC(0x7C, MaxI64S) \ + OPC(0x7D, MaxI64U) \ + OPC(0x7E, MinI64S) \ + OPC(0x7F, MinI64U) \ + OPC(0x80, MaxI64S) \ + OPC(0x81, MaxI64U) \ RSV(0x82) \ RSV(0x83) \ RSV(0x84) \ @@ -579,8 +579,8 @@ IREE_VM_OP_EXT_F32_BufferStoreF32 = 0x34, IREE_VM_OP_EXT_F32_BufferFillF32 = 0x35, IREE_VM_OP_EXT_F32_RoundF32 = 0x36, - IREE_VM_OP_EXT_F32_RSV_0x37, - IREE_VM_OP_EXT_F32_RSV_0x38, + IREE_VM_OP_EXT_F32_MinF32 = 0x37, + IREE_VM_OP_EXT_F32_MaxF32 = 0x38, IREE_VM_OP_EXT_F32_RSV_0x39, IREE_VM_OP_EXT_F32_RSV_0x3A, IREE_VM_OP_EXT_F32_RSV_0x3B, @@ -838,8 +838,8 @@ OPC(0x34, BufferStoreF32) \ OPC(0x35, BufferFillF32) \ OPC(0x36, RoundF32) \ - RSV(0x37) \ - RSV(0x38) \ + OPC(0x37, MinF32) \ + OPC(0x38, MaxF32) \ RSV(0x39) \ RSV(0x3A) \ RSV(0x3B) \ @@ -1102,8 +1102,8 @@ IREE_VM_OP_EXT_F64_BufferStoreF64 = 0x3A, IREE_VM_OP_EXT_F64_BufferFillF64 = 0x3B, IREE_VM_OP_EXT_F64_RoundF64 = 0x3C, - IREE_VM_OP_EXT_F64_RSV_0x3D, - IREE_VM_OP_EXT_F64_RSV_0x3E, + IREE_VM_OP_EXT_F64_MinF64 = 0x3D, + IREE_VM_OP_EXT_F64_MaxF64 = 0x3E, IREE_VM_OP_EXT_F64_RSV_0x3F, IREE_VM_OP_EXT_F64_RSV_0x40, IREE_VM_OP_EXT_F64_RSV_0x41, @@ -1361,8 +1361,8 @@ OPC(0x3A, BufferStoreF64) \ OPC(0x3B, BufferFillF64) \ OPC(0x3C, RoundF64) \ - RSV(0x3D) \ - RSV(0x3E) \ + OPC(0x3D, MinF64) \ + OPC(0x3E, MaxF64) \ RSV(0x3F) \ RSV(0x40) \ RSV(0x41) \
diff --git a/runtime/src/iree/vm/bytecode/verifier.c b/runtime/src/iree/vm/bytecode/verifier.c index f26c4f3..dfcf9ff 100644 --- a/runtime/src/iree/vm/bytecode/verifier.c +++ b/runtime/src/iree/vm/bytecode/verifier.c
@@ -1392,6 +1392,10 @@ VERIFY_OP_CORE_BINARY_I32(RemI32U); VERIFY_OP_CORE_TERNARY_I32(FMAI32); VERIFY_OP_CORE_UNARY_I32(AbsI32); + VERIFY_OP_CORE_BINARY_I32(MinI32S); + VERIFY_OP_CORE_BINARY_I32(MinI32U); + VERIFY_OP_CORE_BINARY_I32(MaxI32S); + VERIFY_OP_CORE_BINARY_I32(MaxI32U); VERIFY_OP_CORE_UNARY_I32(NotI32); VERIFY_OP_CORE_BINARY_I32(AndI32); VERIFY_OP_CORE_BINARY_I32(OrI32); @@ -1407,6 +1411,10 @@ VERIFY_OP_CORE_BINARY_I64(RemI64U); VERIFY_OP_CORE_TERNARY_I64(FMAI64); VERIFY_OP_CORE_UNARY_I64(AbsI64); + VERIFY_OP_CORE_BINARY_I64(MinI64S); + VERIFY_OP_CORE_BINARY_I64(MinI64U); + VERIFY_OP_CORE_BINARY_I64(MaxI64S); + VERIFY_OP_CORE_BINARY_I64(MaxI64U); VERIFY_OP_CORE_UNARY_I64(NotI64); VERIFY_OP_CORE_BINARY_I64(AndI64); VERIFY_OP_CORE_BINARY_I64(OrI64); @@ -1748,6 +1756,8 @@ VERIFY_OP_EXT_F32_UNARY_F32(CeilF32); VERIFY_OP_EXT_F32_UNARY_F32(FloorF32); VERIFY_OP_EXT_F32_UNARY_F32(RoundF32); + VERIFY_OP_EXT_F32_BINARY_F32(MinF32); + VERIFY_OP_EXT_F32_BINARY_F32(MaxF32); VERIFY_OP_EXT_F32_UNARY_F32(AtanF32); VERIFY_OP_EXT_F32_BINARY_F32(Atan2F32);
diff --git a/runtime/src/iree/vm/ops.h b/runtime/src/iree/vm/ops.h index 1bfffbd..0137f2c 100644 --- a/runtime/src/iree/vm/ops.h +++ b/runtime/src/iree/vm/ops.h
@@ -256,6 +256,18 @@ return a * b + c; } static inline int32_t vm_abs_i32(int32_t operand) { return abs(operand); } +static inline int32_t vm_min_i32s(int32_t lhs, int32_t rhs) { + return rhs < lhs ? rhs : lhs; +} +static inline int32_t vm_min_i32u(int32_t lhs, int32_t rhs) { + return (uint32_t)rhs < (uint32_t)lhs ? rhs : lhs; +} +static inline int32_t vm_max_i32s(int32_t lhs, int32_t rhs) { + return lhs < rhs ? rhs : lhs; +} +static inline int32_t vm_max_i32u(int32_t lhs, int32_t rhs) { + return (uint32_t)lhs < (uint32_t)rhs ? rhs : lhs; +} static inline int32_t vm_not_i32(int32_t operand) { return (int32_t)(~((uint32_t)operand)); } @@ -382,6 +394,18 @@ return a * b + c; } static inline int64_t vm_abs_i64(int64_t operand) { return labs(operand); } +static inline int64_t vm_min_i64s(int64_t lhs, int64_t rhs) { + return rhs < lhs ? rhs : lhs; +} +static inline int64_t vm_min_i64u(int64_t lhs, int64_t rhs) { + return (uint64_t)rhs < (uint64_t)lhs ? rhs : lhs; +} +static inline int64_t vm_max_i64s(int64_t lhs, int64_t rhs) { + return lhs < rhs ? rhs : lhs; +} +static inline int64_t vm_max_i64u(int64_t lhs, int64_t rhs) { + return (uint64_t)lhs < (uint64_t)rhs ? rhs : lhs; +} static inline int64_t vm_not_i64(int64_t operand) { return (int64_t)(~((uint64_t)operand)); } @@ -527,6 +551,12 @@ static inline float vm_ceil_f32(float operand) { return ceilf(operand); } static inline float vm_floor_f32(float operand) { return floorf(operand); } static inline float vm_round_f32(float operand) { return roundf(operand); } +static inline float vm_min_f32(float lhs, float rhs) { + return rhs < lhs ? rhs : lhs; +} +static inline float vm_max_f32(float lhs, float rhs) { + return lhs < rhs ? rhs : lhs; +} static inline float vm_atan_f32(float operand) { return atanf(operand); } static inline float vm_atan2_f32(float y, float x) { return atan2f(y, x); }
diff --git a/runtime/src/iree/vm/test/arithmetic_ops.mlir b/runtime/src/iree/vm/test/arithmetic_ops.mlir index 9046b6b..4ec12e1 100644 --- a/runtime/src/iree/vm/test/arithmetic_ops.mlir +++ b/runtime/src/iree/vm/test/arithmetic_ops.mlir
@@ -100,11 +100,55 @@ vm.export @test_abs_i32 vm.func @test_abs_i32() { - %c1 = vm.const.i32 -1 - %c1dno = util.optimization_barrier %c1 : i32 - %v = vm.abs.i32 %c1dno : i32 - %c2 = vm.const.i32 1 - vm.check.eq %v, %c2, "abs(-1)=1" : i32 + %cn1 = vm.const.i32 -1 + %cn1dno = util.optimization_barrier %cn1 : i32 + %v = vm.abs.i32 %cn1dno : i32 + %c1 = vm.const.i32 1 + vm.check.eq %v, %c1, "abs(-1)=1" : i32 + vm.return + } + + vm.export @test_min_i32s + vm.func @test_min_i32s() { + %cn3 = vm.const.i32 -3 + %cn3dno = util.optimization_barrier %cn3 : i32 + %c2 = vm.const.i32 2 + %c2dno = util.optimization_barrier %c2 : i32 + %v = vm.min.i32.s %cn3dno, %c2dno : i32 + vm.check.eq %v, %cn3, "smin(-3,2)=-3" : i32 + vm.return + } + + vm.export @test_min_i32u + vm.func @test_min_i32u() { + %cn3 = vm.const.i32 -3 + %cn3dno = util.optimization_barrier %cn3 : i32 + %c2 = vm.const.i32 2 + %c2dno = util.optimization_barrier %c2 : i32 + %v = vm.min.i32.u %cn3dno, %c2dno : i32 + vm.check.eq %v, %c2, "umin(-3,2)=2" : i32 + vm.return + } + + vm.export @test_max_i32s + vm.func @test_max_i32s() { + %cn3 = vm.const.i32 -3 + %cn3dno = util.optimization_barrier %cn3 : i32 + %c2 = vm.const.i32 2 + %c2dno = util.optimization_barrier %c2 : i32 + %v = vm.max.i32.s %cn3dno, %c2dno : i32 + vm.check.eq %v, %c2, "smax(-3,2)=2" : i32 + vm.return + } + + vm.export @test_max_i32u + vm.func @test_max_i32u() { + %cn3 = vm.const.i32 -3 + %cn3dno = util.optimization_barrier %cn3 : i32 + %c2 = vm.const.i32 2 + %c2dno = util.optimization_barrier %c2 : i32 + %v = vm.max.i32.u %cn3dno, %c2dno : i32 + vm.check.eq %v, %cn3, "umax(-3,2)=-3" : i32 vm.return }
diff --git a/runtime/src/iree/vm/test/arithmetic_ops_f32.mlir b/runtime/src/iree/vm/test/arithmetic_ops_f32.mlir index ce478fb..f446f4d 100644 --- a/runtime/src/iree/vm/test/arithmetic_ops_f32.mlir +++ b/runtime/src/iree/vm/test/arithmetic_ops_f32.mlir
@@ -106,11 +106,43 @@ vm.export @test_floor_f32 vm.func @test_floor_f32() { - %c1 = vm.const.f32 1.5 - %c1dno = util.optimization_barrier %c1 : f32 - %v = vm.floor.f32 %c1dno : f32 - %c2 = vm.const.f32 1.0 - vm.check.eq %v, %c2, "floor(1.5)=1.0" : f32 + %c15 = vm.const.f32 1.5 + %c15dno = util.optimization_barrier %c15 : f32 + %v = vm.floor.f32 %c15dno : f32 + %c1 = vm.const.f32 1.0 + vm.check.eq %v, %c1, "floor(1.5)=1.0" : f32 + vm.return + } + + vm.export @test_round_f32 + vm.func @test_round_f32() { + %c15 = vm.const.f32 1.5 + %c15dno = util.optimization_barrier %c15 : f32 + %v = vm.round.f32 %c15dno : f32 + %c2 = vm.const.f32 2.0 + vm.check.eq %v, %c2, "round(1.5)=2.0" : f32 + vm.return + } + + vm.export @test_min_f32 + vm.func @test_min_f32() { + %cn3 = vm.const.f32 -3.0 + %cn3dno = util.optimization_barrier %cn3 : f32 + %cn2 = vm.const.f32 -2.0 + %cn2dno = util.optimization_barrier %cn2 : f32 + %v = vm.min.f32 %cn3dno, %cn2dno : f32 + vm.check.eq %v, %cn3, "min(-3.0,-2.0)=-3.0" : f32 + vm.return + } + + vm.export @test_max_f32 + vm.func @test_max_f32() { + %cn3 = vm.const.f32 -3.0 + %cn3dno = util.optimization_barrier %cn3 : f32 + %cn2 = vm.const.f32 -2.0 + %cn2dno = util.optimization_barrier %cn2 : f32 + %v = vm.max.f32 %cn3dno, %cn2dno : f32 + vm.check.eq %v, %cn2, "max(-3.0,-2.0)=-2.0" : f32 vm.return }
diff --git a/runtime/src/iree/vm/test/arithmetic_ops_i64.mlir b/runtime/src/iree/vm/test/arithmetic_ops_i64.mlir index fd75c60..b6cc8a2 100644 --- a/runtime/src/iree/vm/test/arithmetic_ops_i64.mlir +++ b/runtime/src/iree/vm/test/arithmetic_ops_i64.mlir
@@ -100,11 +100,55 @@ vm.export @test_abs_i64 vm.func @test_abs_i64() { - %c1 = vm.const.i64 -1 - %c1dno = util.optimization_barrier %c1 : i64 - %v = vm.abs.i64 %c1dno : i64 - %c2 = vm.const.i64 1 - vm.check.eq %v, %c2, "abs(-1)=1" : i64 + %cn1 = vm.const.i64 -1 + %cn1dno = util.optimization_barrier %cn1 : i64 + %v = vm.abs.i64 %cn1dno : i64 + %c1 = vm.const.i64 1 + vm.check.eq %v, %c1, "abs(-1)=1" : i64 + vm.return + } + + vm.export @test_min_i64s + vm.func @test_min_i64s() { + %cn3 = vm.const.i64 -3 + %cn3dno = util.optimization_barrier %cn3 : i64 + %c2 = vm.const.i64 2 + %c2dno = util.optimization_barrier %c2 : i64 + %v = vm.min.i64.s %cn3dno, %c2dno : i64 + vm.check.eq %v, %cn3, "smin(-3,2)=-3" : i64 + vm.return + } + + vm.export @test_min_i64u + vm.func @test_min_i64u() { + %cn3 = vm.const.i64 -3 + %cn3dno = util.optimization_barrier %cn3 : i64 + %c2 = vm.const.i64 2 + %c2dno = util.optimization_barrier %c2 : i64 + %v = vm.min.i64.u %cn3dno, %c2dno : i64 + vm.check.eq %v, %c2, "umin(-3,2)=2" : i64 + vm.return + } + + vm.export @test_max_i64s + vm.func @test_max_i64s() { + %cn3 = vm.const.i64 -3 + %cn3dno = util.optimization_barrier %cn3 : i64 + %c2 = vm.const.i64 2 + %c2dno = util.optimization_barrier %c2 : i64 + %v = vm.max.i64.s %cn3dno, %c2dno : i64 + vm.check.eq %v, %c2, "smax(-3,2)=2" : i64 + vm.return + } + + vm.export @test_max_i64u + vm.func @test_max_i64u() { + %cn3 = vm.const.i64 -3 + %cn3dno = util.optimization_barrier %cn3 : i64 + %c2 = vm.const.i64 2 + %c2dno = util.optimization_barrier %c2 : i64 + %v = vm.max.i64.u %cn3dno, %c2dno : i64 + vm.check.eq %v, %cn3, "umax(-3,2)=-3" : i64 vm.return }