1// RUN: mlir-opt -allow-unregistered-dialect %s | FileCheck %s 2// Verify the printed output can be parsed. 3// RUN: mlir-opt -allow-unregistered-dialect %s | mlir-opt -allow-unregistered-dialect | FileCheck %s 4// Verify the generic form can be parsed. 5// RUN: mlir-opt -allow-unregistered-dialect -mlir-print-op-generic %s | mlir-opt -allow-unregistered-dialect | FileCheck %s 6 7// CHECK: #map = affine_map<(d0) -> (d0 + 1)> 8 9// CHECK: #map1 = affine_map<()[s0] -> (s0 + 1)> 10 11// CHECK-LABEL: func @func_with_ops 12// CHECK-SAME: %[[ARG:.*]]: f32 13func.func @func_with_ops(f32) { 14^bb0(%a : f32): 15 // CHECK: %[[T:.*]] = "getTensor"() : () -> tensor<4x4x?xf32> 16 %t = "getTensor"() : () -> tensor<4x4x?xf32> 17 18 // CHECK: %[[C2:.*]] = arith.constant 2 : index 19 // CHECK-NEXT: %{{.*}} = tensor.dim %[[T]], %[[C2]] : tensor<4x4x?xf32> 20 %c2 = arith.constant 2 : index 21 %t2 = "tensor.dim"(%t, %c2) : (tensor<4x4x?xf32>, index) -> index 22 23 // CHECK: %{{.*}} = arith.addf %[[ARG]], %[[ARG]] : f32 24 %x = "arith.addf"(%a, %a) : (f32,f32) -> (f32) 25 26 // CHECK: return 27 return 28} 29 30// CHECK-LABEL: func @standard_instrs(%arg0: tensor<4x4x?xf32>, %arg1: f32, %arg2: i32, %arg3: index, %arg4: i64, %arg5: f16) { 31func.func @standard_instrs(tensor<4x4x?xf32>, f32, i32, index, i64, f16) { 32^bb42(%t: tensor<4x4x?xf32>, %f: f32, %i: i32, %idx : index, %j: i64, %half: f16): 33 // CHECK: %[[C2:.*]] = arith.constant 2 : index 34 // CHECK: %[[A2:.*]] = tensor.dim %arg0, %[[C2]] : tensor<4x4x?xf32> 35 %c2 = arith.constant 2 : index 36 %a2 = tensor.dim %t, %c2 : tensor<4x4x?xf32> 37 38 // CHECK: %f = constant @func_with_ops : (f32) -> () 39 %10 = constant @func_with_ops : (f32) -> () 40 41 // CHECK: %f_0 = constant @affine_apply : () -> () 42 %11 = constant @affine_apply : () -> () 43 44 // CHECK: %[[I2:.*]] = arith.addi 45 %i2 = arith.addi %i, %i: i32 46 // CHECK: %[[I3:.*]] = arith.addi 47 %i3 = arith.addi %i2, %i : i32 48 // CHECK: %[[I4:.*]] = arith.addi 49 %i4 = arith.addi %i2, %i3 : i32 50 // CHECK: %[[F3:.*]] = arith.addf 51 %f3 = arith.addf %f, %f : f32 52 // CHECK: %[[F4:.*]] = arith.addf 53 %f4 = arith.addf %f, %f3 : f32 54 55 %true = arith.constant true 56 %tci32 = arith.constant dense<0> : tensor<42xi32> 57 %vci32 = arith.constant dense<0> : vector<42xi32> 58 %tci1 = arith.constant dense<1> : tensor<42xi1> 59 %vci1 = arith.constant dense<1> : vector<42xi1> 60 61 // CHECK: %{{.*}} = arith.select %{{.*}}, %arg3, %arg3 : index 62 %21 = arith.select %true, %idx, %idx : index 63 64 // CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : tensor<42xi1>, tensor<42xi32> 65 %22 = arith.select %tci1, %tci32, %tci32 : tensor<42 x i1>, tensor<42 x i32> 66 67 // CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : vector<42xi1>, vector<42xi32> 68 %23 = arith.select %vci1, %vci32, %vci32 : vector<42 x i1>, vector<42 x i32> 69 70 // CHECK: %{{.*}} = arith.select %{{.*}}, %arg3, %arg3 : index 71 %24 = "arith.select"(%true, %idx, %idx) : (i1, index, index) -> index 72 73 // CHECK: %{{.*}} = arith.select %{{.*}}, %{{.*}}, %{{.*}} : tensor<42xi32> 74 %25 = arith.select %true, %tci32, %tci32 : tensor<42 x i32> 75 76 %64 = arith.constant dense<0.> : vector<4 x f32> 77 %tcf32 = arith.constant dense<0.> : tensor<42 x f32> 78 %vcf32 = arith.constant dense<0.> : vector<4 x f32> 79 80 // CHECK: %{{.*}} = arith.cmpf ogt, %{{.*}}, %{{.*}} : f32 81 %65 = arith.cmpf ogt, %f3, %f4 : f32 82 83 // Predicate 0 means ordered equality comparison. 84 // CHECK: %{{.*}} = arith.cmpf oeq, %{{.*}}, %{{.*}} : f32 85 %66 = "arith.cmpf"(%f3, %f4) {predicate = 1} : (f32, f32) -> i1 86 87 // CHECK: %{{.*}} = arith.cmpf olt, %{{.*}}, %{{.*}}: vector<4xf32> 88 %67 = arith.cmpf olt, %vcf32, %vcf32 : vector<4 x f32> 89 90 // CHECK: %{{.*}} = arith.cmpf oeq, %{{.*}}, %{{.*}}: vector<4xf32> 91 %68 = "arith.cmpf"(%vcf32, %vcf32) {predicate = 1} : (vector<4 x f32>, vector<4 x f32>) -> vector<4 x i1> 92 93 // CHECK: %{{.*}} = arith.cmpf oeq, %{{.*}}, %{{.*}}: tensor<42xf32> 94 %69 = arith.cmpf oeq, %tcf32, %tcf32 : tensor<42 x f32> 95 96 // CHECK: %{{.*}} = arith.cmpf oeq, %{{.*}}, %{{.*}}: vector<4xf32> 97 %70 = arith.cmpf oeq, %vcf32, %vcf32 : vector<4 x f32> 98 99 // CHECK: arith.constant true 100 %74 = arith.constant true 101 102 // CHECK: arith.constant false 103 %75 = arith.constant false 104 105 // CHECK: %{{.*}} = math.absf %arg1 : f32 106 %100 = "math.absf"(%f) : (f32) -> f32 107 108 // CHECK: %{{.*}} = math.absf %arg1 : f32 109 %101 = math.absf %f : f32 110 111 // CHECK: %{{.*}} = math.absf %{{.*}}: vector<4xf32> 112 %102 = math.absf %vcf32 : vector<4xf32> 113 114 // CHECK: %{{.*}} = math.absf %arg0 : tensor<4x4x?xf32> 115 %103 = math.absf %t : tensor<4x4x?xf32> 116 117 // CHECK: %{{.*}} = math.ceil %arg1 : f32 118 %104 = "math.ceil"(%f) : (f32) -> f32 119 120 // CHECK: %{{.*}} = math.ceil %arg1 : f32 121 %105 = math.ceil %f : f32 122 123 // CHECK: %{{.*}} = math.ceil %{{.*}}: vector<4xf32> 124 %106 = math.ceil %vcf32 : vector<4xf32> 125 126 // CHECK: %{{.*}} = math.ceil %arg0 : tensor<4x4x?xf32> 127 %107 = math.ceil %t : tensor<4x4x?xf32> 128 129 // CHECK: %{{.*}} = math.copysign %arg1, %arg1 : f32 130 %116 = "math.copysign"(%f, %f) : (f32, f32) -> f32 131 132 // CHECK: %{{.*}} = math.copysign %arg1, %arg1 : f32 133 %117 = math.copysign %f, %f : f32 134 135 // CHECK: %{{.*}} = math.copysign %{{.*}}, %{{.*}}: vector<4xf32> 136 %118 = math.copysign %vcf32, %vcf32 : vector<4xf32> 137 138 // CHECK: %{{.*}} = math.copysign %arg0, %arg0 : tensor<4x4x?xf32> 139 %119 = math.copysign %t, %t : tensor<4x4x?xf32> 140 141 // CHECK: %{{.*}} = math.rsqrt %arg1 : f32 142 %145 = math.rsqrt %f : f32 143 144 // CHECK: math.floor %arg1 : f32 145 %163 = "math.floor"(%f) : (f32) -> f32 146 147 // CHECK: %{{.*}} = math.floor %arg1 : f32 148 %164 = math.floor %f : f32 149 150 // CHECK: %{{.*}} = math.floor %{{.*}}: vector<4xf32> 151 %165 = math.floor %vcf32 : vector<4xf32> 152 153 // CHECK: %{{.*}} = math.floor %arg0 : tensor<4x4x?xf32> 154 %166 = math.floor %t : tensor<4x4x?xf32> 155 156 return 157} 158 159// CHECK-LABEL: func @affine_apply() { 160func.func @affine_apply() { 161 %i = "arith.constant"() {value = 0: index} : () -> index 162 %j = "arith.constant"() {value = 1: index} : () -> index 163 164 // CHECK: affine.apply #map(%c0) 165 %a = "affine.apply" (%i) { map = affine_map<(d0) -> (d0 + 1)> } : 166 (index) -> (index) 167 168 // CHECK: affine.apply #map1()[%c0] 169 %b = affine.apply affine_map<()[x] -> (x+1)>()[%i] 170 171 return 172} 173 174// CHECK-LABEL: func @return_op(%arg0: i32) -> i32 { 175func.func @return_op(%a : i32) -> i32 { 176 // CHECK: return %arg0 : i32 177 "func.return" (%a) : (i32)->() 178} 179 180// CHECK-LABEL: func @calls(%arg0: i32) { 181func.func @calls(%arg0: i32) { 182 // CHECK: %0 = call @return_op(%arg0) : (i32) -> i32 183 %x = call @return_op(%arg0) : (i32) -> i32 184 // CHECK: %1 = call @return_op(%0) : (i32) -> i32 185 %y = call @return_op(%x) : (i32) -> i32 186 // CHECK: %2 = call @return_op(%0) : (i32) -> i32 187 %z = "func.call"(%x) {callee = @return_op} : (i32) -> i32 188 189 // CHECK: %f = constant @affine_apply : () -> () 190 %f = constant @affine_apply : () -> () 191 192 // CHECK: call_indirect %f() : () -> () 193 call_indirect %f() : () -> () 194 195 // CHECK: %f_0 = constant @return_op : (i32) -> i32 196 %f_0 = constant @return_op : (i32) -> i32 197 198 // CHECK: %3 = call_indirect %f_0(%arg0) : (i32) -> i32 199 %2 = call_indirect %f_0(%arg0) : (i32) -> i32 200 201 // CHECK: %4 = call_indirect %f_0(%arg0) : (i32) -> i32 202 %3 = "func.call_indirect"(%f_0, %arg0) : ((i32) -> i32, i32) -> i32 203 204 return 205} 206 207// CHECK-LABEL: func @test_dimop 208// CHECK-SAME: %[[ARG:.*]]: tensor<4x4x?xf32> 209func.func @test_dimop(%arg0: tensor<4x4x?xf32>) { 210 // CHECK: %[[C2:.*]] = arith.constant 2 : index 211 // CHECK: %{{.*}} = tensor.dim %[[ARG]], %[[C2]] : tensor<4x4x?xf32> 212 %c2 = arith.constant 2 : index 213 %0 = tensor.dim %arg0, %c2 : tensor<4x4x?xf32> 214 // use dim as an index to ensure type correctness 215 %1 = affine.apply affine_map<(d0) -> (d0)>(%0) 216 return 217} 218