1// RUN: mlir-opt %s -convert-vector-to-llvm -split-input-file | FileCheck %s 2 3 4func.func @bitcast_f32_to_i32_vector_0d(%input: vector<f32>) -> vector<i32> { 5 %0 = vector.bitcast %input : vector<f32> to vector<i32> 6 return %0 : vector<i32> 7} 8 9// CHECK-LABEL: @bitcast_f32_to_i32_vector_0d 10// CHECK-SAME: %[[input:.*]]: vector<f32> 11// CHECK: %[[vec_f32_1d:.*]] = builtin.unrealized_conversion_cast %[[input]] : vector<f32> to vector<1xf32> 12// CHECK: %[[vec_i32_1d:.*]] = llvm.bitcast %[[vec_f32_1d]] : vector<1xf32> to vector<1xi32> 13// CHECK: %[[vec_i32_0d:.*]] = builtin.unrealized_conversion_cast %[[vec_i32_1d]] : vector<1xi32> to vector<i32> 14// CHECK: return %[[vec_i32_0d]] : vector<i32> 15 16// ----- 17 18func.func @bitcast_f32_to_i32_vector(%input: vector<16xf32>) -> vector<16xi32> { 19 %0 = vector.bitcast %input : vector<16xf32> to vector<16xi32> 20 return %0 : vector<16xi32> 21} 22 23// CHECK-LABEL: @bitcast_f32_to_i32_vector 24// CHECK-SAME: %[[input:.*]]: vector<16xf32> 25// CHECK: llvm.bitcast %[[input]] : vector<16xf32> to vector<16xi32> 26 27// ----- 28 29func.func @bitcast_i8_to_f32_vector(%input: vector<64xi8>) -> vector<16xf32> { 30 %0 = vector.bitcast %input : vector<64xi8> to vector<16xf32> 31 return %0 : vector<16xf32> 32} 33 34// CHECK-LABEL: @bitcast_i8_to_f32_vector 35// CHECK-SAME: %[[input:.*]]: vector<64xi8> 36// CHECK: llvm.bitcast %[[input]] : vector<64xi8> to vector<16xf32> 37 38// ----- 39 40func.func @bitcast_index_to_i8_vector(%input: vector<16xindex>) -> vector<128xi8> { 41 %0 = vector.bitcast %input : vector<16xindex> to vector<128xi8> 42 return %0 : vector<128xi8> 43} 44 45// CHECK-LABEL: @bitcast_index_to_i8_vector 46// CHECK-SAME: %[[input:.*]]: vector<16xindex> 47// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[input]] : vector<16xindex> to vector<16xi64> 48// CHECK: llvm.bitcast %[[T0]] : vector<16xi64> to vector<128xi8> 49 50// ----- 51 52func.func @broadcast_vec0d_from_f32(%arg0: f32) -> vector<f32> { 53 %0 = vector.broadcast %arg0 : f32 to vector<f32> 54 return %0 : vector<f32> 55} 56// CHECK-LABEL: @broadcast_vec0d_from_f32 57// CHECK-SAME: %[[A:.*]]: f32) 58// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]] 59// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<1xf32> to vector<f32> 60// CHECK: return %[[T1]] : vector<f32> 61 62// ----- 63 64func.func @broadcast_vec0d_from_vec0d(%arg0: vector<f32>) -> vector<f32> { 65 %0 = vector.broadcast %arg0 : vector<f32> to vector<f32> 66 return %0 : vector<f32> 67} 68// CHECK-LABEL: @broadcast_vec0d_from_vec0d( 69// CHECK-SAME: %[[A:.*]]: vector<f32>) 70// CHECK: return %[[A]] : vector<f32> 71 72// ----- 73 74func.func @broadcast_vec1d_from_f32(%arg0: f32) -> vector<2xf32> { 75 %0 = vector.broadcast %arg0 : f32 to vector<2xf32> 76 return %0 : vector<2xf32> 77} 78// CHECK-LABEL: @broadcast_vec1d_from_f32 79// CHECK-SAME: %[[A:.*]]: f32) 80// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]] 81// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]] 82// CHECK: return %[[T1]] : vector<2xf32> 83 84// ----- 85 86func.func @broadcast_vec1d_from_index(%arg0: index) -> vector<2xindex> { 87 %0 = vector.broadcast %arg0 : index to vector<2xindex> 88 return %0 : vector<2xindex> 89} 90// CHECK-LABEL: @broadcast_vec1d_from_index 91// CHECK-SAME: %[[A:.*]]: index) 92// CHECK: %[[A1:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64 93// CHECK: %[[T0:.*]] = llvm.insertelement %[[A1]] 94// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]] 95// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<2xi64> to vector<2xindex> 96// CHECK: return %[[T2]] : vector<2xindex> 97 98// ----- 99 100func.func @broadcast_vec2d_from_scalar(%arg0: f32) -> vector<2x3xf32> { 101 %0 = vector.broadcast %arg0 : f32 to vector<2x3xf32> 102 return %0 : vector<2x3xf32> 103} 104// CHECK-LABEL: @broadcast_vec2d_from_scalar( 105// CHECK-SAME: %[[A:.*]]: f32) 106// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]] 107// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]] 108// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0] : !llvm.array<2 x vector<3xf32>> 109// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1] : !llvm.array<2 x vector<3xf32>> 110// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32> 111// CHECK: return %[[T4]] : vector<2x3xf32> 112 113// ----- 114 115func.func @broadcast_vec3d_from_scalar(%arg0: f32) -> vector<2x3x4xf32> { 116 %0 = vector.broadcast %arg0 : f32 to vector<2x3x4xf32> 117 return %0 : vector<2x3x4xf32> 118} 119// CHECK-LABEL: @broadcast_vec3d_from_scalar( 120// CHECK-SAME: %[[A:.*]]: f32) 121// CHECK: %[[T0:.*]] = llvm.insertelement %[[A]] 122// CHECK: %[[T1:.*]] = llvm.shufflevector %[[T0]] 123// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[0, 0] : !llvm.array<2 x array<3 x vector<4xf32>>> 124// ... 125// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %{{.*}}[1, 2] : !llvm.array<2 x array<3 x vector<4xf32>>> 126// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T3]] : !llvm.array<2 x array<3 x vector<4xf32>>> to vector<2x3x4xf32> 127// CHECK: return %[[T4]] : vector<2x3x4xf32> 128 129// ----- 130 131func.func @broadcast_vec1d_from_vec1d(%arg0: vector<2xf32>) -> vector<2xf32> { 132 %0 = vector.broadcast %arg0 : vector<2xf32> to vector<2xf32> 133 return %0 : vector<2xf32> 134} 135// CHECK-LABEL: @broadcast_vec1d_from_vec1d( 136// CHECK-SAME: %[[A:.*]]: vector<2xf32>) 137// CHECK: return %[[A]] : vector<2xf32> 138 139// ----- 140 141func.func @broadcast_vec2d_from_vec0d(%arg0: vector<f32>) -> vector<3x2xf32> { 142 %0 = vector.broadcast %arg0 : vector<f32> to vector<3x2xf32> 143 return %0 : vector<3x2xf32> 144} 145// CHECK-LABEL: @broadcast_vec2d_from_vec0d( 146// CHECK-SAME: %[[A:.*]]: vector<f32>) 147// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32> 148// CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32> 149// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>> 150// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : index) : i64 151// CHECK: %[[T5:.*]] = llvm.extractelement %[[T0]][%[[T4]] : i64] : vector<1xf32> 152// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]] 153// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]] 154// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>> 155// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][1] : !llvm.array<3 x vector<2xf32>> 156// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T6]], %[[T8]][2] : !llvm.array<3 x vector<2xf32>> 157// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32> 158// CHECK: return %[[T10]] : vector<3x2xf32> 159 160// ----- 161 162func.func @broadcast_vec2d_from_vec1d(%arg0: vector<2xf32>) -> vector<3x2xf32> { 163 %0 = vector.broadcast %arg0 : vector<2xf32> to vector<3x2xf32> 164 return %0 : vector<3x2xf32> 165} 166// CHECK-LABEL: @broadcast_vec2d_from_vec1d( 167// CHECK-SAME: %[[A:.*]]: vector<2xf32>) 168// CHECK: %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32> 169// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>> 170// CHECK: %[[T2:.*]] = llvm.insertvalue %[[A]], %[[T1]][0] : !llvm.array<3 x vector<2xf32>> 171// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][1] : !llvm.array<3 x vector<2xf32>> 172// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][2] : !llvm.array<3 x vector<2xf32>> 173// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<3 x vector<2xf32>> to vector<3x2xf32> 174// CHECK: return %[[T5]] : vector<3x2xf32> 175 176// ----- 177 178func.func @broadcast_vec2d_from_index_vec1d(%arg0: vector<2xindex>) -> vector<3x2xindex> { 179 %0 = vector.broadcast %arg0 : vector<2xindex> to vector<3x2xindex> 180 return %0 : vector<3x2xindex> 181} 182// CHECK-LABEL: @broadcast_vec2d_from_index_vec1d( 183// CHECK-SAME: %[[A:.*]]: vector<2xindex>) 184// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64> 185// CHECK: %[[T0:.*]] = arith.constant dense<0> : vector<3x2xindex> 186// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xindex> to !llvm.array<3 x vector<2xi64>> 187// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<3 x vector<2xi64>> 188 189// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %{{.*}} : !llvm.array<3 x vector<2xi64>> to vector<3x2xindex> 190// CHECK: return %[[T4]] : vector<3x2xindex> 191 192// ----- 193 194func.func @broadcast_vec3d_from_vec1d(%arg0: vector<2xf32>) -> vector<4x3x2xf32> { 195 %0 = vector.broadcast %arg0 : vector<2xf32> to vector<4x3x2xf32> 196 return %0 : vector<4x3x2xf32> 197} 198// CHECK-LABEL: @broadcast_vec3d_from_vec1d( 199// CHECK-SAME: %[[A:.*]]: vector<2xf32>) 200// CHECK: %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32> 201// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>> 202// CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32> 203// CHECK: %[[T6:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>> 204 205// CHECK: %[[T3:.*]] = llvm.insertvalue %[[A]], %[[T2]][0] : !llvm.array<3 x vector<2xf32>> 206// CHECK: %[[T4:.*]] = llvm.insertvalue %[[A]], %[[T3]][1] : !llvm.array<3 x vector<2xf32>> 207// CHECK: %[[T5:.*]] = llvm.insertvalue %[[A]], %[[T4]][2] : !llvm.array<3 x vector<2xf32>> 208 209// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T5]], %[[T6]][0] : !llvm.array<4 x array<3 x vector<2xf32>>> 210// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T5]], %[[T7]][1] : !llvm.array<4 x array<3 x vector<2xf32>>> 211// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T5]], %[[T8]][2] : !llvm.array<4 x array<3 x vector<2xf32>>> 212// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T5]], %[[T9]][3] : !llvm.array<4 x array<3 x vector<2xf32>>> 213 214// CHECK: %[[T11:.*]] = builtin.unrealized_conversion_cast %[[T10]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32> 215// CHECK: return %[[T11]] : vector<4x3x2xf32> 216 217// ----- 218 219func.func @broadcast_vec3d_from_vec2d(%arg0: vector<3x2xf32>) -> vector<4x3x2xf32> { 220 %0 = vector.broadcast %arg0 : vector<3x2xf32> to vector<4x3x2xf32> 221 return %0 : vector<4x3x2xf32> 222} 223// CHECK-LABEL: @broadcast_vec3d_from_vec2d( 224// CHECK-SAME: %[[A:.*]]: vector<3x2xf32>) 225// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>> 226// CHECK: %[[T0:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32> 227// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>> 228// CHECK: %[[T3:.*]] = llvm.insertvalue %[[T1]], %[[T2]][0] : !llvm.array<4 x array<3 x vector<2xf32>>> 229// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T1]], %[[T3]][1] : !llvm.array<4 x array<3 x vector<2xf32>>> 230// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T1]], %[[T5]][2] : !llvm.array<4 x array<3 x vector<2xf32>>> 231// CHECK: %[[T9:.*]] = llvm.insertvalue %[[T1]], %[[T7]][3] : !llvm.array<4 x array<3 x vector<2xf32>>> 232// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T9]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32> 233// CHECK: return %[[T10]] : vector<4x3x2xf32> 234 235 236// ----- 237 238func.func @broadcast_stretch(%arg0: vector<1xf32>) -> vector<4xf32> { 239 %0 = vector.broadcast %arg0 : vector<1xf32> to vector<4xf32> 240 return %0 : vector<4xf32> 241} 242// CHECK-LABEL: @broadcast_stretch( 243// CHECK-SAME: %[[A:.*]]: vector<1xf32>) 244// CHECK: %[[T1:.*]] = llvm.mlir.constant(0 : i64) : i64 245// CHECK: %[[T2:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T1]] : i64] : vector<1xf32> 246// CHECK: %[[T3:.*]] = llvm.insertelement %[[T2]] 247// CHECK: %[[T4:.*]] = llvm.shufflevector %[[T3]] 248// CHECK: return %[[T4]] : vector<4xf32> 249 250// ----- 251 252func.func @broadcast_stretch_at_start(%arg0: vector<1x4xf32>) -> vector<3x4xf32> { 253 %0 = vector.broadcast %arg0 : vector<1x4xf32> to vector<3x4xf32> 254 return %0 : vector<3x4xf32> 255} 256// CHECK-LABEL: @broadcast_stretch_at_start( 257// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>) 258// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>> 259// CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<3x4xf32> 260// CHECK: %[[T4:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<3x4xf32> to !llvm.array<3 x vector<4xf32>> 261// CHECK: %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<1 x vector<4xf32>> 262// CHECK: %[[T5:.*]] = llvm.insertvalue %[[T3]], %[[T4]][0] : !llvm.array<3 x vector<4xf32>> 263// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T3]], %[[T5]][1] : !llvm.array<3 x vector<4xf32>> 264// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T3]], %[[T6]][2] : !llvm.array<3 x vector<4xf32>> 265// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32> 266// CHECK: return %[[T8]] : vector<3x4xf32> 267 268// ----- 269 270func.func @broadcast_stretch_at_end(%arg0: vector<4x1xf32>) -> vector<4x3xf32> { 271 %0 = vector.broadcast %arg0 : vector<4x1xf32> to vector<4x3xf32> 272 return %0 : vector<4x3xf32> 273} 274// CHECK-LABEL: @broadcast_stretch_at_end( 275// CHECK-SAME: %[[A:.*]]: vector<4x1xf32>) 276// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1xf32> to !llvm.array<4 x vector<1xf32>> 277// CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3xf32> 278// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3xf32> to !llvm.array<4 x vector<3xf32>> 279// CHECK: %[[T3:.*]] = llvm.extractvalue %[[T2]][0] : !llvm.array<4 x vector<1xf32>> 280// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64 281// CHECK: %[[T5:.*]] = llvm.extractelement %[[T3]]{{\[}}%[[T4]] : i64] : vector<1xf32> 282// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]] 283// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]] 284// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<4 x vector<3xf32>> 285// CHECK: %[[T10:.*]] = llvm.extractvalue %[[T2]][1] : !llvm.array<4 x vector<1xf32>> 286// CHECK: %[[T11:.*]] = llvm.mlir.constant(0 : i64) : i64 287// CHECK: %[[T12:.*]] = llvm.extractelement %[[T10]]{{\[}}%[[T11]] : i64] : vector<1xf32> 288// CHECK: %[[T13Insert:.*]] = llvm.insertelement %[[T12]] 289// CHECK: %[[T13:.*]] = llvm.shufflevector %[[T13Insert]] 290// CHECK: %[[T14:.*]] = llvm.insertvalue %[[T13]], %[[T8]][1] : !llvm.array<4 x vector<3xf32>> 291// CHECK: %[[T16:.*]] = llvm.extractvalue %[[T2]][2] : !llvm.array<4 x vector<1xf32>> 292// CHECK: %[[T17:.*]] = llvm.mlir.constant(0 : i64) : i64 293// CHECK: %[[T18:.*]] = llvm.extractelement %[[T16]]{{\[}}%[[T17]] : i64] : vector<1xf32> 294// CHECK: %[[T19Insert:.*]] = llvm.insertelement %[[T18]] 295// CHECK: %[[T19:.*]] = llvm.shufflevector %[[T19Insert]] 296// CHECK: %[[T20:.*]] = llvm.insertvalue %[[T19]], %[[T14]][2] : !llvm.array<4 x vector<3xf32>> 297// CHECK: %[[T22:.*]] = llvm.extractvalue %[[T2]][3] : !llvm.array<4 x vector<1xf32>> 298// CHECK: %[[T23:.*]] = llvm.mlir.constant(0 : i64) : i64 299// CHECK: %[[T24:.*]] = llvm.extractelement %[[T22]]{{\[}}%[[T23]] : i64] : vector<1xf32> 300// CHECK: %[[T25Insert:.*]] = llvm.insertelement %[[T24]] 301// CHECK: %[[T25:.*]] = llvm.shufflevector %[[T25Insert]] 302// CHECK: %[[T26:.*]] = llvm.insertvalue %[[T25]], %[[T20]][3] : !llvm.array<4 x vector<3xf32>> 303// CHECK: %[[T27:.*]] = builtin.unrealized_conversion_cast %[[T26]] : !llvm.array<4 x vector<3xf32>> to vector<4x3xf32> 304// CHECK: return %[[T27]] : vector<4x3xf32> 305 306// ----- 307 308func.func @broadcast_stretch_in_middle(%arg0: vector<4x1x2xf32>) -> vector<4x3x2xf32> { 309 %0 = vector.broadcast %arg0 : vector<4x1x2xf32> to vector<4x3x2xf32> 310 return %0 : vector<4x3x2xf32> 311} 312// CHECK-LABEL: @broadcast_stretch_in_middle( 313// CHECK-SAME: %[[A:.*]]: vector<4x1x2xf32>) -> vector<4x3x2xf32> { 314// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4x1x2xf32> to !llvm.array<4 x array<1 x vector<2xf32>>> 315// CHECK: %[[T1:.*]] = arith.constant dense<0.000000e+00> : vector<4x3x2xf32> 316// CHECK: %[[T9:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<4x3x2xf32> to !llvm.array<4 x array<3 x vector<2xf32>>> 317// CHECK: %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<3x2xf32> 318// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<3x2xf32> to !llvm.array<3 x vector<2xf32>> 319// CHECK: %[[T4:.*]] = llvm.extractvalue %[[T3]][0, 0] : !llvm.array<4 x array<1 x vector<2xf32>>> 320// CHECK: %[[T6:.*]] = llvm.insertvalue %[[T4]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>> 321// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T4]], %[[T6]][1] : !llvm.array<3 x vector<2xf32>> 322// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T4]], %[[T7]][2] : !llvm.array<3 x vector<2xf32>> 323// CHECK: %[[T10:.*]] = llvm.insertvalue %[[T8]], %[[T9]][0] : !llvm.array<4 x array<3 x vector<2xf32>>> 324// CHECK: %[[T12:.*]] = llvm.extractvalue %[[T3]][1, 0] : !llvm.array<4 x array<1 x vector<2xf32>>> 325// CHECK: %[[T14:.*]] = llvm.insertvalue %[[T12]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>> 326// CHECK: %[[T15:.*]] = llvm.insertvalue %[[T12]], %[[T14]][1] : !llvm.array<3 x vector<2xf32>> 327// CHECK: %[[T16:.*]] = llvm.insertvalue %[[T12]], %[[T15]][2] : !llvm.array<3 x vector<2xf32>> 328// CHECK: %[[T17:.*]] = llvm.insertvalue %[[T16]], %[[T10]][1] : !llvm.array<4 x array<3 x vector<2xf32>>> 329// CHECK: %[[T19:.*]] = llvm.extractvalue %[[T3]][2, 0] : !llvm.array<4 x array<1 x vector<2xf32>>> 330// CHECK: %[[T21:.*]] = llvm.insertvalue %[[T19]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>> 331// CHECK: %[[T22:.*]] = llvm.insertvalue %[[T19]], %[[T21]][1] : !llvm.array<3 x vector<2xf32>> 332// CHECK: %[[T23:.*]] = llvm.insertvalue %[[T19]], %[[T22]][2] : !llvm.array<3 x vector<2xf32>> 333// CHECK: %[[T24:.*]] = llvm.insertvalue %[[T23]], %[[T17]][2] : !llvm.array<4 x array<3 x vector<2xf32>>> 334// CHECK: %[[T26:.*]] = llvm.extractvalue %[[T3]][3, 0] : !llvm.array<4 x array<1 x vector<2xf32>>> 335// CHECK: %[[T28:.*]] = llvm.insertvalue %[[T26]], %[[T5]][0] : !llvm.array<3 x vector<2xf32>> 336// CHECK: %[[T29:.*]] = llvm.insertvalue %[[T26]], %[[T28]][1] : !llvm.array<3 x vector<2xf32>> 337// CHECK: %[[T30:.*]] = llvm.insertvalue %[[T26]], %[[T29]][2] : !llvm.array<3 x vector<2xf32>> 338// CHECK: %[[T31:.*]] = llvm.insertvalue %[[T30]], %[[T24]][3] : !llvm.array<4 x array<3 x vector<2xf32>>> 339// CHECK: %[[T32:.*]] = builtin.unrealized_conversion_cast %[[T31]] : !llvm.array<4 x array<3 x vector<2xf32>>> to vector<4x3x2xf32> 340// CHECK: return %[[T32]] : vector<4x3x2xf32> 341 342// ----- 343 344func.func @outerproduct(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<2x3xf32> { 345 %2 = vector.outerproduct %arg0, %arg1 : vector<2xf32>, vector<3xf32> 346 return %2 : vector<2x3xf32> 347} 348// CHECK-LABEL: @outerproduct( 349// CHECK-SAME: %[[A:.*]]: vector<2xf32>, 350// CHECK-SAME: %[[B:.*]]: vector<3xf32>) 351// CHECK: %[[T2:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32> 352// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>> 353// CHECK: %[[T3:.*]] = llvm.mlir.constant(0 : i64) : i64 354// CHECK: %[[T4:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T3]] : i64] : vector<2xf32> 355// CHECK: %[[T5Insert:.*]] = llvm.insertelement %[[T4]] 356// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T5Insert]] 357// CHECK: %[[T6:.*]] = arith.mulf %[[T5]], %[[B]] : vector<3xf32> 358// CHECK: %[[T8:.*]] = llvm.insertvalue %[[T6]], %[[T7]][0] : !llvm.array<2 x vector<3xf32>> 359// CHECK: %[[T9:.*]] = llvm.mlir.constant(1 : i64) : i64 360// CHECK: %[[T10:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T9]] : i64] : vector<2xf32> 361// CHECK: %[[T11Insert:.*]] = llvm.insertelement %[[T10]] 362// CHECK: %[[T11:.*]] = llvm.shufflevector %[[T11Insert]] 363// CHECK: %[[T12:.*]] = arith.mulf %[[T11]], %[[B]] : vector<3xf32> 364// CHECK: %[[T13:.*]] = llvm.insertvalue %[[T12]], %[[T8]][1] : !llvm.array<2 x vector<3xf32>> 365// CHECK: %[[T14:.*]] = builtin.unrealized_conversion_cast %[[T13]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32> 366// CHECK: return %[[T14]] : vector<2x3xf32> 367 368// ----- 369 370func.func @outerproduct_index(%arg0: vector<2xindex>, %arg1: vector<3xindex>) -> vector<2x3xindex> { 371 %2 = vector.outerproduct %arg0, %arg1 : vector<2xindex>, vector<3xindex> 372 return %2 : vector<2x3xindex> 373} 374// CHECK-LABEL: @outerproduct_index( 375// CHECK-SAME: %[[A:.*]]: vector<2xindex>, 376// CHECK-SAME: %[[B:.*]]: vector<3xindex>) 377// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2xindex> to vector<2xi64> 378// CHECK: %[[T0:.*]] = arith.constant dense<0> : vector<2x3xindex> 379// CHECK: %[[T8:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<2x3xindex> to !llvm.array<2 x vector<3xi64>> 380// CHECK: %[[T2:.*]] = llvm.mlir.constant(0 : i64) : i64 381// CHECK: %[[T3:.*]] = llvm.extractelement %[[T1]]{{\[}}%[[T2]] : i64] : vector<2xi64> 382// CHECK: %[[T4:.*]] = llvm.insertelement %[[T3]] 383// CHECK: %[[T5:.*]] = llvm.shufflevector %[[T4]] 384// CHECK: %[[T5Cast:.*]] = builtin.unrealized_conversion_cast %[[T5]] : vector<3xi64> to vector<3xindex> 385// CHECK: %[[T6:.*]] = arith.muli %[[T5Cast]], %[[B]] : vector<3xindex> 386// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[T6]] : vector<3xindex> to vector<3xi64> 387// CHECK: %{{.*}} = llvm.insertvalue %[[T7]], %[[T8]][0] : !llvm.array<2 x vector<3xi64>> 388 389// ----- 390 391func.func @outerproduct_add(%arg0: vector<2xf32>, %arg1: vector<3xf32>, %arg2: vector<2x3xf32>) -> vector<2x3xf32> { 392 %2 = vector.outerproduct %arg0, %arg1, %arg2 : vector<2xf32>, vector<3xf32> 393 return %2 : vector<2x3xf32> 394} 395// CHECK-LABEL: @outerproduct_add( 396// CHECK-SAME: %[[A:.*]]: vector<2xf32>, 397// CHECK-SAME: %[[B:.*]]: vector<3xf32>, 398// CHECK-SAME: %[[C:.*]]: vector<2x3xf32>) -> vector<2x3xf32> 399// CHECK: %[[T7:.*]] = builtin.unrealized_conversion_cast %[[C]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>> 400// CHECK: %[[T3:.*]] = arith.constant dense<0.000000e+00> : vector<2x3xf32> 401// CHECK: %[[T10:.*]] = builtin.unrealized_conversion_cast %[[T3]] : vector<2x3xf32> to !llvm.array<2 x vector<3xf32>> 402// CHECK: %[[T4:.*]] = llvm.mlir.constant(0 : i64) : i64 403// CHECK: %[[T5:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T4]] : i64] : vector<2xf32> 404// CHECK: %[[T6Insert:.*]] = llvm.insertelement %[[T5]] 405// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T6Insert]] 406// CHECK: %[[T8:.*]] = llvm.extractvalue %[[T7]][0] : !llvm.array<2 x vector<3xf32>> 407// CHECK: %[[T9:.*]] = "llvm.intr.fmuladd"(%[[T6]], %[[B]], %[[T8]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32> 408// CHECK: %[[T11:.*]] = llvm.insertvalue %[[T9]], %[[T10]][0] : !llvm.array<2 x vector<3xf32>> 409// CHECK: %[[T12:.*]] = llvm.mlir.constant(1 : i64) : i64 410// CHECK: %[[T13:.*]] = llvm.extractelement %[[A]]{{\[}}%[[T12]] : i64] : vector<2xf32> 411// CHECK: %[[T14Insert:.*]] = llvm.insertelement %[[T13]] 412// CHECK: %[[T14:.*]] = llvm.shufflevector %[[T14Insert]] 413// CHECK: %[[T16:.*]] = llvm.extractvalue %[[T7]][1] : !llvm.array<2 x vector<3xf32>> 414// CHECK: %[[T17:.*]] = "llvm.intr.fmuladd"(%[[T14]], %[[B]], %[[T16]]) : (vector<3xf32>, vector<3xf32>, vector<3xf32>) -> vector<3xf32> 415// CHECK: %[[T18:.*]] = llvm.insertvalue %[[T17]], %[[T11]][1] : !llvm.array<2 x vector<3xf32>> 416// CHECK: %[[T19:.*]] = builtin.unrealized_conversion_cast %[[T18]] : !llvm.array<2 x vector<3xf32>> to vector<2x3xf32> 417// CHECK: return %[[T19]] : vector<2x3xf32> 418 419// ----- 420 421func.func @shuffle_1D_direct(%arg0: vector<2xf32>, %arg1: vector<2xf32>) -> vector<2xf32> { 422 %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xf32>, vector<2xf32> 423 return %1 : vector<2xf32> 424} 425// CHECK-LABEL: @shuffle_1D_direct( 426// CHECK-SAME: %[[A:.*]]: vector<2xf32>, 427// CHECK-SAME: %[[B:.*]]: vector<2xf32>) 428// CHECK: return %[[A:.*]]: vector<2xf32> 429 430// ----- 431 432func.func @shuffle_1D_index_direct(%arg0: vector<2xindex>, %arg1: vector<2xindex>) -> vector<2xindex> { 433 %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xindex>, vector<2xindex> 434 return %1 : vector<2xindex> 435} 436// CHECK-LABEL: @shuffle_1D_index_direct( 437// CHECK-SAME: %[[A:.*]]: vector<2xindex>, 438// CHECK-SAME: %[[B:.*]]: vector<2xindex>) 439// CHECK: return %[[A:.*]]: vector<2xindex> 440 441// ----- 442 443func.func @shuffle_1D(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<5xf32> { 444 %1 = vector.shuffle %arg0, %arg1 [4, 3, 2, 1, 0] : vector<2xf32>, vector<3xf32> 445 return %1 : vector<5xf32> 446} 447// CHECK-LABEL: @shuffle_1D( 448// CHECK-SAME: %[[A:.*]]: vector<2xf32>, 449// CHECK-SAME: %[[B:.*]]: vector<3xf32>) 450// CHECK: %[[u0:.*]] = llvm.mlir.undef : vector<5xf32> 451// CHECK: %[[c2:.*]] = llvm.mlir.constant(2 : index) : i64 452// CHECK: %[[e1:.*]] = llvm.extractelement %[[B]][%[[c2]] : i64] : vector<3xf32> 453// CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64 454// CHECK: %[[i1:.*]] = llvm.insertelement %[[e1]], %[[u0]][%[[c0]] : i64] : vector<5xf32> 455// CHECK: %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64 456// CHECK: %[[e2:.*]] = llvm.extractelement %[[B]][%[[c1]] : i64] : vector<3xf32> 457// CHECK: %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64 458// CHECK: %[[i2:.*]] = llvm.insertelement %[[e2]], %[[i1]][%[[c1]] : i64] : vector<5xf32> 459// CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64 460// CHECK: %[[e3:.*]] = llvm.extractelement %[[B]][%[[c0]] : i64] : vector<3xf32> 461// CHECK: %[[c2:.*]] = llvm.mlir.constant(2 : index) : i64 462// CHECK: %[[i3:.*]] = llvm.insertelement %[[e3]], %[[i2]][%[[c2]] : i64] : vector<5xf32> 463// CHECK: %[[c1:.*]] = llvm.mlir.constant(1 : index) : i64 464// CHECK: %[[e4:.*]] = llvm.extractelement %[[A]][%[[c1]] : i64] : vector<2xf32> 465// CHECK: %[[c3:.*]] = llvm.mlir.constant(3 : index) : i64 466// CHECK: %[[i4:.*]] = llvm.insertelement %[[e4]], %[[i3]][%[[c3]] : i64] : vector<5xf32> 467// CHECK: %[[c0:.*]] = llvm.mlir.constant(0 : index) : i64 468// CHECK: %[[e5:.*]] = llvm.extractelement %[[A]][%[[c0]] : i64] : vector<2xf32> 469// CHECK: %[[c4:.*]] = llvm.mlir.constant(4 : index) : i64 470// CHECK: %[[i5:.*]] = llvm.insertelement %[[e5]], %[[i4]][%[[c4]] : i64] : vector<5xf32> 471// CHECK: return %[[i5]] : vector<5xf32> 472 473// ----- 474 475func.func @shuffle_2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> { 476 %1 = vector.shuffle %a, %b[1, 0, 2] : vector<1x4xf32>, vector<2x4xf32> 477 return %1 : vector<3x4xf32> 478} 479// CHECK-LABEL: @shuffle_2D( 480// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>, 481// CHECK-SAME: %[[B:.*]]: vector<2x4xf32>) 482// CHECK-DAG: %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>> 483// CHECK-DAG: %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>> 484// CHECK: %[[u0:.*]] = llvm.mlir.undef : !llvm.array<3 x vector<4xf32>> 485// CHECK: %[[e1:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<4xf32>> 486// CHECK: %[[i1:.*]] = llvm.insertvalue %[[e1]], %[[u0]][0] : !llvm.array<3 x vector<4xf32>> 487// CHECK: %[[e2:.*]] = llvm.extractvalue %[[VAL_0]][0] : !llvm.array<1 x vector<4xf32>> 488// CHECK: %[[i2:.*]] = llvm.insertvalue %[[e2]], %[[i1]][1] : !llvm.array<3 x vector<4xf32>> 489// CHECK: %[[e3:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<4xf32>> 490// CHECK: %[[i3:.*]] = llvm.insertvalue %[[e3]], %[[i2]][2] : !llvm.array<3 x vector<4xf32>> 491// CHECK: %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[i3]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32> 492// CHECK: return %[[VAL_3]] : vector<3x4xf32> 493 494// ----- 495 496// CHECK-LABEL: @extract_element_0d 497func.func @extract_element_0d(%a: vector<f32>) -> f32 { 498 // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64 499 // CHECK: llvm.extractelement %{{.*}}[%[[C0]] : {{.*}}] : vector<1xf32> 500 %1 = vector.extractelement %a[] : vector<f32> 501 return %1 : f32 502} 503 504// ----- 505 506func.func @extract_element(%arg0: vector<16xf32>) -> f32 { 507 %0 = arith.constant 15 : i32 508 %1 = vector.extractelement %arg0[%0 : i32]: vector<16xf32> 509 return %1 : f32 510} 511// CHECK-LABEL: @extract_element( 512// CHECK-SAME: %[[A:.*]]: vector<16xf32>) 513// CHECK: %[[c:.*]] = arith.constant 15 : i32 514// CHECK: %[[x:.*]] = llvm.extractelement %[[A]][%[[c]] : i32] : vector<16xf32> 515// CHECK: return %[[x]] : f32 516 517// ----- 518 519func.func @extract_element_index(%arg0: vector<16xf32>) -> f32 { 520 %0 = arith.constant 15 : index 521 %1 = vector.extractelement %arg0[%0 : index]: vector<16xf32> 522 return %1 : f32 523} 524// CHECK-LABEL: @extract_element_index( 525// CHECK-SAME: %[[A:.*]]: vector<16xf32>) 526// CHECK: %[[c:.*]] = arith.constant 15 : index 527// CHECK: %[[i:.*]] = builtin.unrealized_conversion_cast %[[c]] : index to i64 528// CHECK: %[[x:.*]] = llvm.extractelement %[[A]][%[[i]] : i64] : vector<16xf32> 529// CHECK: return %[[x]] : f32 530 531// ----- 532 533func.func @extract_element_from_vec_1d(%arg0: vector<16xf32>) -> f32 { 534 %0 = vector.extract %arg0[15]: vector<16xf32> 535 return %0 : f32 536} 537// CHECK-LABEL: @extract_element_from_vec_1d 538// CHECK: llvm.mlir.constant(15 : i64) : i64 539// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32> 540// CHECK: return {{.*}} : f32 541 542// ----- 543 544func.func @extract_index_element_from_vec_1d(%arg0: vector<16xindex>) -> index { 545 %0 = vector.extract %arg0[15]: vector<16xindex> 546 return %0 : index 547} 548// CHECK-LABEL: @extract_index_element_from_vec_1d( 549// CHECK-SAME: %[[A:.*]]: vector<16xindex>) 550// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64> 551// CHECK: %[[T1:.*]] = llvm.mlir.constant(15 : i64) : i64 552// CHECK: %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<16xi64> 553// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : i64 to index 554// CHECK: return %[[T3]] : index 555 556// ----- 557 558func.func @extract_vec_2d_from_vec_3d(%arg0: vector<4x3x16xf32>) -> vector<3x16xf32> { 559 %0 = vector.extract %arg0[0]: vector<4x3x16xf32> 560 return %0 : vector<3x16xf32> 561} 562// CHECK-LABEL: @extract_vec_2d_from_vec_3d 563// CHECK: llvm.extractvalue {{.*}}[0] : !llvm.array<4 x array<3 x vector<16xf32>>> 564// CHECK: return {{.*}} : vector<3x16xf32> 565 566// ----- 567 568func.func @extract_vec_1d_from_vec_3d(%arg0: vector<4x3x16xf32>) -> vector<16xf32> { 569 %0 = vector.extract %arg0[0, 0]: vector<4x3x16xf32> 570 return %0 : vector<16xf32> 571} 572// CHECK-LABEL: @extract_vec_1d_from_vec_3d 573// CHECK: llvm.extractvalue {{.*}}[0, 0] : !llvm.array<4 x array<3 x vector<16xf32>>> 574// CHECK: return {{.*}} : vector<16xf32> 575 576// ----- 577 578func.func @extract_element_from_vec_3d(%arg0: vector<4x3x16xf32>) -> f32 { 579 %0 = vector.extract %arg0[0, 0, 0]: vector<4x3x16xf32> 580 return %0 : f32 581} 582// CHECK-LABEL: @extract_element_from_vec_3d 583// CHECK: llvm.extractvalue {{.*}}[0, 0] : !llvm.array<4 x array<3 x vector<16xf32>>> 584// CHECK: llvm.mlir.constant(0 : i64) : i64 585// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32> 586// CHECK: return {{.*}} : f32 587 588// ----- 589 590// CHECK-LABEL: @insert_element_0d 591// CHECK-SAME: %[[A:.*]]: f32, 592func.func @insert_element_0d(%a: f32, %b: vector<f32>) -> vector<f32> { 593 // CHECK: %[[B:.*]] = builtin.unrealized_conversion_cast %{{.*}} : 594 // CHECK: vector<f32> to vector<1xf32> 595 // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64 596 // CHECK: %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[C0]] : {{.*}}] : vector<1xf32> 597 %1 = vector.insertelement %a, %b[] : vector<f32> 598 return %1 : vector<f32> 599} 600 601// ----- 602 603func.func @insert_element(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> { 604 %0 = arith.constant 3 : i32 605 %1 = vector.insertelement %arg0, %arg1[%0 : i32] : vector<4xf32> 606 return %1 : vector<4xf32> 607} 608// CHECK-LABEL: @insert_element( 609// CHECK-SAME: %[[A:.*]]: f32, 610// CHECK-SAME: %[[B:.*]]: vector<4xf32>) 611// CHECK: %[[c:.*]] = arith.constant 3 : i32 612// CHECK: %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[c]] : i32] : vector<4xf32> 613// CHECK: return %[[x]] : vector<4xf32> 614 615// ----- 616 617func.func @insert_element_index(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> { 618 %0 = arith.constant 3 : index 619 %1 = vector.insertelement %arg0, %arg1[%0 : index] : vector<4xf32> 620 return %1 : vector<4xf32> 621} 622// CHECK-LABEL: @insert_element_index( 623// CHECK-SAME: %[[A:.*]]: f32, 624// CHECK-SAME: %[[B:.*]]: vector<4xf32>) 625// CHECK: %[[c:.*]] = arith.constant 3 : index 626// CHECK: %[[i:.*]] = builtin.unrealized_conversion_cast %[[c]] : index to i64 627// CHECK: %[[x:.*]] = llvm.insertelement %[[A]], %[[B]][%[[i]] : i64] : vector<4xf32> 628// CHECK: return %[[x]] : vector<4xf32> 629 630// ----- 631 632func.func @insert_element_into_vec_1d(%arg0: f32, %arg1: vector<4xf32>) -> vector<4xf32> { 633 %0 = vector.insert %arg0, %arg1[3] : f32 into vector<4xf32> 634 return %0 : vector<4xf32> 635} 636// CHECK-LABEL: @insert_element_into_vec_1d 637// CHECK: llvm.mlir.constant(3 : i64) : i64 638// CHECK: llvm.insertelement {{.*}}, {{.*}}[{{.*}} : i64] : vector<4xf32> 639// CHECK: return {{.*}} : vector<4xf32> 640 641// ----- 642 643func.func @insert_index_element_into_vec_1d(%arg0: index, %arg1: vector<4xindex>) -> vector<4xindex> { 644 %0 = vector.insert %arg0, %arg1[3] : index into vector<4xindex> 645 return %0 : vector<4xindex> 646} 647// CHECK-LABEL: @insert_index_element_into_vec_1d( 648// CHECK-SAME: %[[A:.*]]: index, 649// CHECK-SAME: %[[B:.*]]: vector<4xindex>) 650// CHECK-DAG: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64 651// CHECK-DAG: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<4xindex> to vector<4xi64> 652// CHECK: %[[T3:.*]] = llvm.mlir.constant(3 : i64) : i64 653// CHECK: %[[T4:.*]] = llvm.insertelement %[[T0]], %[[T1]][%[[T3]] : i64] : vector<4xi64> 654// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : vector<4xi64> to vector<4xindex> 655// CHECK: return %[[T5]] : vector<4xindex> 656 657// ----- 658 659func.func @insert_vec_2d_into_vec_3d(%arg0: vector<8x16xf32>, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 660 %0 = vector.insert %arg0, %arg1[3] : vector<8x16xf32> into vector<4x8x16xf32> 661 return %0 : vector<4x8x16xf32> 662} 663// CHECK-LABEL: @insert_vec_2d_into_vec_3d 664// CHECK: llvm.insertvalue {{.*}}, {{.*}}[3] : !llvm.array<4 x array<8 x vector<16xf32>>> 665// CHECK: return {{.*}} : vector<4x8x16xf32> 666 667// ----- 668 669func.func @insert_vec_1d_into_vec_3d(%arg0: vector<16xf32>, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 670 %0 = vector.insert %arg0, %arg1[3, 7] : vector<16xf32> into vector<4x8x16xf32> 671 return %0 : vector<4x8x16xf32> 672} 673// CHECK-LABEL: @insert_vec_1d_into_vec_3d 674// CHECK: llvm.insertvalue {{.*}}, {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>> 675// CHECK: return {{.*}} : vector<4x8x16xf32> 676 677// ----- 678 679func.func @insert_element_into_vec_3d(%arg0: f32, %arg1: vector<4x8x16xf32>) -> vector<4x8x16xf32> { 680 %0 = vector.insert %arg0, %arg1[3, 7, 15] : f32 into vector<4x8x16xf32> 681 return %0 : vector<4x8x16xf32> 682} 683// CHECK-LABEL: @insert_element_into_vec_3d 684// CHECK: llvm.extractvalue {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>> 685// CHECK: llvm.mlir.constant(15 : i64) : i64 686// CHECK: llvm.insertelement {{.*}}, {{.*}}[{{.*}} : i64] : vector<16xf32> 687// CHECK: llvm.insertvalue {{.*}}, {{.*}}[3, 7] : !llvm.array<4 x array<8 x vector<16xf32>>> 688// CHECK: return {{.*}} : vector<4x8x16xf32> 689 690// ----- 691 692func.func @vector_type_cast(%arg0: memref<8x8x8xf32>) -> memref<vector<8x8x8xf32>> { 693 %0 = vector.type_cast %arg0: memref<8x8x8xf32> to memref<vector<8x8x8xf32>> 694 return %0 : memref<vector<8x8x8xf32>> 695} 696// CHECK-LABEL: @vector_type_cast 697// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)> 698// CHECK: %[[allocated:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<3 x i64>, array<3 x i64>)> 699// CHECK: %[[allocatedBit:.*]] = llvm.bitcast %[[allocated]] : !llvm.ptr<f32> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>> 700// CHECK: llvm.insertvalue %[[allocatedBit]], {{.*}}[0] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)> 701// CHECK: %[[aligned:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<3 x i64>, array<3 x i64>)> 702// CHECK: %[[alignedBit:.*]] = llvm.bitcast %[[aligned]] : !llvm.ptr<f32> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>> 703// CHECK: llvm.insertvalue %[[alignedBit]], {{.*}}[1] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)> 704// CHECK: llvm.mlir.constant(0 : index 705// CHECK: llvm.insertvalue {{.*}}[2] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>>, ptr<array<8 x array<8 x vector<8xf32>>>>, i64)> 706 707// ----- 708 709func.func @vector_index_type_cast(%arg0: memref<8x8x8xindex>) -> memref<vector<8x8x8xindex>> { 710 %0 = vector.type_cast %arg0: memref<8x8x8xindex> to memref<vector<8x8x8xindex>> 711 return %0 : memref<vector<8x8x8xindex>> 712} 713// CHECK-LABEL: @vector_index_type_cast( 714// CHECK-SAME: %[[A:.*]]: memref<8x8x8xindex>) 715// CHECK: %{{.*}} = builtin.unrealized_conversion_cast %[[A]] : memref<8x8x8xindex> to !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<3 x i64>, array<3 x i64>)> 716 717// CHECK: %{{.*}} = builtin.unrealized_conversion_cast %{{.*}} : !llvm.struct<(ptr<array<8 x array<8 x vector<8xi64>>>>, ptr<array<8 x array<8 x vector<8xi64>>>>, i64)> to memref<vector<8x8x8xindex>> 718 719// ----- 720 721func.func @vector_type_cast_non_zero_addrspace(%arg0: memref<8x8x8xf32, 3>) -> memref<vector<8x8x8xf32>, 3> { 722 %0 = vector.type_cast %arg0: memref<8x8x8xf32, 3> to memref<vector<8x8x8xf32>, 3> 723 return %0 : memref<vector<8x8x8xf32>, 3> 724} 725// CHECK-LABEL: @vector_type_cast_non_zero_addrspace 726// CHECK: llvm.mlir.undef : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)> 727// CHECK: %[[allocated:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.struct<(ptr<f32, 3>, ptr<f32, 3>, i64, array<3 x i64>, array<3 x i64>)> 728// CHECK: %[[allocatedBit:.*]] = llvm.bitcast %[[allocated]] : !llvm.ptr<f32, 3> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>, 3> 729// CHECK: llvm.insertvalue %[[allocatedBit]], {{.*}}[0] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)> 730// CHECK: %[[aligned:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.struct<(ptr<f32, 3>, ptr<f32, 3>, i64, array<3 x i64>, array<3 x i64>)> 731// CHECK: %[[alignedBit:.*]] = llvm.bitcast %[[aligned]] : !llvm.ptr<f32, 3> to !llvm.ptr<array<8 x array<8 x vector<8xf32>>>, 3> 732// CHECK: llvm.insertvalue %[[alignedBit]], {{.*}}[1] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)> 733// CHECK: llvm.mlir.constant(0 : index 734// CHECK: llvm.insertvalue {{.*}}[2] : !llvm.struct<(ptr<array<8 x array<8 x vector<8xf32>>>, 3>, ptr<array<8 x array<8 x vector<8xf32>>>, 3>, i64)> 735 736// ----- 737 738func.func @vector_print_scalar_i1(%arg0: i1) { 739 vector.print %arg0 : i1 740 return 741} 742// 743// Type "boolean" always uses zero extension. 744// 745// CHECK-LABEL: @vector_print_scalar_i1( 746// CHECK-SAME: %[[A:.*]]: i1) 747// CHECK: %[[S:.*]] = arith.extui %[[A]] : i1 to i64 748// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 749// CHECK: llvm.call @printNewline() : () -> () 750 751// ----- 752 753func.func @vector_print_scalar_i4(%arg0: i4) { 754 vector.print %arg0 : i4 755 return 756} 757// CHECK-LABEL: @vector_print_scalar_i4( 758// CHECK-SAME: %[[A:.*]]: i4) 759// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i4 to i64 760// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 761// CHECK: llvm.call @printNewline() : () -> () 762 763// ----- 764 765func.func @vector_print_scalar_si4(%arg0: si4) { 766 vector.print %arg0 : si4 767 return 768} 769// CHECK-LABEL: @vector_print_scalar_si4( 770// CHECK-SAME: %[[A:.*]]: si4) 771// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si4 to i4 772// CHECK: %[[S:.*]] = arith.extsi %[[C]] : i4 to i64 773// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 774// CHECK: llvm.call @printNewline() : () -> () 775 776// ----- 777 778func.func @vector_print_scalar_ui4(%arg0: ui4) { 779 vector.print %arg0 : ui4 780 return 781} 782// CHECK-LABEL: @vector_print_scalar_ui4( 783// CHECK-SAME: %[[A:.*]]: ui4) 784// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui4 to i4 785// CHECK: %[[S:.*]] = arith.extui %[[C]] : i4 to i64 786// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> () 787// CHECK: llvm.call @printNewline() : () -> () 788 789// ----- 790 791func.func @vector_print_scalar_i32(%arg0: i32) { 792 vector.print %arg0 : i32 793 return 794} 795// CHECK-LABEL: @vector_print_scalar_i32( 796// CHECK-SAME: %[[A:.*]]: i32) 797// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i32 to i64 798// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 799// CHECK: llvm.call @printNewline() : () -> () 800 801// ----- 802 803func.func @vector_print_scalar_ui32(%arg0: ui32) { 804 vector.print %arg0 : ui32 805 return 806} 807// CHECK-LABEL: @vector_print_scalar_ui32( 808// CHECK-SAME: %[[A:.*]]: ui32) 809// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui32 to i32 810// CHECK: %[[S:.*]] = arith.extui %[[C]] : i32 to i64 811// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> () 812 813// ----- 814 815func.func @vector_print_scalar_i40(%arg0: i40) { 816 vector.print %arg0 : i40 817 return 818} 819// CHECK-LABEL: @vector_print_scalar_i40( 820// CHECK-SAME: %[[A:.*]]: i40) 821// CHECK: %[[S:.*]] = arith.extsi %[[A]] : i40 to i64 822// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 823// CHECK: llvm.call @printNewline() : () -> () 824 825// ----- 826 827func.func @vector_print_scalar_si40(%arg0: si40) { 828 vector.print %arg0 : si40 829 return 830} 831// CHECK-LABEL: @vector_print_scalar_si40( 832// CHECK-SAME: %[[A:.*]]: si40) 833// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : si40 to i40 834// CHECK: %[[S:.*]] = arith.extsi %[[C]] : i40 to i64 835// CHECK: llvm.call @printI64(%[[S]]) : (i64) -> () 836// CHECK: llvm.call @printNewline() : () -> () 837 838// ----- 839 840func.func @vector_print_scalar_ui40(%arg0: ui40) { 841 vector.print %arg0 : ui40 842 return 843} 844// CHECK-LABEL: @vector_print_scalar_ui40( 845// CHECK-SAME: %[[A:.*]]: ui40) 846// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui40 to i40 847// CHECK: %[[S:.*]] = arith.extui %[[C]] : i40 to i64 848// CHECK: llvm.call @printU64(%[[S]]) : (i64) -> () 849// CHECK: llvm.call @printNewline() : () -> () 850 851// ----- 852 853func.func @vector_print_scalar_i64(%arg0: i64) { 854 vector.print %arg0 : i64 855 return 856} 857// CHECK-LABEL: @vector_print_scalar_i64( 858// CHECK-SAME: %[[A:.*]]: i64) 859// CHECK: llvm.call @printI64(%[[A]]) : (i64) -> () 860// CHECK: llvm.call @printNewline() : () -> () 861 862// ----- 863 864func.func @vector_print_scalar_ui64(%arg0: ui64) { 865 vector.print %arg0 : ui64 866 return 867} 868// CHECK-LABEL: @vector_print_scalar_ui64( 869// CHECK-SAME: %[[A:.*]]: ui64) 870// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : ui64 to i64 871// CHECK: llvm.call @printU64(%[[C]]) : (i64) -> () 872// CHECK: llvm.call @printNewline() : () -> () 873 874// ----- 875 876func.func @vector_print_scalar_index(%arg0: index) { 877 vector.print %arg0 : index 878 return 879} 880// CHECK-LABEL: @vector_print_scalar_index( 881// CHECK-SAME: %[[A:.*]]: index) 882// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[A]] : index to i64 883// CHECK: llvm.call @printU64(%[[C]]) : (i64) -> () 884// CHECK: llvm.call @printNewline() : () -> () 885 886// ----- 887 888func.func @vector_print_scalar_f32(%arg0: f32) { 889 vector.print %arg0 : f32 890 return 891} 892// CHECK-LABEL: @vector_print_scalar_f32( 893// CHECK-SAME: %[[A:.*]]: f32) 894// CHECK: llvm.call @printF32(%[[A]]) : (f32) -> () 895// CHECK: llvm.call @printNewline() : () -> () 896 897// ----- 898 899func.func @vector_print_scalar_f64(%arg0: f64) { 900 vector.print %arg0 : f64 901 return 902} 903// CHECK-LABEL: @vector_print_scalar_f64( 904// CHECK-SAME: %[[A:.*]]: f64) 905// CHECK: llvm.call @printF64(%[[A]]) : (f64) -> () 906// CHECK: llvm.call @printNewline() : () -> () 907 908// ----- 909 910func.func @vector_print_vector_0d(%arg0: vector<f32>) { 911 vector.print %arg0 : vector<f32> 912 return 913} 914// CHECK-LABEL: @vector_print_vector_0d( 915// CHECK-SAME: %[[A:.*]]: vector<f32>) 916// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32> 917// CHECK: llvm.call @printOpen() : () -> () 918// CHECK: %[[T1:.*]] = llvm.mlir.constant(0 : index) : i64 919// CHECK: %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<1xf32> 920// CHECK: llvm.call @printF32(%[[T2]]) : (f32) -> () 921// CHECK: llvm.call @printClose() : () -> () 922// CHECK: llvm.call @printNewline() : () -> () 923// CHECK: return 924 925// ----- 926 927func.func @vector_print_vector(%arg0: vector<2x2xf32>) { 928 vector.print %arg0 : vector<2x2xf32> 929 return 930} 931// CHECK-LABEL: @vector_print_vector( 932// CHECK-SAME: %[[A:.*]]: vector<2x2xf32>) 933// CHECK: %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>> 934// CHECK: llvm.call @printOpen() : () -> () 935// CHECK: %[[x0:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<2xf32>> 936// CHECK: llvm.call @printOpen() : () -> () 937// CHECK: %[[x1:.*]] = llvm.mlir.constant(0 : index) : i64 938// CHECK: %[[x2:.*]] = llvm.extractelement %[[x0]][%[[x1]] : i64] : vector<2xf32> 939// CHECK: llvm.call @printF32(%[[x2]]) : (f32) -> () 940// CHECK: llvm.call @printComma() : () -> () 941// CHECK: %[[x3:.*]] = llvm.mlir.constant(1 : index) : i64 942// CHECK: %[[x4:.*]] = llvm.extractelement %[[x0]][%[[x3]] : i64] : vector<2xf32> 943// CHECK: llvm.call @printF32(%[[x4]]) : (f32) -> () 944// CHECK: llvm.call @printClose() : () -> () 945// CHECK: llvm.call @printComma() : () -> () 946// CHECK: %[[x5:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<2xf32>> 947// CHECK: llvm.call @printOpen() : () -> () 948// CHECK: %[[x6:.*]] = llvm.mlir.constant(0 : index) : i64 949// CHECK: %[[x7:.*]] = llvm.extractelement %[[x5]][%[[x6]] : i64] : vector<2xf32> 950// CHECK: llvm.call @printF32(%[[x7]]) : (f32) -> () 951// CHECK: llvm.call @printComma() : () -> () 952// CHECK: %[[x8:.*]] = llvm.mlir.constant(1 : index) : i64 953// CHECK: %[[x9:.*]] = llvm.extractelement %[[x5]][%[[x8]] : i64] : vector<2xf32> 954// CHECK: llvm.call @printF32(%[[x9]]) : (f32) -> () 955// CHECK: llvm.call @printClose() : () -> () 956// CHECK: llvm.call @printClose() : () -> () 957// CHECK: llvm.call @printNewline() : () -> () 958 959// ----- 960 961func.func @extract_strided_slice1(%arg0: vector<4xf32>) -> vector<2xf32> { 962 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xf32> to vector<2xf32> 963 return %0 : vector<2xf32> 964} 965// CHECK-LABEL: @extract_strided_slice1( 966// CHECK-SAME: %[[A:.*]]: vector<4xf32>) 967// CHECK: %[[T0:.*]] = llvm.shufflevector %[[A]], %[[A]] [2, 3] : vector<4xf32>, vector<4xf32> 968// CHECK: return %[[T0]] : vector<2xf32> 969 970// ----- 971 972func.func @extract_strided_index_slice1(%arg0: vector<4xindex>) -> vector<2xindex> { 973 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4xindex> to vector<2xindex> 974 return %0 : vector<2xindex> 975} 976// CHECK-LABEL: @extract_strided_index_slice1( 977// CHECK-SAME: %[[A:.*]]: vector<4xindex>) 978// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<4xindex> to vector<4xi64> 979// CHECK: %[[T2:.*]] = llvm.shufflevector %[[T0]], %[[T0]] [2, 3] : vector<4xi64>, vector<4xi64> 980// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : vector<2xi64> to vector<2xindex> 981// CHECK: return %[[T3]] : vector<2xindex> 982 983// ----- 984 985func.func @extract_strided_slice2(%arg0: vector<4x8xf32>) -> vector<2x8xf32> { 986 %0 = vector.extract_strided_slice %arg0 {offsets = [2], sizes = [2], strides = [1]} : vector<4x8xf32> to vector<2x8xf32> 987 return %0 : vector<2x8xf32> 988} 989// CHECK-LABEL: @extract_strided_slice2( 990// CHECK-SAME: %[[ARG:.*]]: vector<4x8xf32>) 991// CHECK: %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>> 992// CHECK: %[[T0:.*]] = llvm.mlir.undef : !llvm.array<2 x vector<8xf32>> 993// CHECK: %[[T1:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>> 994// CHECK: %[[T2:.*]] = llvm.insertvalue %[[T1]], %[[T0]][0] : !llvm.array<2 x vector<8xf32>> 995// CHECK: %[[T3:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>> 996// CHECK: %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[T2]][1] : !llvm.array<2 x vector<8xf32>> 997// CHECK: %[[T5:.*]] = builtin.unrealized_conversion_cast %[[T4]] : !llvm.array<2 x vector<8xf32>> to vector<2x8xf32> 998// CHECK: return %[[T5]] 999 1000// ----- 1001 1002func.func @extract_strided_slice3(%arg0: vector<4x8xf32>) -> vector<2x2xf32> { 1003 %0 = vector.extract_strided_slice %arg0 {offsets = [2, 2], sizes = [2, 2], strides = [1, 1]} : vector<4x8xf32> to vector<2x2xf32> 1004 return %0 : vector<2x2xf32> 1005} 1006// CHECK-LABEL: @extract_strided_slice3( 1007// CHECK-SAME: %[[ARG:.*]]: vector<4x8xf32>) 1008// CHECK: %[[A:.*]] = builtin.unrealized_conversion_cast %[[ARG]] : vector<4x8xf32> to !llvm.array<4 x vector<8xf32>> 1009// CHECK: %[[VAL_2:.*]] = arith.constant dense<0.000000e+00> : vector<2x2xf32> 1010// CHECK: %[[VAL_6:.*]] = builtin.unrealized_conversion_cast %[[VAL_2]] : vector<2x2xf32> to !llvm.array<2 x vector<2xf32>> 1011// CHECK: %[[T2:.*]] = llvm.extractvalue %[[A]][2] : !llvm.array<4 x vector<8xf32>> 1012// CHECK: %[[T3:.*]] = llvm.shufflevector %[[T2]], %[[T2]] [2, 3] : vector<8xf32>, vector<8xf32> 1013// CHECK: %[[T4:.*]] = llvm.insertvalue %[[T3]], %[[VAL_6]][0] : !llvm.array<2 x vector<2xf32>> 1014// CHECK: %[[T5:.*]] = llvm.extractvalue %[[A]][3] : !llvm.array<4 x vector<8xf32>> 1015// CHECK: %[[T6:.*]] = llvm.shufflevector %[[T5]], %[[T5]] [2, 3] : vector<8xf32>, vector<8xf32> 1016// CHECK: %[[T7:.*]] = llvm.insertvalue %[[T6]], %[[T4]][1] : !llvm.array<2 x vector<2xf32>> 1017// CHECK: %[[VAL_12:.*]] = builtin.unrealized_conversion_cast %[[T7]] : !llvm.array<2 x vector<2xf32>> to vector<2x2xf32> 1018// CHECK: return %[[VAL_12]] : vector<2x2xf32> 1019 1020// ----- 1021 1022func.func @insert_strided_slice1(%b: vector<4x4xf32>, %c: vector<4x4x4xf32>) -> vector<4x4x4xf32> { 1023 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xf32> into vector<4x4x4xf32> 1024 return %0 : vector<4x4x4xf32> 1025} 1026// CHECK-LABEL: @insert_strided_slice1 1027// CHECK: llvm.extractvalue {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xf32>>> 1028// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xf32>>> 1029 1030// ----- 1031 1032func.func @insert_strided_index_slice1(%b: vector<4x4xindex>, %c: vector<4x4x4xindex>) -> vector<4x4x4xindex> { 1033 %0 = vector.insert_strided_slice %b, %c {offsets = [2, 0, 0], strides = [1, 1]} : vector<4x4xindex> into vector<4x4x4xindex> 1034 return %0 : vector<4x4x4xindex> 1035} 1036// CHECK-LABEL: @insert_strided_index_slice1( 1037// CHECK: llvm.extractvalue {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xi64>>> 1038// CHECK: llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.array<4 x array<4 x vector<4xi64>>> 1039 1040// ----- 1041 1042func.func @insert_strided_slice2(%a: vector<2x2xf32>, %b: vector<4x4xf32>) -> vector<4x4xf32> { 1043 %0 = vector.insert_strided_slice %a, %b {offsets = [2, 2], strides = [1, 1]} : vector<2x2xf32> into vector<4x4xf32> 1044 return %0 : vector<4x4xf32> 1045} 1046 1047// CHECK-LABEL: @insert_strided_slice2 1048// 1049// Subvector vector<2xf32> @0 into vector<4xf32> @2 1050// CHECK: %[[V2_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<2xf32>> 1051// CHECK: %[[V4_0:.*]] = llvm.extractvalue {{.*}}[2] : !llvm.array<4 x vector<4xf32>> 1052// Element @0 -> element @2 1053// CHECK: %[[R4_0:.*]] = llvm.shufflevector %[[V2_0]], %[[V2_0]] [0, 1, 0, 0] : vector<2xf32>, vector<2xf32> 1054// CHECK: %[[R4_1:.*]] = llvm.shufflevector %[[R4_0]], %[[V4_0]] [4, 5, 0, 1] : vector<4xf32>, vector<4xf32> 1055// CHECK: llvm.insertvalue %[[R4_1]], {{.*}}[2] : !llvm.array<4 x vector<4xf32>> 1056// 1057// Subvector vector<2xf32> @1 into vector<4xf32> @3 1058// CHECK: %[[V2_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<2xf32>> 1059// CHECK: %[[V4_3:.*]] = llvm.extractvalue {{.*}}[3] : !llvm.array<4 x vector<4xf32>> 1060// Element @0 -> element @2 1061// CHECK: %[[R4_2:.*]] = llvm.shufflevector %[[V2_1]], %[[V2_1]] [0, 1, 0, 0] : vector<2xf32>, vector<2xf32> 1062// CHECK: %[[R4_3:.*]] = llvm.shufflevector %[[R4_2]], %[[V4_3]] [4, 5, 0, 1] : vector<4xf32>, vector<4xf32> 1063// CHECK: llvm.insertvalue %[[R4_3]], {{.*}}[3] : !llvm.array<4 x vector<4xf32>> 1064 1065// ----- 1066 1067func.func @insert_strided_slice3(%arg0: vector<2x4xf32>, %arg1: vector<16x4x8xf32>) -> vector<16x4x8xf32> { 1068 %0 = vector.insert_strided_slice %arg0, %arg1 {offsets = [0, 0, 2], strides = [1, 1]}: 1069 vector<2x4xf32> into vector<16x4x8xf32> 1070 return %0 : vector<16x4x8xf32> 1071} 1072// CHECK-LABEL: func @insert_strided_slice3 1073// CHECK: %[[V4_0:.*]] = llvm.extractvalue {{.*}}[0] : !llvm.array<2 x vector<4xf32>> 1074// CHECK: %[[V4_0_0:.*]] = llvm.extractvalue {{.*}}[0, 0] : !llvm.array<16 x array<4 x vector<8xf32>>> 1075// CHECK: %[[R8_0:.*]] = llvm.shufflevector %[[V4_0]], %[[V4_0]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>, vector<4xf32> 1076// CHECK: %[[R8_1:.*]] = llvm.shufflevector %[[R8_0:.*]], %[[V4_0_0]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>, vector<8xf32> 1077// CHECK: llvm.insertvalue %[[R8_1]], {{.*}}[0] : !llvm.array<4 x vector<8xf32>> 1078 1079// CHECK: %[[V4_1:.*]] = llvm.extractvalue {{.*}}[1] : !llvm.array<2 x vector<4xf32>> 1080// CHECK: %[[V4_0_1:.*]] = llvm.extractvalue {{.*}}[0, 1] : !llvm.array<16 x array<4 x vector<8xf32>>> 1081// CHECK: %[[R8_2:.*]] = llvm.shufflevector %[[V4_1]], %[[V4_1]] [0, 1, 2, 3, 0, 0, 0, 0] : vector<4xf32>, vector<4xf32> 1082// CHECK: %[[R8_3:.*]] = llvm.shufflevector %[[R8_2]], %[[V4_0_1]] [8, 9, 0, 1, 2, 3, 14, 15] : vector<8xf32>, vector<8xf32> 1083// CHECK: llvm.insertvalue %[[R8_3]], {{.*}}[1] : !llvm.array<4 x vector<8xf32>> 1084 1085// ----- 1086 1087func.func @vector_fma(%a: vector<8xf32>, %b: vector<2x4xf32>, %c: vector<1x1x1xf32>) -> (vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32>) { 1088 // CHECK-LABEL: @vector_fma 1089 // CHECK-SAME: %[[A:.*]]: vector<8xf32> 1090 // CHECK-SAME: %[[B:.*]]: vector<2x4xf32> 1091 // CHECK-SAME: %[[C:.*]]: vector<1x1x1xf32> 1092 // CHECK: %[[BL:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>> 1093 // CHECK: "llvm.intr.fmuladd" 1094 // CHECK-SAME: (vector<8xf32>, vector<8xf32>, vector<8xf32>) -> vector<8xf32> 1095 %0 = vector.fma %a, %a, %a : vector<8xf32> 1096 1097 // CHECK: %[[b00:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>> 1098 // CHECK: %[[b01:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>> 1099 // CHECK: %[[b02:.*]] = llvm.extractvalue %[[BL]][0] : !llvm.array<2 x vector<4xf32>> 1100 // CHECK: %[[B0:.*]] = "llvm.intr.fmuladd"(%[[b00]], %[[b01]], %[[b02]]) : 1101 // CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32> 1102 // CHECK: llvm.insertvalue %[[B0]], {{.*}}[0] : !llvm.array<2 x vector<4xf32>> 1103 // CHECK: %[[b10:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>> 1104 // CHECK: %[[b11:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>> 1105 // CHECK: %[[b12:.*]] = llvm.extractvalue %[[BL]][1] : !llvm.array<2 x vector<4xf32>> 1106 // CHECK: %[[B1:.*]] = "llvm.intr.fmuladd"(%[[b10]], %[[b11]], %[[b12]]) : 1107 // CHECK-SAME: (vector<4xf32>, vector<4xf32>, vector<4xf32>) -> vector<4xf32> 1108 // CHECK: llvm.insertvalue %[[B1]], {{.*}}[1] : !llvm.array<2 x vector<4xf32>> 1109 %1 = vector.fma %b, %b, %b : vector<2x4xf32> 1110 1111 // CHECK: %[[C0:.*]] = "llvm.intr.fmuladd" 1112 // CHECK-SAME: (vector<1xf32>, vector<1xf32>, vector<1xf32>) -> vector<1xf32> 1113 %2 = vector.fma %c, %c, %c : vector<1x1x1xf32> 1114 1115 return %0, %1, %2: vector<8xf32>, vector<2x4xf32>, vector<1x1x1xf32> 1116} 1117 1118// ----- 1119 1120func.func @reduce_f16(%arg0: vector<16xf16>) -> f16 { 1121 %0 = vector.reduction <add>, %arg0 : vector<16xf16> into f16 1122 return %0 : f16 1123} 1124// CHECK-LABEL: @reduce_f16( 1125// CHECK-SAME: %[[A:.*]]: vector<16xf16>) 1126// CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f16) : f16 1127// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]]) 1128// CHECK-SAME: {reassoc = false} : (f16, vector<16xf16>) -> f16 1129// CHECK: return %[[V]] : f16 1130 1131// ----- 1132 1133func.func @reduce_f32(%arg0: vector<16xf32>) -> f32 { 1134 %0 = vector.reduction <add>, %arg0 : vector<16xf32> into f32 1135 return %0 : f32 1136} 1137// CHECK-LABEL: @reduce_f32( 1138// CHECK-SAME: %[[A:.*]]: vector<16xf32>) 1139// CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f32) : f32 1140// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]]) 1141// CHECK-SAME: {reassoc = false} : (f32, vector<16xf32>) -> f32 1142// CHECK: return %[[V]] : f32 1143 1144// ----- 1145 1146func.func @reduce_f64(%arg0: vector<16xf64>) -> f64 { 1147 %0 = vector.reduction <add>, %arg0 : vector<16xf64> into f64 1148 return %0 : f64 1149} 1150// CHECK-LABEL: @reduce_f64( 1151// CHECK-SAME: %[[A:.*]]: vector<16xf64>) 1152// CHECK: %[[C:.*]] = llvm.mlir.constant(0.000000e+00 : f64) : f64 1153// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fadd"(%[[C]], %[[A]]) 1154// CHECK-SAME: {reassoc = false} : (f64, vector<16xf64>) -> f64 1155// CHECK: return %[[V]] : f64 1156 1157// ----- 1158 1159func.func @reduce_i8(%arg0: vector<16xi8>) -> i8 { 1160 %0 = vector.reduction <add>, %arg0 : vector<16xi8> into i8 1161 return %0 : i8 1162} 1163// CHECK-LABEL: @reduce_i8( 1164// CHECK-SAME: %[[A:.*]]: vector<16xi8>) 1165// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]]) 1166// CHECK: return %[[V]] : i8 1167 1168// ----- 1169 1170func.func @reduce_i32(%arg0: vector<16xi32>) -> i32 { 1171 %0 = vector.reduction <add>, %arg0 : vector<16xi32> into i32 1172 return %0 : i32 1173} 1174// CHECK-LABEL: @reduce_i32( 1175// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1176// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]]) 1177// CHECK: return %[[V]] : i32 1178 1179// ----- 1180 1181func.func @reduce_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1182 %0 = vector.reduction <add>, %arg0, %arg1 : vector<16xi32> into i32 1183 return %0 : i32 1184} 1185// CHECK-LABEL: @reduce_acc_i32( 1186// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1187// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.add"(%[[A]]) 1188// CHECK: %[[V:.*]] = llvm.add %[[ACC]], %[[R]] 1189// CHECK: return %[[V]] : i32 1190 1191// ----- 1192 1193func.func @reduce_mul_i32(%arg0: vector<16xi32>) -> i32 { 1194 %0 = vector.reduction <mul>, %arg0 : vector<16xi32> into i32 1195 return %0 : i32 1196} 1197// CHECK-LABEL: @reduce_mul_i32( 1198// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1199// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.mul"(%[[A]]) 1200// CHECK: return %[[V]] : i32 1201 1202// ----- 1203 1204func.func @reduce_mul_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1205 %0 = vector.reduction <mul>, %arg0, %arg1 : vector<16xi32> into i32 1206 return %0 : i32 1207} 1208// CHECK-LABEL: @reduce_mul_acc_i32( 1209// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1210// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.mul"(%[[A]]) 1211// CHECK: %[[V:.*]] = llvm.mul %[[ACC]], %[[R]] 1212// CHECK: return %[[V]] : i32 1213 1214// ----- 1215 1216func.func @reduce_fmax_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 { 1217 %0 = vector.reduction <maxf>, %arg0, %arg1 : vector<16xf32> into f32 1218 return %0 : f32 1219} 1220// CHECK-LABEL: @reduce_fmax_f32( 1221// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32) 1222// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fmax"(%[[A]]) : (vector<16xf32>) -> f32 1223// CHECK: %[[C0:.*]] = llvm.fcmp "ogt" %[[V]], %[[B]] : f32 1224// CHECK: %[[S0:.*]] = llvm.select %[[C0]], %[[V]], %[[B]] : i1, f32 1225// CHECK: %[[C1:.*]] = llvm.fcmp "uno" %[[V]], %[[B]] : f32 1226// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7FC00000 : f32) : f32 1227// CHECK: %[[R:.*]] = llvm.select %[[C1]], %[[NAN]], %[[S0]] : i1, f32 1228// CHECK: return %[[R]] : f32 1229 1230// ----- 1231 1232func.func @reduce_fmin_f32(%arg0: vector<16xf32>, %arg1: f32) -> f32 { 1233 %0 = vector.reduction <minf>, %arg0, %arg1 : vector<16xf32> into f32 1234 return %0 : f32 1235} 1236// CHECK-LABEL: @reduce_fmin_f32( 1237// CHECK-SAME: %[[A:.*]]: vector<16xf32>, %[[B:.*]]: f32) 1238// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.fmin"(%[[A]]) : (vector<16xf32>) -> f32 1239// CHECK: %[[C0:.*]] = llvm.fcmp "olt" %[[V]], %[[B]] : f32 1240// CHECK: %[[S0:.*]] = llvm.select %[[C0]], %[[V]], %[[B]] : i1, f32 1241// CHECK: %[[C1:.*]] = llvm.fcmp "uno" %[[V]], %[[B]] : f32 1242// CHECK: %[[NAN:.*]] = llvm.mlir.constant(0x7FC00000 : f32) : f32 1243// CHECK: %[[R:.*]] = llvm.select %[[C1]], %[[NAN]], %[[S0]] : i1, f32 1244// CHECK: return %[[R]] : f32 1245 1246// ----- 1247 1248func.func @reduce_minui_i32(%arg0: vector<16xi32>) -> i32 { 1249 %0 = vector.reduction <minui>, %arg0 : vector<16xi32> into i32 1250 return %0 : i32 1251} 1252// CHECK-LABEL: @reduce_minui_i32( 1253// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1254// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.umin"(%[[A]]) 1255// CHECK: return %[[V]] : i32 1256 1257// ----- 1258 1259func.func @reduce_minui_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1260 %0 = vector.reduction <minui>, %arg0, %arg1 : vector<16xi32> into i32 1261 return %0 : i32 1262} 1263// CHECK-LABEL: @reduce_minui_acc_i32( 1264// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1265// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.umin"(%[[A]]) 1266// CHECK: %[[S:.*]] = llvm.icmp "ule" %[[ACC]], %[[R]] 1267// CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]] 1268// CHECK: return %[[V]] : i32 1269 1270// ----- 1271 1272func.func @reduce_maxui_i32(%arg0: vector<16xi32>) -> i32 { 1273 %0 = vector.reduction <maxui>, %arg0 : vector<16xi32> into i32 1274 return %0 : i32 1275} 1276// CHECK-LABEL: @reduce_maxui_i32( 1277// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1278// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.umax"(%[[A]]) 1279// CHECK: return %[[V]] : i32 1280 1281// ----- 1282 1283func.func @reduce_maxui_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1284 %0 = vector.reduction <maxui>, %arg0, %arg1 : vector<16xi32> into i32 1285 return %0 : i32 1286} 1287// CHECK-LABEL: @reduce_maxui_acc_i32( 1288// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1289// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.umax"(%[[A]]) 1290// CHECK: %[[S:.*]] = llvm.icmp "uge" %[[ACC]], %[[R]] 1291// CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]] 1292// CHECK: return %[[V]] : i32 1293 1294// ----- 1295 1296func.func @reduce_minsi_i32(%arg0: vector<16xi32>) -> i32 { 1297 %0 = vector.reduction <minsi>, %arg0 : vector<16xi32> into i32 1298 return %0 : i32 1299} 1300// CHECK-LABEL: @reduce_minsi_i32( 1301// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1302// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.smin"(%[[A]]) 1303// CHECK: return %[[V]] : i32 1304 1305// ----- 1306 1307func.func @reduce_minsi_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1308 %0 = vector.reduction <minsi>, %arg0, %arg1 : vector<16xi32> into i32 1309 return %0 : i32 1310} 1311// CHECK-LABEL: @reduce_minsi_acc_i32( 1312// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1313// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.smin"(%[[A]]) 1314// CHECK: %[[S:.*]] = llvm.icmp "sle" %[[ACC]], %[[R]] 1315// CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]] 1316// CHECK: return %[[V]] : i32 1317 1318// ----- 1319 1320func.func @reduce_maxsi_i32(%arg0: vector<16xi32>) -> i32 { 1321 %0 = vector.reduction <maxsi>, %arg0 : vector<16xi32> into i32 1322 return %0 : i32 1323} 1324// CHECK-LABEL: @reduce_maxsi_i32( 1325// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1326// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.smax"(%[[A]]) 1327// CHECK: return %[[V]] : i32 1328 1329// ----- 1330 1331func.func @reduce_maxsi_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1332 %0 = vector.reduction <maxsi>, %arg0, %arg1 : vector<16xi32> into i32 1333 return %0 : i32 1334} 1335// CHECK-LABEL: @reduce_maxsi_acc_i32( 1336// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1337// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.smax"(%[[A]]) 1338// CHECK: %[[S:.*]] = llvm.icmp "sge" %[[ACC]], %[[R]] 1339// CHECK: %[[V:.*]] = llvm.select %[[S]], %[[ACC]], %[[R]] 1340// CHECK: return %[[V]] : i32 1341 1342// ----- 1343 1344func.func @reduce_and_i32(%arg0: vector<16xi32>) -> i32 { 1345 %0 = vector.reduction <and>, %arg0 : vector<16xi32> into i32 1346 return %0 : i32 1347} 1348// CHECK-LABEL: @reduce_and_i32( 1349// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1350// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.and"(%[[A]]) 1351// CHECK: return %[[V]] : i32 1352 1353// ----- 1354 1355func.func @reduce_and_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1356 %0 = vector.reduction <and>, %arg0, %arg1 : vector<16xi32> into i32 1357 return %0 : i32 1358} 1359// CHECK-LABEL: @reduce_and_acc_i32( 1360// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1361// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.and"(%[[A]]) 1362// CHECK: %[[V:.*]] = llvm.and %[[ACC]], %[[R]] 1363// CHECK: return %[[V]] : i32 1364 1365// ----- 1366 1367func.func @reduce_or_i32(%arg0: vector<16xi32>) -> i32 { 1368 %0 = vector.reduction <or>, %arg0 : vector<16xi32> into i32 1369 return %0 : i32 1370} 1371// CHECK-LABEL: @reduce_or_i32( 1372// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1373// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.or"(%[[A]]) 1374// CHECK: return %[[V]] : i32 1375 1376// ----- 1377 1378func.func @reduce_or_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1379 %0 = vector.reduction <or>, %arg0, %arg1 : vector<16xi32> into i32 1380 return %0 : i32 1381} 1382// CHECK-LABEL: @reduce_or_acc_i32( 1383// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1384// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.or"(%[[A]]) 1385// CHECK: %[[V:.*]] = llvm.or %[[ACC]], %[[R]] 1386// CHECK: return %[[V]] : i32 1387 1388// ----- 1389 1390func.func @reduce_xor_i32(%arg0: vector<16xi32>) -> i32 { 1391 %0 = vector.reduction <xor>, %arg0 : vector<16xi32> into i32 1392 return %0 : i32 1393} 1394// CHECK-LABEL: @reduce_xor_i32( 1395// CHECK-SAME: %[[A:.*]]: vector<16xi32>) 1396// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.xor"(%[[A]]) 1397// CHECK: return %[[V]] : i32 1398 1399// ----- 1400 1401func.func @reduce_xor_acc_i32(%arg0: vector<16xi32>, %arg1 : i32) -> i32 { 1402 %0 = vector.reduction <xor>, %arg0, %arg1 : vector<16xi32> into i32 1403 return %0 : i32 1404} 1405// CHECK-LABEL: @reduce_xor_acc_i32( 1406// CHECK-SAME: %[[A:.*]]: vector<16xi32>, %[[ACC:.*]]: i32) 1407// CHECK: %[[R:.*]] = "llvm.intr.vector.reduce.xor"(%[[A]]) 1408// CHECK: %[[V:.*]] = llvm.xor %[[ACC]], %[[R]] 1409// CHECK: return %[[V]] : i32 1410 1411// ----- 1412 1413func.func @reduce_i64(%arg0: vector<16xi64>) -> i64 { 1414 %0 = vector.reduction <add>, %arg0 : vector<16xi64> into i64 1415 return %0 : i64 1416} 1417// CHECK-LABEL: @reduce_i64( 1418// CHECK-SAME: %[[A:.*]]: vector<16xi64>) 1419// CHECK: %[[V:.*]] = "llvm.intr.vector.reduce.add"(%[[A]]) 1420// CHECK: return %[[V]] : i64 1421 1422// ----- 1423 1424func.func @reduce_index(%arg0: vector<16xindex>) -> index { 1425 %0 = vector.reduction <add>, %arg0 : vector<16xindex> into index 1426 return %0 : index 1427} 1428// CHECK-LABEL: @reduce_index( 1429// CHECK-SAME: %[[A:.*]]: vector<16xindex>) 1430// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64> 1431// CHECK: %[[T1:.*]] = "llvm.intr.vector.reduce.add"(%[[T0]]) 1432// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : i64 to index 1433// CHECK: return %[[T2]] : index 1434 1435// 4x16 16x3 4x3 1436// ----- 1437 1438func.func @matrix_ops(%A: vector<64xf64>, %B: vector<48xf64>) -> vector<12xf64> { 1439 %C = vector.matrix_multiply %A, %B 1440 { lhs_rows = 4: i32, lhs_columns = 16: i32 , rhs_columns = 3: i32 } : 1441 (vector<64xf64>, vector<48xf64>) -> vector<12xf64> 1442 return %C: vector<12xf64> 1443} 1444// CHECK-LABEL: @matrix_ops 1445// CHECK: llvm.intr.matrix.multiply %{{.*}}, %{{.*}} { 1446// CHECK-SAME: lhs_columns = 16 : i32, lhs_rows = 4 : i32, rhs_columns = 3 : i32 1447// CHECK-SAME: } : (vector<64xf64>, vector<48xf64>) -> vector<12xf64> 1448 1449// ----- 1450 1451func.func @matrix_ops_index(%A: vector<64xindex>, %B: vector<48xindex>) -> vector<12xindex> { 1452 %C = vector.matrix_multiply %A, %B 1453 { lhs_rows = 4: i32, lhs_columns = 16: i32 , rhs_columns = 3: i32 } : 1454 (vector<64xindex>, vector<48xindex>) -> vector<12xindex> 1455 return %C: vector<12xindex> 1456} 1457// CHECK-LABEL: @matrix_ops_index 1458// CHECK: llvm.intr.matrix.multiply %{{.*}}, %{{.*}} { 1459// CHECK-SAME: lhs_columns = 16 : i32, lhs_rows = 4 : i32, rhs_columns = 3 : i32 1460// CHECK-SAME: } : (vector<64xi64>, vector<48xi64>) -> vector<12xi64> 1461 1462// ----- 1463 1464func.func @transfer_read_1d(%A : memref<?xf32>, %base: index) -> vector<17xf32> { 1465 %f7 = arith.constant 7.0: f32 1466 %f = vector.transfer_read %A[%base], %f7 1467 {permutation_map = affine_map<(d0) -> (d0)>} : 1468 memref<?xf32>, vector<17xf32> 1469 vector.transfer_write %f, %A[%base] 1470 {permutation_map = affine_map<(d0) -> (d0)>} : 1471 vector<17xf32>, memref<?xf32> 1472 return %f: vector<17xf32> 1473} 1474// CHECK-LABEL: func @transfer_read_1d 1475// CHECK-SAME: %[[MEM:.*]]: memref<?xf32>, 1476// CHECK-SAME: %[[BASE:.*]]: index) -> vector<17xf32> 1477// CHECK: %[[C7:.*]] = arith.constant 7.0 1478// 1479// 1. Let dim be the memref dimension, compute the in-bound index (dim - offset) 1480// CHECK: %[[C0:.*]] = arith.constant 0 : index 1481// CHECK: %[[DIM:.*]] = memref.dim %[[MEM]], %[[C0]] : memref<?xf32> 1482// CHECK: %[[BOUND:.*]] = arith.subi %[[DIM]], %[[BASE]] : index 1483// 1484// 2. Create a vector with linear indices [ 0 .. vector_length - 1 ]. 1485// CHECK: %[[linearIndex:.*]] = arith.constant dense 1486// CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> : 1487// CHECK-SAME: vector<17xi32> 1488// 1489// 3. Create bound vector to compute in-bound mask: 1490// [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ] 1491// CHECK: %[[btrunc:.*]] = arith.index_cast %[[BOUND]] : index to i32 1492// CHECK: %[[boundVecInsert:.*]] = llvm.insertelement %[[btrunc]] 1493// CHECK: %[[boundVect:.*]] = llvm.shufflevector %[[boundVecInsert]] 1494// CHECK: %[[mask:.*]] = arith.cmpi slt, %[[linearIndex]], %[[boundVect]] 1495// CHECK-SAME: : vector<17xi32> 1496// 1497// 4. Create pass-through vector. 1498// CHECK: %[[PASS_THROUGH:.*]] = arith.constant dense<7.{{.*}}> : vector<17xf32> 1499// 1500// 5. Bitcast to vector form. 1501// CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}} : 1502// CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1503// CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] : 1504// CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>> 1505// 1506// 6. Rewrite as a masked read. 1507// CHECK: %[[loaded:.*]] = llvm.intr.masked.load %[[vecPtr]], %[[mask]], 1508// CHECK-SAME: %[[PASS_THROUGH]] {alignment = 4 : i32} : 1509// 1510// 1. Let dim be the memref dimension, compute the in-bound index (dim - offset) 1511// CHECK: %[[C0_b:.*]] = arith.constant 0 : index 1512// CHECK: %[[DIM_b:.*]] = memref.dim %[[MEM]], %[[C0_b]] : memref<?xf32> 1513// CHECK: %[[BOUND_b:.*]] = arith.subi %[[DIM_b]], %[[BASE]] : index 1514// 1515// 2. Create a vector with linear indices [ 0 .. vector_length - 1 ]. 1516// CHECK: %[[linearIndex_b:.*]] = arith.constant dense 1517// CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> : 1518// CHECK-SAME: vector<17xi32> 1519// 1520// 3. Create bound vector to compute in-bound mask: 1521// [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ] 1522// CHECK: %[[btrunc_b:.*]] = arith.index_cast %[[BOUND_b]] : index to i32 1523// CHECK: %[[boundVecInsert_b:.*]] = llvm.insertelement %[[btrunc_b]] 1524// CHECK: %[[boundVect_b:.*]] = llvm.shufflevector %[[boundVecInsert_b]] 1525// CHECK: %[[mask_b:.*]] = arith.cmpi slt, %[[linearIndex_b]], 1526// CHECK-SAME: %[[boundVect_b]] : vector<17xi32> 1527// 1528// 4. Bitcast to vector form. 1529// CHECK: %[[gep_b:.*]] = llvm.getelementptr {{.*}} : 1530// CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1531// CHECK: %[[vecPtr_b:.*]] = llvm.bitcast %[[gep_b]] : 1532// CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>> 1533// 1534// 5. Rewrite as a masked write. 1535// CHECK: llvm.intr.masked.store %[[loaded]], %[[vecPtr_b]], %[[mask_b]] 1536// CHECK-SAME: {alignment = 4 : i32} : 1537// CHECK-SAME: vector<17xf32>, vector<17xi1> into !llvm.ptr<vector<17xf32>> 1538 1539// ----- 1540 1541func.func @transfer_read_index_1d(%A : memref<?xindex>, %base: index) -> vector<17xindex> { 1542 %f7 = arith.constant 7: index 1543 %f = vector.transfer_read %A[%base], %f7 1544 {permutation_map = affine_map<(d0) -> (d0)>} : 1545 memref<?xindex>, vector<17xindex> 1546 vector.transfer_write %f, %A[%base] 1547 {permutation_map = affine_map<(d0) -> (d0)>} : 1548 vector<17xindex>, memref<?xindex> 1549 return %f: vector<17xindex> 1550} 1551// CHECK-LABEL: func @transfer_read_index_1d 1552// CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xindex> 1553// CHECK: %[[SPLAT:.*]] = arith.constant dense<7> : vector<17xindex> 1554// CHECK: %{{.*}} = builtin.unrealized_conversion_cast %[[SPLAT]] : vector<17xindex> to vector<17xi64> 1555 1556// CHECK: %[[loaded:.*]] = llvm.intr.masked.load %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : 1557// CHECK-SAME: (!llvm.ptr<vector<17xi64>>, vector<17xi1>, vector<17xi64>) -> vector<17xi64> 1558 1559// CHECK: llvm.intr.masked.store %[[loaded]], %{{.*}}, %{{.*}} {alignment = 8 : i32} : 1560// CHECK-SAME: vector<17xi64>, vector<17xi1> into !llvm.ptr<vector<17xi64>> 1561 1562// ----- 1563 1564func.func @transfer_read_2d_to_1d(%A : memref<?x?xf32>, %base0: index, %base1: index) -> vector<17xf32> { 1565 %f7 = arith.constant 7.0: f32 1566 %f = vector.transfer_read %A[%base0, %base1], %f7 1567 {permutation_map = affine_map<(d0, d1) -> (d1)>} : 1568 memref<?x?xf32>, vector<17xf32> 1569 return %f: vector<17xf32> 1570} 1571// CHECK-LABEL: func @transfer_read_2d_to_1d 1572// CHECK-SAME: %[[BASE_0:[a-zA-Z0-9]*]]: index, %[[BASE_1:[a-zA-Z0-9]*]]: index) -> vector<17xf32> 1573// CHECK: %[[c1:.*]] = arith.constant 1 : index 1574// CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[c1]] : memref<?x?xf32> 1575// 1576// Compute the in-bound index (dim - offset) 1577// CHECK: %[[BOUND:.*]] = arith.subi %[[DIM]], %[[BASE_1]] : index 1578// 1579// Create a vector with linear indices [ 0 .. vector_length - 1 ]. 1580// CHECK: %[[linearIndex:.*]] = arith.constant dense 1581// CHECK-SAME: <[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]> : 1582// CHECK-SAME: vector<17xi32> 1583// 1584// Create bound vector to compute in-bound mask: 1585// [ 0 .. vector_length - 1 ] < [ dim - offset .. dim - offset ] 1586// CHECK: %[[btrunc:.*]] = arith.index_cast %[[BOUND]] : index to i32 1587// CHECK: %[[boundVecInsert:.*]] = llvm.insertelement %[[btrunc]] 1588// CHECK: %[[boundVect:.*]] = llvm.shufflevector %[[boundVecInsert]] 1589// CHECK: %[[mask:.*]] = arith.cmpi slt, %[[linearIndex]], %[[boundVect]] 1590 1591// ----- 1592 1593func.func @transfer_read_1d_non_zero_addrspace(%A : memref<?xf32, 3>, %base: index) -> vector<17xf32> { 1594 %f7 = arith.constant 7.0: f32 1595 %f = vector.transfer_read %A[%base], %f7 1596 {permutation_map = affine_map<(d0) -> (d0)>} : 1597 memref<?xf32, 3>, vector<17xf32> 1598 vector.transfer_write %f, %A[%base] 1599 {permutation_map = affine_map<(d0) -> (d0)>} : 1600 vector<17xf32>, memref<?xf32, 3> 1601 return %f: vector<17xf32> 1602} 1603// CHECK-LABEL: func @transfer_read_1d_non_zero_addrspace 1604// CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xf32> 1605// 1606// 1. Check address space for GEP is correct. 1607// CHECK: %[[gep:.*]] = llvm.getelementptr {{.*}} : 1608// CHECK-SAME: (!llvm.ptr<f32, 3>, i64) -> !llvm.ptr<f32, 3> 1609// CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] : 1610// CHECK-SAME: !llvm.ptr<f32, 3> to !llvm.ptr<vector<17xf32>, 3> 1611// 1612// 2. Check address space of the memref is correct. 1613// CHECK: %[[c0:.*]] = arith.constant 0 : index 1614// CHECK: %[[DIM:.*]] = memref.dim %{{.*}}, %[[c0]] : memref<?xf32, 3> 1615// 1616// 3. Check address space for GEP is correct. 1617// CHECK: %[[gep_b:.*]] = llvm.getelementptr {{.*}} : 1618// CHECK-SAME: (!llvm.ptr<f32, 3>, i64) -> !llvm.ptr<f32, 3> 1619// CHECK: %[[vecPtr_b:.*]] = llvm.bitcast %[[gep_b]] : 1620// CHECK-SAME: !llvm.ptr<f32, 3> to !llvm.ptr<vector<17xf32>, 3> 1621 1622// ----- 1623 1624func.func @transfer_read_1d_inbounds(%A : memref<?xf32>, %base: index) -> vector<17xf32> { 1625 %f7 = arith.constant 7.0: f32 1626 %f = vector.transfer_read %A[%base], %f7 {in_bounds = [true]} : 1627 memref<?xf32>, vector<17xf32> 1628 return %f: vector<17xf32> 1629} 1630// CHECK-LABEL: func @transfer_read_1d_inbounds 1631// CHECK-SAME: %[[BASE:[a-zA-Z0-9]*]]: index) -> vector<17xf32> 1632// 1633// 1. Bitcast to vector form. 1634// CHECK: %[[gep:.*]] = llvm.getelementptr {{.*}} : 1635// CHECK-SAME: (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1636// CHECK: %[[vecPtr:.*]] = llvm.bitcast %[[gep]] : 1637// CHECK-SAME: !llvm.ptr<f32> to !llvm.ptr<vector<17xf32>> 1638// 1639// 2. Rewrite as a load. 1640// CHECK: %[[loaded:.*]] = llvm.load %[[vecPtr]] {alignment = 4 : i64} : !llvm.ptr<vector<17xf32>> 1641 1642// ----- 1643 1644// CHECK-LABEL: func @transfer_read_1d_mask 1645// CHECK: %[[mask1:.*]] = arith.constant dense<[false, false, true, false, true]> 1646// CHECK: %[[cmpi:.*]] = arith.cmpi slt 1647// CHECK: %[[mask2:.*]] = arith.andi %[[cmpi]], %[[mask1]] 1648// CHECK: %[[r:.*]] = llvm.intr.masked.load %{{.*}}, %[[mask2]] 1649// CHECK: return %[[r]] 1650func.func @transfer_read_1d_mask(%A : memref<?xf32>, %base : index) -> vector<5xf32> { 1651 %m = arith.constant dense<[0, 0, 1, 0, 1]> : vector<5xi1> 1652 %f7 = arith.constant 7.0: f32 1653 %f = vector.transfer_read %A[%base], %f7, %m : memref<?xf32>, vector<5xf32> 1654 return %f: vector<5xf32> 1655} 1656 1657// ----- 1658 1659func.func @genbool_0d_f() -> vector<i1> { 1660 %0 = vector.constant_mask [0] : vector<i1> 1661 return %0 : vector<i1> 1662} 1663// CHECK-LABEL: func @genbool_0d_f 1664// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<i1> 1665// CHECK: return %[[VAL_0]] : vector<i1> 1666 1667// ----- 1668 1669func.func @genbool_0d_t() -> vector<i1> { 1670 %0 = vector.constant_mask [1] : vector<i1> 1671 return %0 : vector<i1> 1672} 1673// CHECK-LABEL: func @genbool_0d_t 1674// CHECK: %[[VAL_0:.*]] = arith.constant dense<true> : vector<i1> 1675// CHECK: return %[[VAL_0]] : vector<i1> 1676 1677// ----- 1678 1679func.func @genbool_1d() -> vector<8xi1> { 1680 %0 = vector.constant_mask [4] : vector<8xi1> 1681 return %0 : vector<8xi1> 1682} 1683// CHECK-LABEL: func @genbool_1d 1684// CHECK: %[[VAL_0:.*]] = arith.constant dense<[true, true, true, true, false, false, false, false]> : vector<8xi1> 1685// CHECK: return %[[VAL_0]] : vector<8xi1> 1686 1687// ----- 1688 1689func.func @genbool_1d_scalable() -> vector<[8]xi1> { 1690 %0 = vector.constant_mask [0] : vector<[8]xi1> 1691 return %0 : vector<[8]xi1> 1692} 1693// CHECK-LABEL: func @genbool_1d_scalable 1694// CHECK: %[[VAL_0:.*]] = arith.constant dense<false> : vector<[8]xi1> 1695// CHECK: return %[[VAL_0]] : vector<[8]xi1> 1696 1697// ----- 1698 1699func.func @genbool_2d() -> vector<4x4xi1> { 1700 %v = vector.constant_mask [2, 2] : vector<4x4xi1> 1701 return %v: vector<4x4xi1> 1702} 1703 1704// CHECK-LABEL: func @genbool_2d 1705// CHECK: %[[VAL_0:.*]] = arith.constant dense<[true, true, false, false]> : vector<4xi1> 1706// CHECK: %[[VAL_1:.*]] = arith.constant dense<false> : vector<4x4xi1> 1707// CHECK: %[[VAL_2:.*]] = builtin.unrealized_conversion_cast %[[VAL_1]] : vector<4x4xi1> to !llvm.array<4 x vector<4xi1>> 1708// CHECK: %[[VAL_3:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_2]][0] : !llvm.array<4 x vector<4xi1>> 1709// CHECK: %[[VAL_4:.*]] = llvm.insertvalue %[[VAL_0]], %[[VAL_3]][1] : !llvm.array<4 x vector<4xi1>> 1710// CHECK: %[[VAL_5:.*]] = builtin.unrealized_conversion_cast %[[VAL_4]] : !llvm.array<4 x vector<4xi1>> to vector<4x4xi1> 1711// CHECK: return %[[VAL_5]] : vector<4x4xi1> 1712 1713// ----- 1714 1715func.func @create_mask_0d(%a : index) -> vector<i1> { 1716 %v = vector.create_mask %a : vector<i1> 1717 return %v: vector<i1> 1718} 1719 1720// CHECK-LABEL: func @create_mask_0d 1721// CHECK-SAME: %[[arg:.*]]: index 1722// CHECK: %[[indices:.*]] = arith.constant dense<0> : vector<i32> 1723// CHECK: %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32 1724// CHECK: %[[bounds:.*]] = llvm.insertelement %[[arg_i32]] 1725// CHECK: %[[boundsCast:.*]] = builtin.unrealized_conversion_cast %[[bounds]] : vector<1xi32> to vector<i32> 1726// CHECK: %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[boundsCast]] : vector<i32> 1727// CHECK: return %[[result]] : vector<i1> 1728 1729// ----- 1730 1731func.func @create_mask_1d(%a : index) -> vector<4xi1> { 1732 %v = vector.create_mask %a : vector<4xi1> 1733 return %v: vector<4xi1> 1734} 1735 1736// CHECK-LABEL: func @create_mask_1d 1737// CHECK-SAME: %[[arg:.*]]: index 1738// CHECK: %[[indices:.*]] = arith.constant dense<[0, 1, 2, 3]> : vector<4xi32> 1739// CHECK: %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32 1740// CHECK: %[[boundsInsert:.*]] = llvm.insertelement %[[arg_i32]] 1741// CHECK: %[[bounds:.*]] = llvm.shufflevector %[[boundsInsert]] 1742// CHECK: %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[bounds]] : vector<4xi32> 1743// CHECK: return %[[result]] : vector<4xi1> 1744 1745func.func @create_mask_1d_scalable(%a : index) -> vector<[4]xi1> { 1746 %v = vector.create_mask %a : vector<[4]xi1> 1747 return %v: vector<[4]xi1> 1748} 1749 1750// CHECK-LABEL: func @create_mask_1d_scalable 1751// CHECK-SAME: %[[arg:.*]]: index 1752// CHECK: %[[indices:.*]] = llvm.intr.experimental.stepvector : vector<[4]xi32> 1753// CHECK: %[[arg_i32:.*]] = arith.index_cast %[[arg]] : index to i32 1754// CHECK: %[[boundsInsert:.*]] = llvm.insertelement %[[arg_i32]], {{.*}} : vector<[4]xi32> 1755// CHECK: %[[bounds:.*]] = llvm.shufflevector %[[boundsInsert]], {{.*}} : vector<[4]xi32>, vector<[4]xi32> 1756// CHECK: %[[result:.*]] = arith.cmpi slt, %[[indices]], %[[bounds]] : vector<[4]xi32> 1757// CHECK: return %[[result]] : vector<[4]xi1> 1758 1759// ----- 1760 1761func.func @flat_transpose(%arg0: vector<16xf32>) -> vector<16xf32> { 1762 %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 } 1763 : vector<16xf32> -> vector<16xf32> 1764 return %0 : vector<16xf32> 1765} 1766 1767// CHECK-LABEL: func @flat_transpose 1768// CHECK-SAME: %[[A:.*]]: vector<16xf32> 1769// CHECK: %[[T:.*]] = llvm.intr.matrix.transpose %[[A]] 1770// CHECK-SAME: {columns = 4 : i32, rows = 4 : i32} : 1771// CHECK-SAME: vector<16xf32> into vector<16xf32> 1772// CHECK: return %[[T]] : vector<16xf32> 1773 1774// ----- 1775 1776func.func @flat_transpose_index(%arg0: vector<16xindex>) -> vector<16xindex> { 1777 %0 = vector.flat_transpose %arg0 { rows = 4: i32, columns = 4: i32 } 1778 : vector<16xindex> -> vector<16xindex> 1779 return %0 : vector<16xindex> 1780} 1781// CHECK-LABEL: func @flat_transpose_index 1782// CHECK-SAME: %[[A:.*]]: vector<16xindex> 1783// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64> 1784// CHECK: %[[T1:.*]] = llvm.intr.matrix.transpose %[[T0]] 1785// CHECK-SAME: {columns = 4 : i32, rows = 4 : i32} : 1786// CHECK-SAME: vector<16xi64> into vector<16xi64> 1787// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : vector<16xi64> to vector<16xindex> 1788// CHECK: return %[[T2]] : vector<16xindex> 1789 1790// ----- 1791 1792func.func @vector_load_op(%memref : memref<200x100xf32>, %i : index, %j : index) -> vector<8xf32> { 1793 %0 = vector.load %memref[%i, %j] : memref<200x100xf32>, vector<8xf32> 1794 return %0 : vector<8xf32> 1795} 1796 1797// CHECK-LABEL: func @vector_load_op 1798// CHECK: %[[c100:.*]] = llvm.mlir.constant(100 : index) : i64 1799// CHECK: %[[mul:.*]] = llvm.mul %{{.*}}, %[[c100]] : i64 1800// CHECK: %[[add:.*]] = llvm.add %[[mul]], %{{.*}} : i64 1801// CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}}[%[[add]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1802// CHECK: %[[bcast:.*]] = llvm.bitcast %[[gep]] : !llvm.ptr<f32> to !llvm.ptr<vector<8xf32>> 1803// CHECK: llvm.load %[[bcast]] {alignment = 4 : i64} : !llvm.ptr<vector<8xf32>> 1804 1805// ----- 1806 1807func.func @vector_load_op_index(%memref : memref<200x100xindex>, %i : index, %j : index) -> vector<8xindex> { 1808 %0 = vector.load %memref[%i, %j] : memref<200x100xindex>, vector<8xindex> 1809 return %0 : vector<8xindex> 1810} 1811// CHECK-LABEL: func @vector_load_op_index 1812// CHECK: %[[T0:.*]] = llvm.load %{{.*}} {alignment = 8 : i64} : !llvm.ptr<vector<8xi64>> 1813// CHECK: %[[T1:.*]] = builtin.unrealized_conversion_cast %[[T0]] : vector<8xi64> to vector<8xindex> 1814// CHECK: return %[[T1]] : vector<8xindex> 1815 1816// ----- 1817 1818func.func @vector_store_op(%memref : memref<200x100xf32>, %i : index, %j : index) { 1819 %val = arith.constant dense<11.0> : vector<4xf32> 1820 vector.store %val, %memref[%i, %j] : memref<200x100xf32>, vector<4xf32> 1821 return 1822} 1823 1824// CHECK-LABEL: func @vector_store_op 1825// CHECK: %[[c100:.*]] = llvm.mlir.constant(100 : index) : i64 1826// CHECK: %[[mul:.*]] = llvm.mul %{{.*}}, %[[c100]] : i64 1827// CHECK: %[[add:.*]] = llvm.add %[[mul]], %{{.*}} : i64 1828// CHECK: %[[gep:.*]] = llvm.getelementptr %{{.*}}[%[[add]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1829// CHECK: %[[bcast:.*]] = llvm.bitcast %[[gep]] : !llvm.ptr<f32> to !llvm.ptr<vector<4xf32>> 1830// CHECK: llvm.store %{{.*}}, %[[bcast]] {alignment = 4 : i64} : !llvm.ptr<vector<4xf32>> 1831 1832// ----- 1833 1834func.func @vector_store_op_index(%memref : memref<200x100xindex>, %i : index, %j : index) { 1835 %val = arith.constant dense<11> : vector<4xindex> 1836 vector.store %val, %memref[%i, %j] : memref<200x100xindex>, vector<4xindex> 1837 return 1838} 1839// CHECK-LABEL: func @vector_store_op_index 1840// CHECK: llvm.store %{{.*}}, %{{.*}} {alignment = 8 : i64} : !llvm.ptr<vector<4xi64>> 1841 1842// ----- 1843 1844func.func @masked_load_op(%arg0: memref<?xf32>, %arg1: vector<16xi1>, %arg2: vector<16xf32>) -> vector<16xf32> { 1845 %c0 = arith.constant 0: index 1846 %0 = vector.maskedload %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<16xi1>, vector<16xf32> into vector<16xf32> 1847 return %0 : vector<16xf32> 1848} 1849 1850// CHECK-LABEL: func @masked_load_op 1851// CHECK: %[[CO:.*]] = arith.constant 0 : index 1852// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64 1853// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1854// CHECK: %[[B:.*]] = llvm.bitcast %[[P]] : !llvm.ptr<f32> to !llvm.ptr<vector<16xf32>> 1855// CHECK: %[[L:.*]] = llvm.intr.masked.load %[[B]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.ptr<vector<16xf32>>, vector<16xi1>, vector<16xf32>) -> vector<16xf32> 1856// CHECK: return %[[L]] : vector<16xf32> 1857 1858// ----- 1859 1860func.func @masked_load_op_index(%arg0: memref<?xindex>, %arg1: vector<16xi1>, %arg2: vector<16xindex>) -> vector<16xindex> { 1861 %c0 = arith.constant 0: index 1862 %0 = vector.maskedload %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<16xi1>, vector<16xindex> into vector<16xindex> 1863 return %0 : vector<16xindex> 1864} 1865// CHECK-LABEL: func @masked_load_op_index 1866// CHECK: %{{.*}} = llvm.intr.masked.load %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : (!llvm.ptr<vector<16xi64>>, vector<16xi1>, vector<16xi64>) -> vector<16xi64> 1867 1868// ----- 1869 1870func.func @masked_store_op(%arg0: memref<?xf32>, %arg1: vector<16xi1>, %arg2: vector<16xf32>) { 1871 %c0 = arith.constant 0: index 1872 vector.maskedstore %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<16xi1>, vector<16xf32> 1873 return 1874} 1875 1876// CHECK-LABEL: func @masked_store_op 1877// CHECK: %[[CO:.*]] = arith.constant 0 : index 1878// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64 1879// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1880// CHECK: %[[B:.*]] = llvm.bitcast %[[P]] : !llvm.ptr<f32> to !llvm.ptr<vector<16xf32>> 1881// CHECK: llvm.intr.masked.store %{{.*}}, %[[B]], %{{.*}} {alignment = 4 : i32} : vector<16xf32>, vector<16xi1> into !llvm.ptr<vector<16xf32>> 1882 1883// ----- 1884 1885func.func @masked_store_op_index(%arg0: memref<?xindex>, %arg1: vector<16xi1>, %arg2: vector<16xindex>) { 1886 %c0 = arith.constant 0: index 1887 vector.maskedstore %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<16xi1>, vector<16xindex> 1888 return 1889} 1890// CHECK-LABEL: func @masked_store_op_index 1891// CHECK: llvm.intr.masked.store %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : vector<16xi64>, vector<16xi1> into !llvm.ptr<vector<16xi64>> 1892 1893// ----- 1894 1895func.func @gather_op(%arg0: memref<?xf32>, %arg1: vector<3xi32>, %arg2: vector<3xi1>, %arg3: vector<3xf32>) -> vector<3xf32> { 1896 %0 = arith.constant 0: index 1897 %1 = vector.gather %arg0[%0][%arg1], %arg2, %arg3 : memref<?xf32>, vector<3xi32>, vector<3xi1>, vector<3xf32> into vector<3xf32> 1898 return %1 : vector<3xf32> 1899} 1900 1901// CHECK-LABEL: func @gather_op 1902// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, vector<3xi32>) -> !llvm.vec<3 x ptr<f32>> 1903// CHECK: %[[G:.*]] = llvm.intr.masked.gather %[[P]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.vec<3 x ptr<f32>>, vector<3xi1>, vector<3xf32>) -> vector<3xf32> 1904// CHECK: return %[[G]] : vector<3xf32> 1905 1906// ----- 1907 1908func.func @gather_op_index(%arg0: memref<?xindex>, %arg1: vector<3xindex>, %arg2: vector<3xi1>, %arg3: vector<3xindex>) -> vector<3xindex> { 1909 %0 = arith.constant 0: index 1910 %1 = vector.gather %arg0[%0][%arg1], %arg2, %arg3 : memref<?xindex>, vector<3xindex>, vector<3xi1>, vector<3xindex> into vector<3xindex> 1911 return %1 : vector<3xindex> 1912} 1913 1914// CHECK-LABEL: func @gather_op_index 1915// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<i64>, vector<3xi64>) -> !llvm.vec<3 x ptr<i64>> 1916// CHECK: %[[G:.*]] = llvm.intr.masked.gather %{{.*}}, %{{.*}}, %{{.*}} {alignment = 8 : i32} : (!llvm.vec<3 x ptr<i64>>, vector<3xi1>, vector<3xi64>) -> vector<3xi64> 1917// CHECK: %{{.*}} = builtin.unrealized_conversion_cast %[[G]] : vector<3xi64> to vector<3xindex> 1918 1919// ----- 1920 1921func.func @gather_2d_op(%arg0: memref<4x4xf32>, %arg1: vector<4xi32>, %arg2: vector<4xi1>, %arg3: vector<4xf32>) -> vector<4xf32> { 1922 %0 = arith.constant 3 : index 1923 %1 = vector.gather %arg0[%0, %0][%arg1], %arg2, %arg3 : memref<4x4xf32>, vector<4xi32>, vector<4xi1>, vector<4xf32> into vector<4xf32> 1924 return %1 : vector<4xf32> 1925} 1926 1927// CHECK-LABEL: func @gather_2d_op 1928// CHECK: %[[B:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1929// CHECK: %[[P:.*]] = llvm.getelementptr %[[B]][%{{.*}}] : (!llvm.ptr<f32>, vector<4xi32>) -> !llvm.vec<4 x ptr<f32>> 1930// CHECK: %[[G:.*]] = llvm.intr.masked.gather %[[P]], %{{.*}}, %{{.*}} {alignment = 4 : i32} : (!llvm.vec<4 x ptr<f32>>, vector<4xi1>, vector<4xf32>) -> vector<4xf32> 1931// CHECK: return %[[G]] : vector<4xf32> 1932 1933// ----- 1934 1935func.func @scatter_op(%arg0: memref<?xf32>, %arg1: vector<3xi32>, %arg2: vector<3xi1>, %arg3: vector<3xf32>) { 1936 %0 = arith.constant 0: index 1937 vector.scatter %arg0[%0][%arg1], %arg2, %arg3 : memref<?xf32>, vector<3xi32>, vector<3xi1>, vector<3xf32> 1938 return 1939} 1940 1941// CHECK-LABEL: func @scatter_op 1942// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, vector<3xi32>) -> !llvm.vec<3 x ptr<f32>> 1943// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 4 : i32} : vector<3xf32>, vector<3xi1> into !llvm.vec<3 x ptr<f32>> 1944 1945// ----- 1946 1947func.func @scatter_op_index(%arg0: memref<?xindex>, %arg1: vector<3xindex>, %arg2: vector<3xi1>, %arg3: vector<3xindex>) { 1948 %0 = arith.constant 0: index 1949 vector.scatter %arg0[%0][%arg1], %arg2, %arg3 : memref<?xindex>, vector<3xindex>, vector<3xi1>, vector<3xindex> 1950 return 1951} 1952 1953// CHECK-LABEL: func @scatter_op_index 1954// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<i64>, vector<3xi64>) -> !llvm.vec<3 x ptr<i64>> 1955// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 8 : i32} : vector<3xi64>, vector<3xi1> into !llvm.vec<3 x ptr<i64>> 1956 1957// ----- 1958 1959func.func @scatter_2d_op(%arg0: memref<4x4xf32>, %arg1: vector<4xi32>, %arg2: vector<4xi1>, %arg3: vector<4xf32>) { 1960 %0 = arith.constant 3 : index 1961 vector.scatter %arg0[%0, %0][%arg1], %arg2, %arg3 : memref<4x4xf32>, vector<4xi32>, vector<4xi1>, vector<4xf32> 1962 return 1963} 1964 1965// CHECK-LABEL: func @scatter_2d_op 1966// CHECK: %[[B:.*]] = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1967// CHECK: %[[P:.*]] = llvm.getelementptr %[[B]][%{{.*}}] : (!llvm.ptr<f32>, vector<4xi32>) -> !llvm.vec<4 x ptr<f32>> 1968// CHECK: llvm.intr.masked.scatter %{{.*}}, %[[P]], %{{.*}} {alignment = 4 : i32} : vector<4xf32>, vector<4xi1> into !llvm.vec<4 x ptr<f32>> 1969 1970// ----- 1971 1972func.func @expand_load_op(%arg0: memref<?xf32>, %arg1: vector<11xi1>, %arg2: vector<11xf32>) -> vector<11xf32> { 1973 %c0 = arith.constant 0: index 1974 %0 = vector.expandload %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<11xi1>, vector<11xf32> into vector<11xf32> 1975 return %0 : vector<11xf32> 1976} 1977 1978// CHECK-LABEL: func @expand_load_op 1979// CHECK: %[[CO:.*]] = arith.constant 0 : index 1980// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64 1981// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 1982// CHECK: %[[E:.*]] = "llvm.intr.masked.expandload"(%[[P]], %{{.*}}, %{{.*}}) : (!llvm.ptr<f32>, vector<11xi1>, vector<11xf32>) -> vector<11xf32> 1983// CHECK: return %[[E]] : vector<11xf32> 1984 1985// ----- 1986 1987func.func @expand_load_op_index(%arg0: memref<?xindex>, %arg1: vector<11xi1>, %arg2: vector<11xindex>) -> vector<11xindex> { 1988 %c0 = arith.constant 0: index 1989 %0 = vector.expandload %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<11xi1>, vector<11xindex> into vector<11xindex> 1990 return %0 : vector<11xindex> 1991} 1992// CHECK-LABEL: func @expand_load_op_index 1993// CHECK: %{{.*}} = "llvm.intr.masked.expandload"(%{{.*}}, %{{.*}}, %{{.*}}) : (!llvm.ptr<i64>, vector<11xi1>, vector<11xi64>) -> vector<11xi64> 1994 1995// ----- 1996 1997func.func @compress_store_op(%arg0: memref<?xf32>, %arg1: vector<11xi1>, %arg2: vector<11xf32>) { 1998 %c0 = arith.constant 0: index 1999 vector.compressstore %arg0[%c0], %arg1, %arg2 : memref<?xf32>, vector<11xi1>, vector<11xf32> 2000 return 2001} 2002 2003// CHECK-LABEL: func @compress_store_op 2004// CHECK: %[[CO:.*]] = arith.constant 0 : index 2005// CHECK: %[[C:.*]] = builtin.unrealized_conversion_cast %[[CO]] : index to i64 2006// CHECK: %[[P:.*]] = llvm.getelementptr %{{.*}}[%[[C]]] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32> 2007// CHECK: "llvm.intr.masked.compressstore"(%{{.*}}, %[[P]], %{{.*}}) : (vector<11xf32>, !llvm.ptr<f32>, vector<11xi1>) -> () 2008 2009// ----- 2010 2011func.func @compress_store_op_index(%arg0: memref<?xindex>, %arg1: vector<11xi1>, %arg2: vector<11xindex>) { 2012 %c0 = arith.constant 0: index 2013 vector.compressstore %arg0[%c0], %arg1, %arg2 : memref<?xindex>, vector<11xi1>, vector<11xindex> 2014 return 2015} 2016// CHECK-LABEL: func @compress_store_op_index 2017// CHECK: "llvm.intr.masked.compressstore"(%{{.*}}, %{{.*}}, %{{.*}}) : (vector<11xi64>, !llvm.ptr<i64>, vector<11xi1>) -> () 2018 2019// ----- 2020 2021// CHECK-LABEL: @splat_0d 2022// CHECK-SAME: %[[ARG:.*]]: f32 2023func.func @splat_0d(%a: f32) -> vector<f32> { 2024 %v = vector.splat %a : vector<f32> 2025 return %v : vector<f32> 2026} 2027// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : vector<1xf32> 2028// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : i32 2029// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ARG]], %[[UNDEF]][%[[ZERO]] : i32] : vector<1xf32> 2030// CHECK-NEXT: %[[VCAST:[0-9]+]] = builtin.unrealized_conversion_cast %[[V]] : vector<1xf32> to vector<f32> 2031// CHECK-NEXT: return %[[VCAST]] : vector<f32> 2032 2033// ----- 2034 2035// CHECK-LABEL: @splat 2036// CHECK-SAME: %[[A:arg[0-9]+]]: vector<4xf32> 2037// CHECK-SAME: %[[ELT:arg[0-9]+]]: f32 2038func.func @splat(%a: vector<4xf32>, %b: f32) -> vector<4xf32> { 2039 %vb = vector.splat %b : vector<4xf32> 2040 %r = arith.mulf %a, %vb : vector<4xf32> 2041 return %r : vector<4xf32> 2042} 2043// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : vector<4xf32> 2044// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : i32 2045// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ELT]], %[[UNDEF]][%[[ZERO]] : i32] : vector<4xf32> 2046// CHECK-NEXT: %[[SPLAT:[0-9]+]] = llvm.shufflevector %[[V]], %[[UNDEF]] [0 : i32, 0 : i32, 0 : i32, 0 : i32] 2047// CHECK-NEXT: %[[SCALE:[0-9]+]] = arith.mulf %[[A]], %[[SPLAT]] : vector<4xf32> 2048// CHECK-NEXT: return %[[SCALE]] : vector<4xf32> 2049