This commit moves FuncOp out of the builtin dialect, and into the Func dialect. This move has been planned in some capacity from the moment we made FuncOp an operation (years ago). This commit handles the functional aspects of the move, but various aspects are left untouched to ease migration: func::FuncOp is re-exported into mlir to reduce the actual API churn, the assembly format still accepts the unqualified `func`. These temporary measures will remain for a little while to simplify migration before being removed. Differential Revision: https://reviews.llvm.org/D121266
386 lines
16 KiB
MLIR
386 lines
16 KiB
MLIR
// RUN: mlir-opt -pass-pipeline="func.func(convert-arith-to-llvm)" %s -split-input-file | FileCheck %s
|
|
|
|
// CHECK-LABEL: @vector_ops
|
|
func @vector_ops(%arg0: vector<4xf32>, %arg1: vector<4xi1>, %arg2: vector<4xi64>, %arg3: vector<4xi64>) -> vector<4xf32> {
|
|
// CHECK-NEXT: %0 = llvm.mlir.constant(dense<4.200000e+01> : vector<4xf32>) : vector<4xf32>
|
|
%0 = arith.constant dense<42.> : vector<4xf32>
|
|
// CHECK-NEXT: %1 = llvm.fadd %arg0, %0 : vector<4xf32>
|
|
%1 = arith.addf %arg0, %0 : vector<4xf32>
|
|
// CHECK-NEXT: %2 = llvm.sdiv %arg2, %arg2 : vector<4xi64>
|
|
%3 = arith.divsi %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %3 = llvm.udiv %arg2, %arg2 : vector<4xi64>
|
|
%4 = arith.divui %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %4 = llvm.srem %arg2, %arg2 : vector<4xi64>
|
|
%5 = arith.remsi %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %5 = llvm.urem %arg2, %arg2 : vector<4xi64>
|
|
%6 = arith.remui %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %6 = llvm.fdiv %arg0, %0 : vector<4xf32>
|
|
%7 = arith.divf %arg0, %0 : vector<4xf32>
|
|
// CHECK-NEXT: %7 = llvm.frem %arg0, %0 : vector<4xf32>
|
|
%8 = arith.remf %arg0, %0 : vector<4xf32>
|
|
// CHECK-NEXT: %8 = llvm.and %arg2, %arg3 : vector<4xi64>
|
|
%9 = arith.andi %arg2, %arg3 : vector<4xi64>
|
|
// CHECK-NEXT: %9 = llvm.or %arg2, %arg3 : vector<4xi64>
|
|
%10 = arith.ori %arg2, %arg3 : vector<4xi64>
|
|
// CHECK-NEXT: %10 = llvm.xor %arg2, %arg3 : vector<4xi64>
|
|
%11 = arith.xori %arg2, %arg3 : vector<4xi64>
|
|
// CHECK-NEXT: %11 = llvm.shl %arg2, %arg2 : vector<4xi64>
|
|
%12 = arith.shli %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %12 = llvm.ashr %arg2, %arg2 : vector<4xi64>
|
|
%13 = arith.shrsi %arg2, %arg2 : vector<4xi64>
|
|
// CHECK-NEXT: %13 = llvm.lshr %arg2, %arg2 : vector<4xi64>
|
|
%14 = arith.shrui %arg2, %arg2 : vector<4xi64>
|
|
return %1 : vector<4xf32>
|
|
}
|
|
|
|
// CHECK-LABEL: @ops
|
|
func @ops(f32, f32, i32, i32, f64) -> (f32, i32) {
|
|
^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64):
|
|
// CHECK: = llvm.fsub %arg0, %arg1 : f32
|
|
%0 = arith.subf %arg0, %arg1: f32
|
|
// CHECK: = llvm.sub %arg2, %arg3 : i32
|
|
%1 = arith.subi %arg2, %arg3: i32
|
|
// CHECK: = llvm.icmp "slt" %arg2, %1 : i32
|
|
%2 = arith.cmpi slt, %arg2, %1 : i32
|
|
// CHECK: = llvm.sdiv %arg2, %arg3 : i32
|
|
%3 = arith.divsi %arg2, %arg3 : i32
|
|
// CHECK: = llvm.udiv %arg2, %arg3 : i32
|
|
%4 = arith.divui %arg2, %arg3 : i32
|
|
// CHECK: = llvm.srem %arg2, %arg3 : i32
|
|
%5 = arith.remsi %arg2, %arg3 : i32
|
|
// CHECK: = llvm.urem %arg2, %arg3 : i32
|
|
%6 = arith.remui %arg2, %arg3 : i32
|
|
// CHECK: = llvm.fdiv %arg0, %arg1 : f32
|
|
%8 = arith.divf %arg0, %arg1 : f32
|
|
// CHECK: = llvm.frem %arg0, %arg1 : f32
|
|
%9 = arith.remf %arg0, %arg1 : f32
|
|
// CHECK: = llvm.and %arg2, %arg3 : i32
|
|
%10 = arith.andi %arg2, %arg3 : i32
|
|
// CHECK: = llvm.or %arg2, %arg3 : i32
|
|
%11 = arith.ori %arg2, %arg3 : i32
|
|
// CHECK: = llvm.xor %arg2, %arg3 : i32
|
|
%12 = arith.xori %arg2, %arg3 : i32
|
|
// CHECK: = llvm.mlir.constant(7.900000e-01 : f64) : f64
|
|
%15 = arith.constant 7.9e-01 : f64
|
|
// CHECK: = llvm.shl %arg2, %arg3 : i32
|
|
%16 = arith.shli %arg2, %arg3 : i32
|
|
// CHECK: = llvm.ashr %arg2, %arg3 : i32
|
|
%17 = arith.shrsi %arg2, %arg3 : i32
|
|
// CHECK: = llvm.lshr %arg2, %arg3 : i32
|
|
%18 = arith.shrui %arg2, %arg3 : i32
|
|
return %0, %4 : f32, i32
|
|
}
|
|
|
|
// Checking conversion of index types to integers using i1, assuming no target
|
|
// system would have a 1-bit address space. Otherwise, we would have had to
|
|
// make this test dependent on the pointer size on the target system.
|
|
// CHECK-LABEL: @index_cast
|
|
func @index_cast(%arg0: index, %arg1: i1) {
|
|
// CHECK: = llvm.trunc %0 : i{{.*}} to i1
|
|
%0 = arith.index_cast %arg0: index to i1
|
|
// CHECK-NEXT: = llvm.sext %arg1 : i1 to i{{.*}}
|
|
%1 = arith.index_cast %arg1: i1 to index
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: @vector_index_cast
|
|
func @vector_index_cast(%arg0: vector<2xindex>, %arg1: vector<2xi1>) {
|
|
// CHECK: = llvm.trunc %{{.*}} : vector<2xi{{.*}}> to vector<2xi1>
|
|
%0 = arith.index_cast %arg0: vector<2xindex> to vector<2xi1>
|
|
// CHECK-NEXT: = llvm.sext %{{.*}} : vector<2xi1> to vector<2xi{{.*}}>
|
|
%1 = arith.index_cast %arg1: vector<2xi1> to vector<2xindex>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of signed integer types to floating point.
|
|
// CHECK-LABEL: @sitofp
|
|
func @sitofp(%arg0 : i32, %arg1 : i64) {
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : i32 to f32
|
|
%0 = arith.sitofp %arg0: i32 to f32
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : i32 to f64
|
|
%1 = arith.sitofp %arg0: i32 to f64
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : i64 to f32
|
|
%2 = arith.sitofp %arg1: i64 to f32
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : i64 to f64
|
|
%3 = arith.sitofp %arg1: i64 to f64
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer vectors to floating point vector types.
|
|
// CHECK-LABEL: @sitofp_vector
|
|
func @sitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi16> to vector<2xf32>
|
|
%0 = arith.sitofp %arg0: vector<2xi16> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi16> to vector<2xf64>
|
|
%1 = arith.sitofp %arg0: vector<2xi16> to vector<2xf64>
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi32> to vector<2xf32>
|
|
%2 = arith.sitofp %arg1: vector<2xi32> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi32> to vector<2xf64>
|
|
%3 = arith.sitofp %arg1: vector<2xi32> to vector<2xf64>
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi64> to vector<2xf32>
|
|
%4 = arith.sitofp %arg2: vector<2xi64> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.sitofp {{.*}} : vector<2xi64> to vector<2xf64>
|
|
%5 = arith.sitofp %arg2: vector<2xi64> to vector<2xf64>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of unsigned integer types to floating point.
|
|
// CHECK-LABEL: @uitofp
|
|
func @uitofp(%arg0 : i32, %arg1 : i64) {
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : i32 to f32
|
|
%0 = arith.uitofp %arg0: i32 to f32
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : i32 to f64
|
|
%1 = arith.uitofp %arg0: i32 to f64
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : i64 to f32
|
|
%2 = arith.uitofp %arg1: i64 to f32
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : i64 to f64
|
|
%3 = arith.uitofp %arg1: i64 to f64
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer types to floating point.
|
|
// CHECK-LABEL: @fpext
|
|
func @fpext(%arg0 : f16, %arg1 : f32) {
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : f16 to f32
|
|
%0 = arith.extf %arg0: f16 to f32
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : f16 to f64
|
|
%1 = arith.extf %arg0: f16 to f64
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : f32 to f64
|
|
%2 = arith.extf %arg1: f32 to f64
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer types to floating point.
|
|
// CHECK-LABEL: @fpext
|
|
func @fpext_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>) {
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf16> to vector<2xf32>
|
|
%0 = arith.extf %arg0: vector<2xf16> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf16> to vector<2xf64>
|
|
%1 = arith.extf %arg0: vector<2xf16> to vector<2xf64>
|
|
// CHECK-NEXT: = llvm.fpext {{.*}} : vector<2xf32> to vector<2xf64>
|
|
%2 = arith.extf %arg1: vector<2xf32> to vector<2xf64>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of floating point to integer types.
|
|
// CHECK-LABEL: @fptosi
|
|
func @fptosi(%arg0 : f32, %arg1 : f64) {
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : f32 to i32
|
|
%0 = arith.fptosi %arg0: f32 to i32
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : f32 to i64
|
|
%1 = arith.fptosi %arg0: f32 to i64
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : f64 to i32
|
|
%2 = arith.fptosi %arg1: f64 to i32
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : f64 to i64
|
|
%3 = arith.fptosi %arg1: f64 to i64
|
|
return
|
|
}
|
|
|
|
// Checking conversion of floating point vectors to integer vector types.
|
|
// CHECK-LABEL: @fptosi_vector
|
|
func @fptosi_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf16> to vector<2xi32>
|
|
%0 = arith.fptosi %arg0: vector<2xf16> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf16> to vector<2xi64>
|
|
%1 = arith.fptosi %arg0: vector<2xf16> to vector<2xi64>
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf32> to vector<2xi32>
|
|
%2 = arith.fptosi %arg1: vector<2xf32> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf32> to vector<2xi64>
|
|
%3 = arith.fptosi %arg1: vector<2xf32> to vector<2xi64>
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf64> to vector<2xi32>
|
|
%4 = arith.fptosi %arg2: vector<2xf64> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptosi {{.*}} : vector<2xf64> to vector<2xi64>
|
|
%5 = arith.fptosi %arg2: vector<2xf64> to vector<2xi64>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of floating point to integer types.
|
|
// CHECK-LABEL: @fptoui
|
|
func @fptoui(%arg0 : f32, %arg1 : f64) {
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : f32 to i32
|
|
%0 = arith.fptoui %arg0: f32 to i32
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : f32 to i64
|
|
%1 = arith.fptoui %arg0: f32 to i64
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : f64 to i32
|
|
%2 = arith.fptoui %arg1: f64 to i32
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : f64 to i64
|
|
%3 = arith.fptoui %arg1: f64 to i64
|
|
return
|
|
}
|
|
|
|
// Checking conversion of floating point vectors to integer vector types.
|
|
// CHECK-LABEL: @fptoui_vector
|
|
func @fptoui_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) {
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf16> to vector<2xi32>
|
|
%0 = arith.fptoui %arg0: vector<2xf16> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf16> to vector<2xi64>
|
|
%1 = arith.fptoui %arg0: vector<2xf16> to vector<2xi64>
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf32> to vector<2xi32>
|
|
%2 = arith.fptoui %arg1: vector<2xf32> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf32> to vector<2xi64>
|
|
%3 = arith.fptoui %arg1: vector<2xf32> to vector<2xi64>
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf64> to vector<2xi32>
|
|
%4 = arith.fptoui %arg2: vector<2xf64> to vector<2xi32>
|
|
// CHECK-NEXT: = llvm.fptoui {{.*}} : vector<2xf64> to vector<2xi64>
|
|
%5 = arith.fptoui %arg2: vector<2xf64> to vector<2xi64>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer vectors to floating point vector types.
|
|
// CHECK-LABEL: @uitofp_vector
|
|
func @uitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) {
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi16> to vector<2xf32>
|
|
%0 = arith.uitofp %arg0: vector<2xi16> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi16> to vector<2xf64>
|
|
%1 = arith.uitofp %arg0: vector<2xi16> to vector<2xf64>
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi32> to vector<2xf32>
|
|
%2 = arith.uitofp %arg1: vector<2xi32> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi32> to vector<2xf64>
|
|
%3 = arith.uitofp %arg1: vector<2xi32> to vector<2xf64>
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi64> to vector<2xf32>
|
|
%4 = arith.uitofp %arg2: vector<2xi64> to vector<2xf32>
|
|
// CHECK-NEXT: = llvm.uitofp {{.*}} : vector<2xi64> to vector<2xf64>
|
|
%5 = arith.uitofp %arg2: vector<2xi64> to vector<2xf64>
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer types to floating point.
|
|
// CHECK-LABEL: @fptrunc
|
|
func @fptrunc(%arg0 : f32, %arg1 : f64) {
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : f32 to f16
|
|
%0 = arith.truncf %arg0: f32 to f16
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : f64 to f16
|
|
%1 = arith.truncf %arg1: f64 to f16
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : f64 to f32
|
|
%2 = arith.truncf %arg1: f64 to f32
|
|
return
|
|
}
|
|
|
|
// Checking conversion of integer types to floating point.
|
|
// CHECK-LABEL: @fptrunc
|
|
func @fptrunc_vector(%arg0 : vector<2xf32>, %arg1 : vector<2xf64>) {
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf32> to vector<2xf16>
|
|
%0 = arith.truncf %arg0: vector<2xf32> to vector<2xf16>
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf64> to vector<2xf16>
|
|
%1 = arith.truncf %arg1: vector<2xf64> to vector<2xf16>
|
|
// CHECK-NEXT: = llvm.fptrunc {{.*}} : vector<2xf64> to vector<2xf32>
|
|
%2 = arith.truncf %arg1: vector<2xf64> to vector<2xf32>
|
|
return
|
|
}
|
|
|
|
// Check sign and zero extension and truncation of integers.
|
|
// CHECK-LABEL: @integer_extension_and_truncation
|
|
func @integer_extension_and_truncation(%arg0 : i3) {
|
|
// CHECK-NEXT: = llvm.sext %arg0 : i3 to i6
|
|
%0 = arith.extsi %arg0 : i3 to i6
|
|
// CHECK-NEXT: = llvm.zext %arg0 : i3 to i6
|
|
%1 = arith.extui %arg0 : i3 to i6
|
|
// CHECK-NEXT: = llvm.trunc %arg0 : i3 to i2
|
|
%2 = arith.trunci %arg0 : i3 to i2
|
|
return
|
|
}
|
|
|
|
// CHECK-LABEL: func @fcmp(%arg0: f32, %arg1: f32) {
|
|
func @fcmp(f32, f32) -> () {
|
|
^bb0(%arg0: f32, %arg1: f32):
|
|
// CHECK: llvm.fcmp "oeq" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ogt" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "oge" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "olt" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ole" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "one" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ord" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ueq" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ugt" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "uge" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ult" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "ule" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "une" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: llvm.fcmp "uno" %arg0, %arg1 : f32
|
|
// CHECK-NEXT: return
|
|
%1 = arith.cmpf oeq, %arg0, %arg1 : f32
|
|
%2 = arith.cmpf ogt, %arg0, %arg1 : f32
|
|
%3 = arith.cmpf oge, %arg0, %arg1 : f32
|
|
%4 = arith.cmpf olt, %arg0, %arg1 : f32
|
|
%5 = arith.cmpf ole, %arg0, %arg1 : f32
|
|
%6 = arith.cmpf one, %arg0, %arg1 : f32
|
|
%7 = arith.cmpf ord, %arg0, %arg1 : f32
|
|
%8 = arith.cmpf ueq, %arg0, %arg1 : f32
|
|
%9 = arith.cmpf ugt, %arg0, %arg1 : f32
|
|
%10 = arith.cmpf uge, %arg0, %arg1 : f32
|
|
%11 = arith.cmpf ult, %arg0, %arg1 : f32
|
|
%12 = arith.cmpf ule, %arg0, %arg1 : f32
|
|
%13 = arith.cmpf une, %arg0, %arg1 : f32
|
|
%14 = arith.cmpf uno, %arg0, %arg1 : f32
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: @index_vector
|
|
func @index_vector(%arg0: vector<4xindex>) {
|
|
// CHECK: %[[CST:.*]] = llvm.mlir.constant(dense<[0, 1, 2, 3]> : vector<4xindex>) : vector<4xi64>
|
|
%0 = arith.constant dense<[0, 1, 2, 3]> : vector<4xindex>
|
|
// CHECK: %[[V:.*]] = llvm.add %{{.*}}, %[[CST]] : vector<4xi64>
|
|
%1 = arith.addi %arg0, %0 : vector<4xindex>
|
|
func.return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: @bitcast_1d
|
|
func @bitcast_1d(%arg0: vector<2xf32>) {
|
|
// CHECK: llvm.bitcast %{{.*}} : vector<2xf32> to vector<2xi32>
|
|
arith.bitcast %arg0 : vector<2xf32> to vector<2xi32>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: func @cmpf_2dvector(
|
|
func @cmpf_2dvector(%arg0 : vector<4x3xf32>, %arg1 : vector<4x3xf32>) {
|
|
// CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[EXTRACT1:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.array<4 x vector<3xf32>>
|
|
// CHECK: %[[EXTRACT2:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.array<4 x vector<3xf32>>
|
|
// CHECK: %[[CMP:.*]] = llvm.fcmp "olt" %[[EXTRACT1]], %[[EXTRACT2]] : vector<3xf32>
|
|
// CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[CMP]], %2[0] : !llvm.array<4 x vector<3xi1>>
|
|
%0 = arith.cmpf olt, %arg0, %arg1 : vector<4x3xf32>
|
|
func.return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: func @cmpi_0dvector(
|
|
func @cmpi_0dvector(%arg0 : vector<i32>, %arg1 : vector<i32>) {
|
|
// CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[CMP:.*]] = llvm.icmp "ult" %[[ARG0]], %[[ARG1]] : vector<1xi32>
|
|
%0 = arith.cmpi ult, %arg0, %arg1 : vector<i32>
|
|
func.return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: func @cmpi_2dvector(
|
|
func @cmpi_2dvector(%arg0 : vector<4x3xi32>, %arg1 : vector<4x3xi32>) {
|
|
// CHECK: %[[ARG0:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[ARG1:.*]] = builtin.unrealized_conversion_cast
|
|
// CHECK: %[[EXTRACT1:.*]] = llvm.extractvalue %[[ARG0]][0] : !llvm.array<4 x vector<3xi32>>
|
|
// CHECK: %[[EXTRACT2:.*]] = llvm.extractvalue %[[ARG1]][0] : !llvm.array<4 x vector<3xi32>>
|
|
// CHECK: %[[CMP:.*]] = llvm.icmp "ult" %[[EXTRACT1]], %[[EXTRACT2]] : vector<3xi32>
|
|
// CHECK: %[[INSERT:.*]] = llvm.insertvalue %[[CMP]], %2[0] : !llvm.array<4 x vector<3xi1>>
|
|
%0 = arith.cmpi ult, %arg0, %arg1 : vector<4x3xi32>
|
|
func.return
|
|
}
|
|
|
|
// -----
|
|
|
|
// CHECK-LABEL: @select
|
|
func @select(%arg0 : i1, %arg1 : i32, %arg2 : i32) -> i32 {
|
|
// CHECK: = llvm.select %arg0, %arg1, %arg2 : i1, i32
|
|
%0 = arith.select %arg0, %arg1, %arg2 : i32
|
|
return %0 : i32
|
|
}
|