forked from OSchip/llvm-project
313 lines
9.3 KiB
MLIR
313 lines
9.3 KiB
MLIR
// RUN: mlir-opt -convert-std-to-spirv %s -o - | FileCheck %s
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std binary arithmetic ops
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @add_sub
|
|
func @add_sub(%arg0 : i32, %arg1 : i32) {
|
|
// CHECK: spv.IAdd
|
|
%0 = addi %arg0, %arg1 : i32
|
|
// CHECK: spv.ISub
|
|
%1 = subi %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @fadd_scalar
|
|
func @fadd_scalar(%arg: f32) -> f32 {
|
|
// CHECK: spv.FAdd
|
|
%0 = addf %arg, %arg : f32
|
|
return %0 : f32
|
|
}
|
|
|
|
// CHECK-LABEL: @fdiv_scalar
|
|
func @fdiv_scalar(%arg: f32) -> f32 {
|
|
// CHECK: spv.FDiv
|
|
%0 = divf %arg, %arg : f32
|
|
return %0 : f32
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_scalar
|
|
func @fmul_scalar(%arg: f32) -> f32 {
|
|
// CHECK: spv.FMul
|
|
%0 = mulf %arg, %arg : f32
|
|
return %0 : f32
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_vector2
|
|
func @fmul_vector2(%arg: vector<2xf32>) -> vector<2xf32> {
|
|
// CHECK: spv.FMul
|
|
%0 = mulf %arg, %arg : vector<2xf32>
|
|
return %0 : vector<2xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_vector3
|
|
func @fmul_vector3(%arg: vector<3xf32>) -> vector<3xf32> {
|
|
// CHECK: spv.FMul
|
|
%0 = mulf %arg, %arg : vector<3xf32>
|
|
return %0 : vector<3xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_vector4
|
|
func @fmul_vector4(%arg: vector<4xf32>) -> vector<4xf32> {
|
|
// CHECK: spv.FMul
|
|
%0 = mulf %arg, %arg : vector<4xf32>
|
|
return %0 : vector<4xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_vector5
|
|
func @fmul_vector5(%arg: vector<5xf32>) -> vector<5xf32> {
|
|
// Vector length of only 2, 3, and 4 is valid for SPIR-V
|
|
// CHECK: mulf
|
|
%0 = mulf %arg, %arg : vector<5xf32>
|
|
return %0 : vector<5xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @fmul_tensor
|
|
func @fmul_tensor(%arg: tensor<4xf32>) -> tensor<4xf32> {
|
|
// For tensors mulf cannot be lowered directly to spv.FMul
|
|
// CHECK: mulf
|
|
%0 = mulf %arg, %arg : tensor<4xf32>
|
|
return %0 : tensor<4xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @frem_scalar
|
|
func @frem_scalar(%arg: f32) -> f32 {
|
|
// CHECK: spv.FRem
|
|
%0 = remf %arg, %arg : f32
|
|
return %0 : f32
|
|
}
|
|
|
|
// CHECK-LABEL: @fsub_scalar
|
|
func @fsub_scalar(%arg: f32) -> f32 {
|
|
// CHECK: spv.FSub
|
|
%0 = subf %arg, %arg : f32
|
|
return %0 : f32
|
|
}
|
|
|
|
// CHECK-LABEL: @div_rem
|
|
func @div_rem(%arg0 : i32, %arg1 : i32) {
|
|
// CHECK: spv.SDiv
|
|
%0 = divi_signed %arg0, %arg1 : i32
|
|
// CHECK: spv.SMod
|
|
%1 = remi_signed %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std bit ops
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @bitwise_scalar
|
|
func @bitwise_scalar(%arg0 : i32, %arg1 : i32) {
|
|
// CHECK: spv.BitwiseAnd
|
|
%0 = and %arg0, %arg1 : i32
|
|
// CHECK: spv.BitwiseOr
|
|
%1 = or %arg0, %arg1 : i32
|
|
// CHECK: spv.BitwiseXor
|
|
%2 = xor %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @bitwise_vector
|
|
func @bitwise_vector(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
|
|
// CHECK: spv.BitwiseAnd
|
|
%0 = and %arg0, %arg1 : vector<4xi32>
|
|
// CHECK: spv.BitwiseOr
|
|
%1 = or %arg0, %arg1 : vector<4xi32>
|
|
// CHECK: spv.BitwiseXor
|
|
%2 = xor %arg0, %arg1 : vector<4xi32>
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @shift_scalar
|
|
func @shift_scalar(%arg0 : i32, %arg1 : i32) {
|
|
// CHECK: spv.ShiftLeftLogical
|
|
%0 = shift_left %arg0, %arg1 : i32
|
|
// CHECK: spv.ShiftRightArithmetic
|
|
%1 = shift_right_signed %arg0, %arg1 : i32
|
|
// CHECK: spv.ShiftRightLogical
|
|
%2 = shift_right_unsigned %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @shift_vector
|
|
func @shift_vector(%arg0 : vector<4xi32>, %arg1 : vector<4xi32>) {
|
|
// CHECK: spv.ShiftLeftLogical
|
|
%0 = shift_left %arg0, %arg1 : vector<4xi32>
|
|
// CHECK: spv.ShiftRightArithmetic
|
|
%1 = shift_right_signed %arg0, %arg1 : vector<4xi32>
|
|
// CHECK: spv.ShiftRightLogical
|
|
%2 = shift_right_unsigned %arg0, %arg1 : vector<4xi32>
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.cmpf
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @cmpf
|
|
func @cmpf(%arg0 : f32, %arg1 : f32) {
|
|
// CHECK: spv.FOrdEqual
|
|
%1 = cmpf "oeq", %arg0, %arg1 : f32
|
|
// CHECK: spv.FOrdGreaterThan
|
|
%2 = cmpf "ogt", %arg0, %arg1 : f32
|
|
// CHECK: spv.FOrdGreaterThanEqual
|
|
%3 = cmpf "oge", %arg0, %arg1 : f32
|
|
// CHECK: spv.FOrdLessThan
|
|
%4 = cmpf "olt", %arg0, %arg1 : f32
|
|
// CHECK: spv.FOrdLessThanEqual
|
|
%5 = cmpf "ole", %arg0, %arg1 : f32
|
|
// CHECK: spv.FOrdNotEqual
|
|
%6 = cmpf "one", %arg0, %arg1 : f32
|
|
// CHECK: spv.FUnordEqual
|
|
%7 = cmpf "ueq", %arg0, %arg1 : f32
|
|
// CHECK: spv.FUnordGreaterThan
|
|
%8 = cmpf "ugt", %arg0, %arg1 : f32
|
|
// CHECK: spv.FUnordGreaterThanEqual
|
|
%9 = cmpf "uge", %arg0, %arg1 : f32
|
|
// CHECK: spv.FUnordLessThan
|
|
%10 = cmpf "ult", %arg0, %arg1 : f32
|
|
// CHECK: FUnordLessThanEqual
|
|
%11 = cmpf "ule", %arg0, %arg1 : f32
|
|
// CHECK: spv.FUnordNotEqual
|
|
%12 = cmpf "une", %arg0, %arg1 : f32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.cmpi
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @cmpi
|
|
func @cmpi(%arg0 : i32, %arg1 : i32) {
|
|
// CHECK: spv.IEqual
|
|
%0 = cmpi "eq", %arg0, %arg1 : i32
|
|
// CHECK: spv.INotEqual
|
|
%1 = cmpi "ne", %arg0, %arg1 : i32
|
|
// CHECK: spv.SLessThan
|
|
%2 = cmpi "slt", %arg0, %arg1 : i32
|
|
// CHECK: spv.SLessThanEqual
|
|
%3 = cmpi "sle", %arg0, %arg1 : i32
|
|
// CHECK: spv.SGreaterThan
|
|
%4 = cmpi "sgt", %arg0, %arg1 : i32
|
|
// CHECK: spv.SGreaterThanEqual
|
|
%5 = cmpi "sge", %arg0, %arg1 : i32
|
|
// CHECK: spv.ULessThan
|
|
%6 = cmpi "ult", %arg0, %arg1 : i32
|
|
// CHECK: spv.ULessThanEqual
|
|
%7 = cmpi "ule", %arg0, %arg1 : i32
|
|
// CHECK: spv.UGreaterThan
|
|
%8 = cmpi "ugt", %arg0, %arg1 : i32
|
|
// CHECK: spv.UGreaterThanEqual
|
|
%9 = cmpi "uge", %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.constant
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @constant
|
|
func @constant() {
|
|
// CHECK: spv.constant true
|
|
%0 = constant true
|
|
// CHECK: spv.constant 42 : i64
|
|
%1 = constant 42
|
|
// CHECK: spv.constant {{[0-9]*\.[0-9]*e?-?[0-9]*}} : f32
|
|
%2 = constant 0.5 : f32
|
|
// CHECK: spv.constant dense<[2, 3]> : vector<2xi32>
|
|
%3 = constant dense<[2, 3]> : vector<2xi32>
|
|
// CHECK: spv.constant 1 : i32
|
|
%4 = constant 1 : index
|
|
// CHECK: spv.constant dense<1> : tensor<6xi32> : !spv.array<6 x i32 [4]>
|
|
%5 = constant dense<1> : tensor<2x3xi32>
|
|
// CHECK: spv.constant dense<1.000000e+00> : tensor<6xf32> : !spv.array<6 x f32 [4]>
|
|
%6 = constant dense<1.0> : tensor<2x3xf32>
|
|
// CHECK: spv.constant dense<{{\[}}1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]> : tensor<6xf32> : !spv.array<6 x f32 [4]>
|
|
%7 = constant dense<[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]> : tensor<2x3xf32>
|
|
// CHECK: spv.constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32 [4]>
|
|
%8 = constant dense<[[1, 2, 3], [4, 5, 6]]> : tensor<2x3xi32>
|
|
// CHECK: spv.constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32 [4]>
|
|
%9 = constant dense<[[1, 2], [3, 4], [5, 6]]> : tensor<3x2xi32>
|
|
// CHECK: spv.constant dense<{{\[}}1, 2, 3, 4, 5, 6]> : tensor<6xi32> : !spv.array<6 x i32 [4]>
|
|
%10 = constant dense<[1, 2, 3, 4, 5, 6]> : tensor<6xi32>
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std logical binary operations
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @logical_scalar
|
|
func @logical_scalar(%arg0 : i1, %arg1 : i1) {
|
|
// CHECK: spv.LogicalAnd
|
|
%0 = and %arg0, %arg1 : i1
|
|
// CHECK: spv.LogicalOr
|
|
%1 = or %arg0, %arg1 : i1
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @logical_vector
|
|
func @logical_vector(%arg0 : vector<4xi1>, %arg1 : vector<4xi1>) {
|
|
// CHECK: spv.LogicalAnd
|
|
%0 = and %arg0, %arg1 : vector<4xi1>
|
|
// CHECK: spv.LogicalOr
|
|
%1 = or %arg0, %arg1 : vector<4xi1>
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.fpext
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @fpext
|
|
func @fpext(%arg0 : f32) {
|
|
// CHECK: spv.FConvert
|
|
%0 = std.fpext %arg0 : f32 to f64
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.fptrunc
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @fptrunc
|
|
func @fptrunc(%arg0 : f64) {
|
|
// CHECK: spv.FConvert
|
|
%0 = std.fptrunc %arg0 : f64 to f32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.select
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @select
|
|
func @select(%arg0 : i32, %arg1 : i32) {
|
|
%0 = cmpi "sle", %arg0, %arg1 : i32
|
|
// CHECK: spv.Select
|
|
%1 = select %0, %arg0, %arg1 : i32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// std.sitofp
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: @sitofp
|
|
func @sitofp(%arg0 : i32) {
|
|
// CHECK: spv.ConvertSToF
|
|
%0 = std.sitofp %arg0 : i32 to f32
|
|
return
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// memref type
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CHECK-LABEL: func @memref_type({{%.*}}: memref<3xi1>) {
|
|
func @memref_type(%arg0: memref<3xi1>) {
|
|
return
|
|
}
|