1// RUN: mlir-opt -convert-std-to-llvm %s -split-input-file | FileCheck %s 2// RUN: mlir-opt -convert-std-to-llvm='index-bitwidth=32' %s -split-input-file | FileCheck --check-prefix=CHECK32 %s 3 4// CHECK-LABEL: func @empty() { 5// CHECK-NEXT: llvm.return 6// CHECK-NEXT: } 7func @empty() { 8^bb0: 9 return 10} 11 12// CHECK-LABEL: llvm.func @body(!llvm.i64) 13func private @body(index) 14 15// CHECK-LABEL: func @simple_loop() { 16// CHECK32-LABEL: func @simple_loop() { 17func @simple_loop() { 18^bb0: 19// CHECK-NEXT: llvm.br ^bb1 20// CHECK32-NEXT: llvm.br ^bb1 21 br ^bb1 22 23// CHECK-NEXT: ^bb1: // pred: ^bb0 24// CHECK-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64 25// CHECK-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64 26// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 27// CHECK32-NEXT: ^bb1: // pred: ^bb0 28// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32 29// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i32 30// CHECK32-NEXT: llvm.br ^bb2({{.*}} : !llvm.i32) 31^bb1: // pred: ^bb0 32 %c1 = constant 1 : index 33 %c42 = constant 42 : index 34 br ^bb2(%c1 : index) 35 36// CHECK: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb3 37// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 38// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4 39// CHECK32: ^bb2({{.*}}: !llvm.i32): // 2 preds: ^bb1, ^bb3 40// CHECK32-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i32 41// CHECK32-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4 42^bb2(%0: index): // 2 preds: ^bb1, ^bb3 43 %1 = cmpi "slt", %0, %c42 : index 44 cond_br %1, ^bb3, ^bb4 45 46// CHECK: ^bb3: // pred: ^bb2 47// CHECK-NEXT: llvm.call @body({{.*}}) : (!llvm.i64) -> () 48// CHECK-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64 49// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 50// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 51// CHECK32: ^bb3: // pred: ^bb2 52// CHECK32-NEXT: llvm.call @body({{.*}}) : (!llvm.i32) -> () 53// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32 54// CHECK32-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i32 55// CHECK32-NEXT: llvm.br ^bb2({{.*}} : !llvm.i32) 56^bb3: // pred: ^bb2 57 call @body(%0) : (index) -> () 58 %c1_0 = constant 1 : index 59 %2 = addi %0, %c1_0 : index 60 br ^bb2(%2 : index) 61 62// CHECK: ^bb4: // pred: ^bb2 63// CHECK-NEXT: llvm.return 64^bb4: // pred: ^bb2 65 return 66} 67 68// CHECK-LABEL: llvm.func @complex_numbers() 69// CHECK-NEXT: %[[REAL0:.*]] = llvm.mlir.constant(1.200000e+00 : f32) : !llvm.float 70// CHECK-NEXT: %[[IMAG0:.*]] = llvm.mlir.constant(3.400000e+00 : f32) : !llvm.float 71// CHECK-NEXT: %[[CPLX0:.*]] = llvm.mlir.undef : !llvm.struct<(float, float)> 72// CHECK-NEXT: %[[CPLX1:.*]] = llvm.insertvalue %[[REAL0]], %[[CPLX0]][0] : !llvm.struct<(float, float)> 73// CHECK-NEXT: %[[CPLX2:.*]] = llvm.insertvalue %[[IMAG0]], %[[CPLX1]][1] : !llvm.struct<(float, float)> 74// CHECK-NEXT: %[[REAL1:.*]] = llvm.extractvalue %[[CPLX2:.*]][0] : !llvm.struct<(float, float)> 75// CHECK-NEXT: %[[IMAG1:.*]] = llvm.extractvalue %[[CPLX2:.*]][1] : !llvm.struct<(float, float)> 76// CHECK-NEXT: llvm.return 77func @complex_numbers() { 78 %real0 = constant 1.2 : f32 79 %imag0 = constant 3.4 : f32 80 %cplx2 = create_complex %real0, %imag0 : complex<f32> 81 %real1 = re %cplx2 : complex<f32> 82 %imag1 = im %cplx2 : complex<f32> 83 return 84} 85 86// CHECK-LABEL: llvm.func @complex_addition() 87// CHECK-DAG: %[[A_REAL:.*]] = llvm.extractvalue %[[A:.*]][0] : !llvm.struct<(double, double)> 88// CHECK-DAG: %[[B_REAL:.*]] = llvm.extractvalue %[[B:.*]][0] : !llvm.struct<(double, double)> 89// CHECK-DAG: %[[A_IMAG:.*]] = llvm.extractvalue %[[A]][1] : !llvm.struct<(double, double)> 90// CHECK-DAG: %[[B_IMAG:.*]] = llvm.extractvalue %[[B]][1] : !llvm.struct<(double, double)> 91// CHECK: %[[C0:.*]] = llvm.mlir.undef : !llvm.struct<(double, double)> 92// CHECK-DAG: %[[C_REAL:.*]] = llvm.fadd %[[A_REAL]], %[[B_REAL]] : !llvm.double 93// CHECK-DAG: %[[C_IMAG:.*]] = llvm.fadd %[[A_IMAG]], %[[B_IMAG]] : !llvm.double 94// CHECK: %[[C1:.*]] = llvm.insertvalue %[[C_REAL]], %[[C0]][0] : !llvm.struct<(double, double)> 95// CHECK: %[[C2:.*]] = llvm.insertvalue %[[C_IMAG]], %[[C1]][1] : !llvm.struct<(double, double)> 96func @complex_addition() { 97 %a_re = constant 1.2 : f64 98 %a_im = constant 3.4 : f64 99 %a = create_complex %a_re, %a_im : complex<f64> 100 %b_re = constant 5.6 : f64 101 %b_im = constant 7.8 : f64 102 %b = create_complex %b_re, %b_im : complex<f64> 103 %c = addcf %a, %b : complex<f64> 104 return 105} 106 107// CHECK-LABEL: llvm.func @complex_substraction() 108// CHECK-DAG: %[[A_REAL:.*]] = llvm.extractvalue %[[A:.*]][0] : !llvm.struct<(double, double)> 109// CHECK-DAG: %[[B_REAL:.*]] = llvm.extractvalue %[[B:.*]][0] : !llvm.struct<(double, double)> 110// CHECK-DAG: %[[A_IMAG:.*]] = llvm.extractvalue %[[A]][1] : !llvm.struct<(double, double)> 111// CHECK-DAG: %[[B_IMAG:.*]] = llvm.extractvalue %[[B]][1] : !llvm.struct<(double, double)> 112// CHECK: %[[C0:.*]] = llvm.mlir.undef : !llvm.struct<(double, double)> 113// CHECK-DAG: %[[C_REAL:.*]] = llvm.fsub %[[A_REAL]], %[[B_REAL]] : !llvm.double 114// CHECK-DAG: %[[C_IMAG:.*]] = llvm.fsub %[[A_IMAG]], %[[B_IMAG]] : !llvm.double 115// CHECK: %[[C1:.*]] = llvm.insertvalue %[[C_REAL]], %[[C0]][0] : !llvm.struct<(double, double)> 116// CHECK: %[[C2:.*]] = llvm.insertvalue %[[C_IMAG]], %[[C1]][1] : !llvm.struct<(double, double)> 117func @complex_substraction() { 118 %a_re = constant 1.2 : f64 119 %a_im = constant 3.4 : f64 120 %a = create_complex %a_re, %a_im : complex<f64> 121 %b_re = constant 5.6 : f64 122 %b_im = constant 7.8 : f64 123 %b = create_complex %b_re, %b_im : complex<f64> 124 %c = subcf %a, %b : complex<f64> 125 return 126} 127 128// CHECK-LABEL: func @simple_caller() { 129// CHECK-NEXT: llvm.call @simple_loop() : () -> () 130// CHECK-NEXT: llvm.return 131// CHECK-NEXT: } 132func @simple_caller() { 133^bb0: 134 call @simple_loop() : () -> () 135 return 136} 137 138// Check that function call attributes persist during conversion. 139// CHECK-LABEL: @call_with_attributes 140func @call_with_attributes() { 141 // CHECK: llvm.call @simple_loop() {baz = [1, 2, 3, 4], foo = "bar"} : () -> () 142 call @simple_loop() {foo="bar", baz=[1,2,3,4]} : () -> () 143 return 144} 145 146// CHECK-LABEL: func @ml_caller() { 147// CHECK-NEXT: llvm.call @simple_loop() : () -> () 148// CHECK-NEXT: llvm.call @more_imperfectly_nested_loops() : () -> () 149// CHECK-NEXT: llvm.return 150// CHECK-NEXT: } 151func @ml_caller() { 152^bb0: 153 call @simple_loop() : () -> () 154 call @more_imperfectly_nested_loops() : () -> () 155 return 156} 157 158// CHECK-LABEL: llvm.func @body_args(!llvm.i64) -> !llvm.i64 159// CHECK32-LABEL: llvm.func @body_args(!llvm.i32) -> !llvm.i32 160func private @body_args(index) -> index 161// CHECK-LABEL: llvm.func @other(!llvm.i64, !llvm.i32) -> !llvm.i32 162// CHECK32-LABEL: llvm.func @other(!llvm.i32, !llvm.i32) -> !llvm.i32 163func private @other(index, i32) -> i32 164 165// CHECK-LABEL: func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 { 166// CHECK-NEXT: {{.*}} = llvm.mlir.constant(0 : i32) : !llvm.i32 167// CHECK-NEXT: llvm.br ^bb1 168// CHECK32-LABEL: func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 { 169// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(0 : i32) : !llvm.i32 170// CHECK32-NEXT: llvm.br ^bb1 171func @func_args(i32, i32) -> i32 { 172^bb0(%arg0: i32, %arg1: i32): 173 %c0_i32 = constant 0 : i32 174 br ^bb1 175 176// CHECK-NEXT: ^bb1: // pred: ^bb0 177// CHECK-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64 178// CHECK-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64 179// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 180// CHECK32-NEXT: ^bb1: // pred: ^bb0 181// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i32 182// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i32 183// CHECK32-NEXT: llvm.br ^bb2({{.*}} : !llvm.i32) 184^bb1: // pred: ^bb0 185 %c0 = constant 0 : index 186 %c42 = constant 42 : index 187 br ^bb2(%c0 : index) 188 189// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb3 190// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 191// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4 192// CHECK32-NEXT: ^bb2({{.*}}: !llvm.i32): // 2 preds: ^bb1, ^bb3 193// CHECK32-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i32 194// CHECK32-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4 195^bb2(%0: index): // 2 preds: ^bb1, ^bb3 196 %1 = cmpi "slt", %0, %c42 : index 197 cond_br %1, ^bb3, ^bb4 198 199// CHECK-NEXT: ^bb3: // pred: ^bb2 200// CHECK-NEXT: {{.*}} = llvm.call @body_args({{.*}}) : (!llvm.i64) -> !llvm.i64 201// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm.i64, !llvm.i32) -> !llvm.i32 202// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32 203// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm.i64, !llvm.i32) -> !llvm.i32 204// CHECK-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64 205// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 206// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 207// CHECK32-NEXT: ^bb3: // pred: ^bb2 208// CHECK32-NEXT: {{.*}} = llvm.call @body_args({{.*}}) : (!llvm.i32) -> !llvm.i32 209// CHECK32-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm.i32, !llvm.i32) -> !llvm.i32 210// CHECK32-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i32, !llvm.i32) -> !llvm.i32 211// CHECK32-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm.i32, !llvm.i32) -> !llvm.i32 212// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i32 213// CHECK32-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i32 214// CHECK32-NEXT: llvm.br ^bb2({{.*}} : !llvm.i32) 215^bb3: // pred: ^bb2 216 %2 = call @body_args(%0) : (index) -> index 217 %3 = call @other(%2, %arg0) : (index, i32) -> i32 218 %4 = call @other(%2, %3) : (index, i32) -> i32 219 %5 = call @other(%2, %arg1) : (index, i32) -> i32 220 %c1 = constant 1 : index 221 %6 = addi %0, %c1 : index 222 br ^bb2(%6 : index) 223 224// CHECK-NEXT: ^bb4: // pred: ^bb2 225// CHECK-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64 226// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32 227// CHECK-NEXT: llvm.return {{.*}} : !llvm.i32 228// CHECK32-NEXT: ^bb4: // pred: ^bb2 229// CHECK32-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i32 230// CHECK32-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i32, !llvm.i32) -> !llvm.i32 231// CHECK32-NEXT: llvm.return {{.*}} : !llvm.i32 232^bb4: // pred: ^bb2 233 %c0_0 = constant 0 : index 234 %7 = call @other(%c0_0, %c0_i32) : (index, i32) -> i32 235 return %7 : i32 236} 237 238// CHECK-LABEL: llvm.func @pre(!llvm.i64) 239// CHECK32-LABEL: llvm.func @pre(!llvm.i32) 240func private @pre(index) 241 242// CHECK-LABEL: llvm.func @body2(!llvm.i64, !llvm.i64) 243// CHECK32-LABEL: llvm.func @body2(!llvm.i32, !llvm.i32) 244func private @body2(index, index) 245 246// CHECK-LABEL: llvm.func @post(!llvm.i64) 247// CHECK32-LABEL: llvm.func @post(!llvm.i32) 248func private @post(index) 249 250// CHECK-LABEL: func @imperfectly_nested_loops() { 251// CHECK-NEXT: llvm.br ^bb1 252func @imperfectly_nested_loops() { 253^bb0: 254 br ^bb1 255 256// CHECK-NEXT: ^bb1: // pred: ^bb0 257// CHECK-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64 258// CHECK-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64 259// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 260^bb1: // pred: ^bb0 261 %c0 = constant 0 : index 262 %c42 = constant 42 : index 263 br ^bb2(%c0 : index) 264 265// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb7 266// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 267// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb8 268^bb2(%0: index): // 2 preds: ^bb1, ^bb7 269 %1 = cmpi "slt", %0, %c42 : index 270 cond_br %1, ^bb3, ^bb8 271 272// CHECK-NEXT: ^bb3: 273// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm.i64) -> () 274// CHECK-NEXT: llvm.br ^bb4 275^bb3: // pred: ^bb2 276 call @pre(%0) : (index) -> () 277 br ^bb4 278 279// CHECK-NEXT: ^bb4: // pred: ^bb3 280// CHECK-NEXT: {{.*}} = llvm.mlir.constant(7 : index) : !llvm.i64 281// CHECK-NEXT: {{.*}} = llvm.mlir.constant(56 : index) : !llvm.i64 282// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64) 283^bb4: // pred: ^bb3 284 %c7 = constant 7 : index 285 %c56 = constant 56 : index 286 br ^bb5(%c7 : index) 287 288// CHECK-NEXT: ^bb5({{.*}}: !llvm.i64): // 2 preds: ^bb4, ^bb6 289// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 290// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb6, ^bb7 291^bb5(%2: index): // 2 preds: ^bb4, ^bb6 292 %3 = cmpi "slt", %2, %c56 : index 293 cond_br %3, ^bb6, ^bb7 294 295// CHECK-NEXT: ^bb6: // pred: ^bb5 296// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> () 297// CHECK-NEXT: {{.*}} = llvm.mlir.constant(2 : index) : !llvm.i64 298// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 299// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64) 300^bb6: // pred: ^bb5 301 call @body2(%0, %2) : (index, index) -> () 302 %c2 = constant 2 : index 303 %4 = addi %2, %c2 : index 304 br ^bb5(%4 : index) 305 306// CHECK-NEXT: ^bb7: // pred: ^bb5 307// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm.i64) -> () 308// CHECK-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64 309// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 310// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 311^bb7: // pred: ^bb5 312 call @post(%0) : (index) -> () 313 %c1 = constant 1 : index 314 %5 = addi %0, %c1 : index 315 br ^bb2(%5 : index) 316 317// CHECK-NEXT: ^bb8: // pred: ^bb2 318// CHECK-NEXT: llvm.return 319^bb8: // pred: ^bb2 320 return 321} 322 323// CHECK-LABEL: llvm.func @mid(!llvm.i64) 324func private @mid(index) 325 326// CHECK-LABEL: llvm.func @body3(!llvm.i64, !llvm.i64) 327func private @body3(index, index) 328 329// A complete function transformation check. 330// CHECK-LABEL: func @more_imperfectly_nested_loops() { 331// CHECK-NEXT: llvm.br ^bb1 332// CHECK-NEXT:^bb1: // pred: ^bb0 333// CHECK-NEXT: {{.*}} = llvm.mlir.constant(0 : index) : !llvm.i64 334// CHECK-NEXT: {{.*}} = llvm.mlir.constant(42 : index) : !llvm.i64 335// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 336// CHECK-NEXT:^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb11 337// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 338// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb12 339// CHECK-NEXT:^bb3: // pred: ^bb2 340// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm.i64) -> () 341// CHECK-NEXT: llvm.br ^bb4 342// CHECK-NEXT:^bb4: // pred: ^bb3 343// CHECK-NEXT: {{.*}} = llvm.mlir.constant(7 : index) : !llvm.i64 344// CHECK-NEXT: {{.*}} = llvm.mlir.constant(56 : index) : !llvm.i64 345// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64) 346// CHECK-NEXT:^bb5({{.*}}: !llvm.i64): // 2 preds: ^bb4, ^bb6 347// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 348// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb6, ^bb7 349// CHECK-NEXT:^bb6: // pred: ^bb5 350// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> () 351// CHECK-NEXT: {{.*}} = llvm.mlir.constant(2 : index) : !llvm.i64 352// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 353// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64) 354// CHECK-NEXT:^bb7: // pred: ^bb5 355// CHECK-NEXT: llvm.call @mid({{.*}}) : (!llvm.i64) -> () 356// CHECK-NEXT: llvm.br ^bb8 357// CHECK-NEXT:^bb8: // pred: ^bb7 358// CHECK-NEXT: {{.*}} = llvm.mlir.constant(18 : index) : !llvm.i64 359// CHECK-NEXT: {{.*}} = llvm.mlir.constant(37 : index) : !llvm.i64 360// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm.i64) 361// CHECK-NEXT:^bb9({{.*}}: !llvm.i64): // 2 preds: ^bb8, ^bb10 362// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64 363// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb10, ^bb11 364// CHECK-NEXT:^bb10: // pred: ^bb9 365// CHECK-NEXT: llvm.call @body3({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> () 366// CHECK-NEXT: {{.*}} = llvm.mlir.constant(3 : index) : !llvm.i64 367// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 368// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm.i64) 369// CHECK-NEXT:^bb11: // pred: ^bb9 370// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm.i64) -> () 371// CHECK-NEXT: {{.*}} = llvm.mlir.constant(1 : index) : !llvm.i64 372// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 373// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64) 374// CHECK-NEXT:^bb12: // pred: ^bb2 375// CHECK-NEXT: llvm.return 376// CHECK-NEXT: } 377func @more_imperfectly_nested_loops() { 378^bb0: 379 br ^bb1 380^bb1: // pred: ^bb0 381 %c0 = constant 0 : index 382 %c42 = constant 42 : index 383 br ^bb2(%c0 : index) 384^bb2(%0: index): // 2 preds: ^bb1, ^bb11 385 %1 = cmpi "slt", %0, %c42 : index 386 cond_br %1, ^bb3, ^bb12 387^bb3: // pred: ^bb2 388 call @pre(%0) : (index) -> () 389 br ^bb4 390^bb4: // pred: ^bb3 391 %c7 = constant 7 : index 392 %c56 = constant 56 : index 393 br ^bb5(%c7 : index) 394^bb5(%2: index): // 2 preds: ^bb4, ^bb6 395 %3 = cmpi "slt", %2, %c56 : index 396 cond_br %3, ^bb6, ^bb7 397^bb6: // pred: ^bb5 398 call @body2(%0, %2) : (index, index) -> () 399 %c2 = constant 2 : index 400 %4 = addi %2, %c2 : index 401 br ^bb5(%4 : index) 402^bb7: // pred: ^bb5 403 call @mid(%0) : (index) -> () 404 br ^bb8 405^bb8: // pred: ^bb7 406 %c18 = constant 18 : index 407 %c37 = constant 37 : index 408 br ^bb9(%c18 : index) 409^bb9(%5: index): // 2 preds: ^bb8, ^bb10 410 %6 = cmpi "slt", %5, %c37 : index 411 cond_br %6, ^bb10, ^bb11 412^bb10: // pred: ^bb9 413 call @body3(%0, %5) : (index, index) -> () 414 %c3 = constant 3 : index 415 %7 = addi %5, %c3 : index 416 br ^bb9(%7 : index) 417^bb11: // pred: ^bb9 418 call @post(%0) : (index) -> () 419 %c1 = constant 1 : index 420 %8 = addi %0, %c1 : index 421 br ^bb2(%8 : index) 422^bb12: // pred: ^bb2 423 return 424} 425 426// CHECK-LABEL: llvm.func @get_i64() -> !llvm.i64 427func private @get_i64() -> (i64) 428// CHECK-LABEL: llvm.func @get_f32() -> !llvm.float 429func private @get_f32() -> (f32) 430// CHECK-LABEL: llvm.func @get_c16() -> !llvm.struct<(half, half)> 431func private @get_c16() -> (complex<f16>) 432// CHECK-LABEL: llvm.func @get_c32() -> !llvm.struct<(float, float)> 433func private @get_c32() -> (complex<f32>) 434// CHECK-LABEL: llvm.func @get_c64() -> !llvm.struct<(double, double)> 435func private @get_c64() -> (complex<f64>) 436// CHECK-LABEL: llvm.func @get_memref() -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)> 437// CHECK32-LABEL: llvm.func @get_memref() -> !llvm.struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)> 438func private @get_memref() -> (memref<42x?x10x?xf32>) 439 440// CHECK-LABEL: llvm.func @multireturn() -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> { 441// CHECK32-LABEL: llvm.func @multireturn() -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> { 442func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) { 443^bb0: 444// CHECK-NEXT: {{.*}} = llvm.call @get_i64() : () -> !llvm.i64 445// CHECK-NEXT: {{.*}} = llvm.call @get_f32() : () -> !llvm.float 446// CHECK-NEXT: {{.*}} = llvm.call @get_memref() : () -> !llvm.struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)> 447// CHECK32-NEXT: {{.*}} = llvm.call @get_i64() : () -> !llvm.i64 448// CHECK32-NEXT: {{.*}} = llvm.call @get_f32() : () -> !llvm.float 449// CHECK32-NEXT: {{.*}} = llvm.call @get_memref() : () -> !llvm.struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)> 450 %0 = call @get_i64() : () -> (i64) 451 %1 = call @get_f32() : () -> (f32) 452 %2 = call @get_memref() : () -> (memref<42x?x10x?xf32>) 453// CHECK-NEXT: {{.*}} = llvm.mlir.undef : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 454// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 455// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 456// CHECK-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 457// CHECK-NEXT: llvm.return {{.*}} : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 458// CHECK32-NEXT: {{.*}} = llvm.mlir.undef : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 459// CHECK32-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 460// CHECK32-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 461// CHECK32-NEXT: {{.*}} = llvm.insertvalue {{.*}}, {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 462// CHECK32-NEXT: llvm.return {{.*}} : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 463 return %0, %1, %2 : i64, f32, memref<42x?x10x?xf32> 464} 465 466 467// CHECK-LABEL: llvm.func @multireturn_caller() { 468// CHECK32-LABEL: llvm.func @multireturn_caller() { 469func @multireturn_caller() { 470^bb0: 471// CHECK-NEXT: {{.*}} = llvm.call @multireturn() : () -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 472// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 473// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 474// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i64, array<4 x i64>, array<4 x i64>)>)> 475// CHECK32-NEXT: {{.*}} = llvm.call @multireturn() : () -> !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 476// CHECK32-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 477// CHECK32-NEXT: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 478// CHECK32-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm.struct<(i64, float, struct<(ptr<float>, ptr<float>, i32, array<4 x i32>, array<4 x i32>)>)> 479 %0:3 = call @multireturn() : () -> (i64, f32, memref<42x?x10x?xf32>) 480 %1 = constant 42 : i64 481// CHECK: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64 482 %2 = addi %0#0, %1 : i64 483 %3 = constant 42.0 : f32 484// CHECK: {{.*}} = llvm.fadd {{.*}}, {{.*}} : !llvm.float 485 %4 = addf %0#1, %3 : f32 486 %5 = constant 0 : index 487 return 488} 489 490// CHECK-LABEL: llvm.func @vector_ops(%arg0: !llvm.vec<4 x float>, %arg1: !llvm.vec<4 x i1>, %arg2: !llvm.vec<4 x i64>, %arg3: !llvm.vec<4 x i64>) -> !llvm.vec<4 x float> { 491func @vector_ops(%arg0: vector<4xf32>, %arg1: vector<4xi1>, %arg2: vector<4xi64>, %arg3: vector<4xi64>) -> vector<4xf32> { 492// CHECK-NEXT: %0 = llvm.mlir.constant(dense<4.200000e+01> : vector<4xf32>) : !llvm.vec<4 x float> 493 %0 = constant dense<42.> : vector<4xf32> 494// CHECK-NEXT: %1 = llvm.fadd %arg0, %0 : !llvm.vec<4 x float> 495 %1 = addf %arg0, %0 : vector<4xf32> 496// CHECK-NEXT: %2 = llvm.sdiv %arg2, %arg2 : !llvm.vec<4 x i64> 497 %3 = divi_signed %arg2, %arg2 : vector<4xi64> 498// CHECK-NEXT: %3 = llvm.udiv %arg2, %arg2 : !llvm.vec<4 x i64> 499 %4 = divi_unsigned %arg2, %arg2 : vector<4xi64> 500// CHECK-NEXT: %4 = llvm.srem %arg2, %arg2 : !llvm.vec<4 x i64> 501 %5 = remi_signed %arg2, %arg2 : vector<4xi64> 502// CHECK-NEXT: %5 = llvm.urem %arg2, %arg2 : !llvm.vec<4 x i64> 503 %6 = remi_unsigned %arg2, %arg2 : vector<4xi64> 504// CHECK-NEXT: %6 = llvm.fdiv %arg0, %0 : !llvm.vec<4 x float> 505 %7 = divf %arg0, %0 : vector<4xf32> 506// CHECK-NEXT: %7 = llvm.frem %arg0, %0 : !llvm.vec<4 x float> 507 %8 = remf %arg0, %0 : vector<4xf32> 508// CHECK-NEXT: %8 = llvm.and %arg2, %arg3 : !llvm.vec<4 x i64> 509 %9 = and %arg2, %arg3 : vector<4xi64> 510// CHECK-NEXT: %9 = llvm.or %arg2, %arg3 : !llvm.vec<4 x i64> 511 %10 = or %arg2, %arg3 : vector<4xi64> 512// CHECK-NEXT: %10 = llvm.xor %arg2, %arg3 : !llvm.vec<4 x i64> 513 %11 = xor %arg2, %arg3 : vector<4xi64> 514// CHECK-NEXT: %11 = llvm.shl %arg2, %arg2 : !llvm.vec<4 x i64> 515 %12 = shift_left %arg2, %arg2 : vector<4xi64> 516// CHECK-NEXT: %12 = llvm.ashr %arg2, %arg2 : !llvm.vec<4 x i64> 517 %13 = shift_right_signed %arg2, %arg2 : vector<4xi64> 518// CHECK-NEXT: %13 = llvm.lshr %arg2, %arg2 : !llvm.vec<4 x i64> 519 %14 = shift_right_unsigned %arg2, %arg2 : vector<4xi64> 520 return %1 : vector<4xf32> 521} 522 523// CHECK-LABEL: @ops 524func @ops(f32, f32, i32, i32, f64) -> (f32, i32) { 525^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32, %arg4: f64): 526// CHECK-NEXT: %0 = llvm.fsub %arg0, %arg1 : !llvm.float 527 %0 = subf %arg0, %arg1: f32 528// CHECK-NEXT: %1 = llvm.sub %arg2, %arg3 : !llvm.i32 529 %1 = subi %arg2, %arg3: i32 530// CHECK-NEXT: %2 = llvm.icmp "slt" %arg2, %1 : !llvm.i32 531 %2 = cmpi "slt", %arg2, %1 : i32 532// CHECK-NEXT: %3 = llvm.sdiv %arg2, %arg3 : !llvm.i32 533 %3 = divi_signed %arg2, %arg3 : i32 534// CHECK-NEXT: %4 = llvm.udiv %arg2, %arg3 : !llvm.i32 535 %4 = divi_unsigned %arg2, %arg3 : i32 536// CHECK-NEXT: %5 = llvm.srem %arg2, %arg3 : !llvm.i32 537 %5 = remi_signed %arg2, %arg3 : i32 538// CHECK-NEXT: %6 = llvm.urem %arg2, %arg3 : !llvm.i32 539 %6 = remi_unsigned %arg2, %arg3 : i32 540// CHECK-NEXT: %7 = llvm.select %2, %arg2, %arg3 : !llvm.i1, !llvm.i32 541 %7 = select %2, %arg2, %arg3 : i32 542// CHECK-NEXT: %8 = llvm.fdiv %arg0, %arg1 : !llvm.float 543 %8 = divf %arg0, %arg1 : f32 544// CHECK-NEXT: %9 = llvm.frem %arg0, %arg1 : !llvm.float 545 %9 = remf %arg0, %arg1 : f32 546// CHECK-NEXT: %10 = llvm.and %arg2, %arg3 : !llvm.i32 547 %10 = and %arg2, %arg3 : i32 548// CHECK-NEXT: %11 = llvm.or %arg2, %arg3 : !llvm.i32 549 %11 = or %arg2, %arg3 : i32 550// CHECK-NEXT: %12 = llvm.xor %arg2, %arg3 : !llvm.i32 551 %12 = xor %arg2, %arg3 : i32 552// CHECK-NEXT: %13 = "llvm.intr.exp"(%arg0) : (!llvm.float) -> !llvm.float 553 %13 = std.exp %arg0 : f32 554// CHECK-NEXT: %14 = "llvm.intr.exp2"(%arg0) : (!llvm.float) -> !llvm.float 555 %14 = std.exp2 %arg0 : f32 556// CHECK-NEXT: %15 = llvm.mlir.constant(7.900000e-01 : f64) : !llvm.double 557 %15 = constant 7.9e-01 : f64 558// CHECK-NEXT: %16 = llvm.shl %arg2, %arg3 : !llvm.i32 559 %16 = shift_left %arg2, %arg3 : i32 560// CHECK-NEXT: %17 = llvm.ashr %arg2, %arg3 : !llvm.i32 561 %17 = shift_right_signed %arg2, %arg3 : i32 562// CHECK-NEXT: %18 = llvm.lshr %arg2, %arg3 : !llvm.i32 563 %18 = shift_right_unsigned %arg2, %arg3 : i32 564// CHECK-NEXT: %{{[0-9]+}} = "llvm.intr.sqrt"(%arg0) : (!llvm.float) -> !llvm.float 565 %19 = std.sqrt %arg0 : f32 566// CHECK-NEXT: %{{[0-9]+}} = "llvm.intr.sqrt"(%arg4) : (!llvm.double) -> !llvm.double 567 %20 = std.sqrt %arg4 : f64 568 return %0, %4 : f32, i32 569} 570 571// Checking conversion of index types to integers using i1, assuming no target 572// system would have a 1-bit address space. Otherwise, we would have had to 573// make this test dependent on the pointer size on the target system. 574// CHECK-LABEL: @index_cast 575func @index_cast(%arg0: index, %arg1: i1) { 576// CHECK-NEXT: = llvm.trunc %arg0 : !llvm.i{{.*}} to !llvm.i1 577 %0 = index_cast %arg0: index to i1 578// CHECK-NEXT: = llvm.sext %arg1 : !llvm.i1 to !llvm.i{{.*}} 579 %1 = index_cast %arg1: i1 to index 580 return 581} 582 583// Checking conversion of signed integer types to floating point. 584// CHECK-LABEL: @sitofp 585func @sitofp(%arg0 : i32, %arg1 : i64) { 586// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i32 to !llvm.float 587 %0 = sitofp %arg0: i32 to f32 588// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i32 to !llvm.double 589 %1 = sitofp %arg0: i32 to f64 590// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i64 to !llvm.float 591 %2 = sitofp %arg1: i64 to f32 592// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.i64 to !llvm.double 593 %3 = sitofp %arg1: i64 to f64 594 return 595} 596 597// Checking conversion of integer vectors to floating point vector types. 598// CHECK-LABEL: @sitofp_vector 599func @sitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) { 600// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x float> 601 %0 = sitofp %arg0: vector<2xi16> to vector<2xf32> 602// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x double> 603 %1 = sitofp %arg0: vector<2xi16> to vector<2xf64> 604// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x float> 605 %2 = sitofp %arg1: vector<2xi32> to vector<2xf32> 606// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x double> 607 %3 = sitofp %arg1: vector<2xi32> to vector<2xf64> 608// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x float> 609 %4 = sitofp %arg2: vector<2xi64> to vector<2xf32> 610// CHECK-NEXT: = llvm.sitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x double> 611 %5 = sitofp %arg2: vector<2xi64> to vector<2xf64> 612 return 613} 614 615// Checking conversion of unsigned integer types to floating point. 616// CHECK-LABEL: @uitofp 617func @uitofp(%arg0 : i32, %arg1 : i64) { 618// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.float 619 %0 = uitofp %arg0: i32 to f32 620// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i32 to !llvm.double 621 %1 = uitofp %arg0: i32 to f64 622// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.float 623 %2 = uitofp %arg1: i64 to f32 624// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.i64 to !llvm.double 625 %3 = uitofp %arg1: i64 to f64 626 return 627} 628 629// Checking conversion of integer types to floating point. 630// CHECK-LABEL: @fpext 631func @fpext(%arg0 : f16, %arg1 : f32) { 632// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.half to !llvm.float 633 %0 = fpext %arg0: f16 to f32 634// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.half to !llvm.double 635 %1 = fpext %arg0: f16 to f64 636// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.float to !llvm.double 637 %2 = fpext %arg1: f32 to f64 638 return 639} 640 641// Checking conversion of integer types to floating point. 642// CHECK-LABEL: @fpext 643func @fpext_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>) { 644// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x float> 645 %0 = fpext %arg0: vector<2xf16> to vector<2xf32> 646// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x double> 647 %1 = fpext %arg0: vector<2xf16> to vector<2xf64> 648// CHECK-NEXT: = llvm.fpext {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x double> 649 %2 = fpext %arg1: vector<2xf32> to vector<2xf64> 650 return 651} 652 653// Checking conversion of floating point to integer types. 654// CHECK-LABEL: @fptosi 655func @fptosi(%arg0 : f32, %arg1 : f64) { 656// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.float to !llvm.i32 657 %0 = fptosi %arg0: f32 to i32 658// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.float to !llvm.i64 659 %1 = fptosi %arg0: f32 to i64 660// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.double to !llvm.i32 661 %2 = fptosi %arg1: f64 to i32 662// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.double to !llvm.i64 663 %3 = fptosi %arg1: f64 to i64 664 return 665} 666 667// Checking conversion of floating point vectors to integer vector types. 668// CHECK-LABEL: @fptosi_vector 669func @fptosi_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) { 670// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i32> 671 %0 = fptosi %arg0: vector<2xf16> to vector<2xi32> 672// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i64> 673 %1 = fptosi %arg0: vector<2xf16> to vector<2xi64> 674// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i32> 675 %2 = fptosi %arg1: vector<2xf32> to vector<2xi32> 676// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i64> 677 %3 = fptosi %arg1: vector<2xf32> to vector<2xi64> 678// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i32> 679 %4 = fptosi %arg2: vector<2xf64> to vector<2xi32> 680// CHECK-NEXT: = llvm.fptosi {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i64> 681 %5 = fptosi %arg2: vector<2xf64> to vector<2xi64> 682 return 683} 684 685// Checking conversion of floating point to integer types. 686// CHECK-LABEL: @fptoui 687func @fptoui(%arg0 : f32, %arg1 : f64) { 688// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i32 689 %0 = fptoui %arg0: f32 to i32 690// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.float to !llvm.i64 691 %1 = fptoui %arg0: f32 to i64 692// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i32 693 %2 = fptoui %arg1: f64 to i32 694// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.double to !llvm.i64 695 %3 = fptoui %arg1: f64 to i64 696 return 697} 698 699// Checking conversion of floating point vectors to integer vector types. 700// CHECK-LABEL: @fptoui_vector 701func @fptoui_vector(%arg0 : vector<2xf16>, %arg1 : vector<2xf32>, %arg2 : vector<2xf64>) { 702// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i32> 703 %0 = fptoui %arg0: vector<2xf16> to vector<2xi32> 704// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x half> to !llvm.vec<2 x i64> 705 %1 = fptoui %arg0: vector<2xf16> to vector<2xi64> 706// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i32> 707 %2 = fptoui %arg1: vector<2xf32> to vector<2xi32> 708// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x i64> 709 %3 = fptoui %arg1: vector<2xf32> to vector<2xi64> 710// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i32> 711 %4 = fptoui %arg2: vector<2xf64> to vector<2xi32> 712// CHECK-NEXT: = llvm.fptoui {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x i64> 713 %5 = fptoui %arg2: vector<2xf64> to vector<2xi64> 714 return 715} 716 717// Checking conversion of integer vectors to floating point vector types. 718// CHECK-LABEL: @uitofp_vector 719func @uitofp_vector(%arg0 : vector<2xi16>, %arg1 : vector<2xi32>, %arg2 : vector<2xi64>) { 720// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x float> 721 %0 = uitofp %arg0: vector<2xi16> to vector<2xf32> 722// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i16> to !llvm.vec<2 x double> 723 %1 = uitofp %arg0: vector<2xi16> to vector<2xf64> 724// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x float> 725 %2 = uitofp %arg1: vector<2xi32> to vector<2xf32> 726// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i32> to !llvm.vec<2 x double> 727 %3 = uitofp %arg1: vector<2xi32> to vector<2xf64> 728// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x float> 729 %4 = uitofp %arg2: vector<2xi64> to vector<2xf32> 730// CHECK-NEXT: = llvm.uitofp {{.*}} : !llvm.vec<2 x i64> to !llvm.vec<2 x double> 731 %5 = uitofp %arg2: vector<2xi64> to vector<2xf64> 732 return 733} 734 735// Checking conversion of integer types to floating point. 736// CHECK-LABEL: @fptrunc 737func @fptrunc(%arg0 : f32, %arg1 : f64) { 738// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.float to !llvm.half 739 %0 = fptrunc %arg0: f32 to f16 740// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.double to !llvm.half 741 %1 = fptrunc %arg1: f64 to f16 742// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.double to !llvm.float 743 %2 = fptrunc %arg1: f64 to f32 744 return 745} 746 747// Checking conversion of integer types to floating point. 748// CHECK-LABEL: @fptrunc 749func @fptrunc_vector(%arg0 : vector<2xf32>, %arg1 : vector<2xf64>) { 750// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x float> to !llvm.vec<2 x half> 751 %0 = fptrunc %arg0: vector<2xf32> to vector<2xf16> 752// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x half> 753 %1 = fptrunc %arg1: vector<2xf64> to vector<2xf16> 754// CHECK-NEXT: = llvm.fptrunc {{.*}} : !llvm.vec<2 x double> to !llvm.vec<2 x float> 755 %2 = fptrunc %arg1: vector<2xf64> to vector<2xf32> 756 return 757} 758 759// Check sign and zero extension and truncation of integers. 760// CHECK-LABEL: @integer_extension_and_truncation 761func @integer_extension_and_truncation() { 762// CHECK-NEXT: %0 = llvm.mlir.constant(-3 : i3) : !llvm.i3 763 %0 = constant 5 : i3 764// CHECK-NEXT: = llvm.sext %0 : !llvm.i3 to !llvm.i6 765 %1 = sexti %0 : i3 to i6 766// CHECK-NEXT: = llvm.zext %0 : !llvm.i3 to !llvm.i6 767 %2 = zexti %0 : i3 to i6 768// CHECK-NEXT: = llvm.trunc %0 : !llvm.i3 to !llvm.i2 769 %3 = trunci %0 : i3 to i2 770 return 771} 772 773// CHECK-LABEL: @dfs_block_order 774func @dfs_block_order(%arg0: i32) -> (i32) { 775// CHECK-NEXT: %[[CST:.*]] = llvm.mlir.constant(42 : i32) : !llvm.i32 776 %0 = constant 42 : i32 777// CHECK-NEXT: llvm.br ^bb2 778 br ^bb2 779 780// CHECK-NEXT: ^bb1: 781// CHECK-NEXT: %[[ADD:.*]] = llvm.add %arg0, %[[CST]] : !llvm.i32 782// CHECK-NEXT: llvm.return %[[ADD]] : !llvm.i32 783^bb1: 784 %2 = addi %arg0, %0 : i32 785 return %2 : i32 786 787// CHECK-NEXT: ^bb2: 788^bb2: 789// CHECK-NEXT: llvm.br ^bb1 790 br ^bb1 791} 792 793// CHECK-LABEL: func @fcmp(%arg0: !llvm.float, %arg1: !llvm.float) { 794func @fcmp(f32, f32) -> () { 795^bb0(%arg0: f32, %arg1: f32): 796 // CHECK: llvm.fcmp "oeq" %arg0, %arg1 : !llvm.float 797 // CHECK-NEXT: llvm.fcmp "ogt" %arg0, %arg1 : !llvm.float 798 // CHECK-NEXT: llvm.fcmp "oge" %arg0, %arg1 : !llvm.float 799 // CHECK-NEXT: llvm.fcmp "olt" %arg0, %arg1 : !llvm.float 800 // CHECK-NEXT: llvm.fcmp "ole" %arg0, %arg1 : !llvm.float 801 // CHECK-NEXT: llvm.fcmp "one" %arg0, %arg1 : !llvm.float 802 // CHECK-NEXT: llvm.fcmp "ord" %arg0, %arg1 : !llvm.float 803 // CHECK-NEXT: llvm.fcmp "ueq" %arg0, %arg1 : !llvm.float 804 // CHECK-NEXT: llvm.fcmp "ugt" %arg0, %arg1 : !llvm.float 805 // CHECK-NEXT: llvm.fcmp "uge" %arg0, %arg1 : !llvm.float 806 // CHECK-NEXT: llvm.fcmp "ult" %arg0, %arg1 : !llvm.float 807 // CHECK-NEXT: llvm.fcmp "ule" %arg0, %arg1 : !llvm.float 808 // CHECK-NEXT: llvm.fcmp "une" %arg0, %arg1 : !llvm.float 809 // CHECK-NEXT: llvm.fcmp "uno" %arg0, %arg1 : !llvm.float 810 // CHECK-NEXT: llvm.return 811 %1 = cmpf "oeq", %arg0, %arg1 : f32 812 %2 = cmpf "ogt", %arg0, %arg1 : f32 813 %3 = cmpf "oge", %arg0, %arg1 : f32 814 %4 = cmpf "olt", %arg0, %arg1 : f32 815 %5 = cmpf "ole", %arg0, %arg1 : f32 816 %6 = cmpf "one", %arg0, %arg1 : f32 817 %7 = cmpf "ord", %arg0, %arg1 : f32 818 %8 = cmpf "ueq", %arg0, %arg1 : f32 819 %9 = cmpf "ugt", %arg0, %arg1 : f32 820 %10 = cmpf "uge", %arg0, %arg1 : f32 821 %11 = cmpf "ult", %arg0, %arg1 : f32 822 %12 = cmpf "ule", %arg0, %arg1 : f32 823 %13 = cmpf "une", %arg0, %arg1 : f32 824 %14 = cmpf "uno", %arg0, %arg1 : f32 825 826 return 827} 828 829// CHECK-LABEL: @vec_bin 830func @vec_bin(%arg0: vector<2x2x2xf32>) -> vector<2x2x2xf32> { 831 %0 = addf %arg0, %arg0 : vector<2x2x2xf32> 832 return %0 : vector<2x2x2xf32> 833 834// CHECK-NEXT: llvm.mlir.undef : !llvm.array<2 x array<2 x vec<2 x float>>> 835 836// This block appears 2x2 times 837// CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>> 838// CHECK-NEXT: llvm.extractvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>> 839// CHECK-NEXT: llvm.fadd %{{.*}} : !llvm.vec<2 x float> 840// CHECK-NEXT: llvm.insertvalue %{{.*}}[0, 0] : !llvm.array<2 x array<2 x vec<2 x float>>> 841 842// We check the proper indexing of extract/insert in the remaining 3 positions. 843// CHECK: llvm.extractvalue %{{.*}}[0, 1] : !llvm.array<2 x array<2 x vec<2 x float>>> 844// CHECK: llvm.insertvalue %{{.*}}[0, 1] : !llvm.array<2 x array<2 x vec<2 x float>>> 845// CHECK: llvm.extractvalue %{{.*}}[1, 0] : !llvm.array<2 x array<2 x vec<2 x float>>> 846// CHECK: llvm.insertvalue %{{.*}}[1, 0] : !llvm.array<2 x array<2 x vec<2 x float>>> 847// CHECK: llvm.extractvalue %{{.*}}[1, 1] : !llvm.array<2 x array<2 x vec<2 x float>>> 848// CHECK: llvm.insertvalue %{{.*}}[1, 1] : !llvm.array<2 x array<2 x vec<2 x float>>> 849 850// And we're done 851// CHECK-NEXT: return 852} 853 854// CHECK-LABEL: @splat 855// CHECK-SAME: %[[A:arg[0-9]+]]: !llvm.vec<4 x float> 856// CHECK-SAME: %[[ELT:arg[0-9]+]]: !llvm.float 857func @splat(%a: vector<4xf32>, %b: f32) -> vector<4xf32> { 858 %vb = splat %b : vector<4xf32> 859 %r = mulf %a, %vb : vector<4xf32> 860 return %r : vector<4xf32> 861} 862// CHECK-NEXT: %[[UNDEF:[0-9]+]] = llvm.mlir.undef : !llvm.vec<4 x float> 863// CHECK-NEXT: %[[ZERO:[0-9]+]] = llvm.mlir.constant(0 : i32) : !llvm.i32 864// CHECK-NEXT: %[[V:[0-9]+]] = llvm.insertelement %[[ELT]], %[[UNDEF]][%[[ZERO]] : !llvm.i32] : !llvm.vec<4 x float> 865// CHECK-NEXT: %[[SPLAT:[0-9]+]] = llvm.shufflevector %[[V]], %[[UNDEF]] [0 : i32, 0 : i32, 0 : i32, 0 : i32] 866// CHECK-NEXT: %[[SCALE:[0-9]+]] = llvm.fmul %[[A]], %[[SPLAT]] : !llvm.vec<4 x float> 867// CHECK-NEXT: llvm.return %[[SCALE]] : !llvm.vec<4 x float> 868 869// CHECK-LABEL: func @view( 870// CHECK: %[[ARG0:.*]]: !llvm.i64, %[[ARG1:.*]]: !llvm.i64, %[[ARG2:.*]]: !llvm.i64 871func @view(%arg0 : index, %arg1 : index, %arg2 : index) { 872 // CHECK: llvm.mlir.constant(2048 : index) : !llvm.i64 873 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 874 %0 = alloc() : memref<2048xi8> 875 876 // Test two dynamic sizes. 877 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 878 // CHECK: %[[BASE_PTR:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 879 // CHECK: %[[SHIFTED_BASE_PTR:.*]] = llvm.getelementptr %[[BASE_PTR]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8> 880 // CHECK: %[[CAST_SHIFTED_BASE_PTR:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR]] : !llvm.ptr<i8> to !llvm.ptr<float> 881 // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 882 // CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 883 // CHECK: llvm.insertvalue %[[C0]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 884 // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 885 // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 886 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 887 // CHECK: llvm.insertvalue %[[ARG0]], %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 888 // CHECK: llvm.mul %{{.*}}, %[[ARG1]] 889 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 890 %1 = view %0[%arg2][%arg0, %arg1] : memref<2048xi8> to memref<?x?xf32> 891 892 // Test one dynamic size. 893 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 894 // CHECK: %[[BASE_PTR_2:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 895 // CHECK: %[[SHIFTED_BASE_PTR_2:.*]] = llvm.getelementptr %[[BASE_PTR_2]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8> 896 // CHECK: %[[CAST_SHIFTED_BASE_PTR_2:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_2]] : !llvm.ptr<i8> to !llvm.ptr<float> 897 // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_2]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 898 // CHECK: %[[C0_2:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 899 // CHECK: llvm.insertvalue %[[C0_2]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 900 // CHECK: llvm.insertvalue %[[ARG1]], %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 901 // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 902 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 903 // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 904 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 905 // CHECK: llvm.mul %{{.*}}, %[[ARG1]] 906 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 907 %3 = view %0[%arg2][%arg1] : memref<2048xi8> to memref<4x?xf32> 908 909 // Test static sizes. 910 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 911 // CHECK: %[[BASE_PTR_3:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8>, ptr<i8>, i64, array<1 x i64>, array<1 x i64>)> 912 // CHECK: %[[SHIFTED_BASE_PTR_3:.*]] = llvm.getelementptr %[[BASE_PTR_3]][%[[ARG2]]] : (!llvm.ptr<i8>, !llvm.i64) -> !llvm.ptr<i8> 913 // CHECK: %[[CAST_SHIFTED_BASE_PTR_3:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_3]] : !llvm.ptr<i8> to !llvm.ptr<float> 914 // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_3]], %{{.*}}[1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 915 // CHECK: %[[C0_3:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 916 // CHECK: llvm.insertvalue %[[C0_3]], %{{.*}}[2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 917 // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 918 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 919 // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 920 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 921 // CHECK: llvm.mlir.constant(64 : index) : !llvm.i64 922 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 923 // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 924 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 925 %5 = view %0[%arg2][] : memref<2048xi8> to memref<64x4xf32> 926 927 // Test view memory space. 928 // CHECK: llvm.mlir.constant(2048 : index) : !llvm.i64 929 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<i8, 4>, ptr<i8, 4>, i64, array<1 x i64>, array<1 x i64>)> 930 %6 = alloc() : memref<2048xi8, 4> 931 932 // CHECK: llvm.mlir.undef : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 933 // CHECK: %[[BASE_PTR_4:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr<i8, 4>, ptr<i8, 4>, i64, array<1 x i64>, array<1 x i64>)> 934 // CHECK: %[[SHIFTED_BASE_PTR_4:.*]] = llvm.getelementptr %[[BASE_PTR_4]][%[[ARG2]]] : (!llvm.ptr<i8, 4>, !llvm.i64) -> !llvm.ptr<i8, 4> 935 // CHECK: %[[CAST_SHIFTED_BASE_PTR_4:.*]] = llvm.bitcast %[[SHIFTED_BASE_PTR_4]] : !llvm.ptr<i8, 4> to !llvm.ptr<float, 4> 936 // CHECK: llvm.insertvalue %[[CAST_SHIFTED_BASE_PTR_4]], %{{.*}}[1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 937 // CHECK: %[[C0_4:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 938 // CHECK: llvm.insertvalue %[[C0_4]], %{{.*}}[2] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 939 // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 940 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 941 // CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 942 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 943 // CHECK: llvm.mlir.constant(64 : index) : !llvm.i64 944 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[3, 0] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 945 // CHECK: llvm.mlir.constant(4 : index) : !llvm.i64 946 // CHECK: llvm.insertvalue %{{.*}}, %{{.*}}[4, 0] : !llvm.struct<(ptr<float, 4>, ptr<float, 4>, i64, array<2 x i64>, array<2 x i64>)> 947 %7 = view %6[%arg2][] : memref<2048xi8, 4> to memref<64x4xf32, 4> 948 949 return 950} 951 952// CHECK-LABEL: func @subview( 953// CHECK-COUNT-2: !llvm.ptr<float>, 954// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64, 955// CHECK: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64, 956// CHECK: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64, 957// CHECK: %[[ARG2:.*]]: !llvm.i64) 958// CHECK32-LABEL: func @subview( 959// CHECK32-COUNT-2: !llvm.ptr<float>, 960// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32, 961// CHECK32: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32, 962// CHECK32: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32, 963// CHECK32: %[[ARG2:.*]]: !llvm.i32) 964func @subview(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) { 965 // The last "insertvalue" that populates the memref descriptor from the function arguments. 966 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 967 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 968 969 // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 970 // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 971 // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 972 // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 973 // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 974 // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 975 // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 976 // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 977 // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64 978 // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64 979 // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64 980 // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64 981 // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 982 // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 983 // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64 984 // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 985 // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 986 // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64 987 // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 988 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 989 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 990 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 991 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 992 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 993 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 994 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 995 // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 996 // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32 997 // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32 998 // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32 999 // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32 1000 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1001 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1002 // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32 1003 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1004 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1005 // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32 1006 1007 %1 = subview %0[%arg0, %arg1][%arg0, %arg1][%arg0, %arg1] : 1008 memref<64x4xf32, offset: 0, strides: [4, 1]> 1009 to memref<?x?xf32, offset: ?, strides: [?, ?]> 1010 return 1011} 1012 1013// CHECK-LABEL: func @subview_non_zero_addrspace( 1014// CHECK-COUNT-2: !llvm.ptr<float, 3>, 1015// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64, 1016// CHECK: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64, 1017// CHECK: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64, 1018// CHECK: %[[ARG2:.*]]: !llvm.i64) 1019// CHECK32-LABEL: func @subview_non_zero_addrspace( 1020// CHECK32-COUNT-2: !llvm.ptr<float, 3>, 1021// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32, 1022// CHECK32: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32, 1023// CHECK32: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32, 1024// CHECK32: %[[ARG2:.*]]: !llvm.i32) 1025func @subview_non_zero_addrspace(%0 : memref<64x4xf32, offset: 0, strides: [4, 1], 3>, %arg0 : index, %arg1 : index, %arg2 : index) { 1026 // The last "insertvalue" that populates the memref descriptor from the function arguments. 1027 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1028 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1029 1030 // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1031 // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3> 1032 // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1033 // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3> 1034 // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1035 // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1036 // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1037 // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1038 // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64 1039 // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64 1040 // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64 1041 // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64 1042 // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1043 // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1044 // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i64 1045 // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1046 // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1047 // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i64 1048 // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i64, array<2 x i64>, array<2 x i64>)> 1049 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1050 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3> 1051 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1052 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float, 3> to !llvm.ptr<float, 3> 1053 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1054 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1055 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1056 // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1057 // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32 1058 // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32 1059 // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32 1060 // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32 1061 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1062 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG1]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1063 // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE1]] : !llvm.i32 1064 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1065 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG0]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float, 3>, ptr<float, 3>, i32, array<2 x i32>, array<2 x i32>)> 1066 // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32 1067 1068 %1 = subview %0[%arg0, %arg1][%arg0, %arg1][%arg0, %arg1] : 1069 memref<64x4xf32, offset: 0, strides: [4, 1], 3> 1070 to memref<?x?xf32, offset: ?, strides: [?, ?], 3> 1071 return 1072} 1073 1074// CHECK-LABEL: func @subview_const_size( 1075// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1076// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1077// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 1078// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 1079// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 1080// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 1081// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 1082// CHECK-SAME: %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i64 1083// CHECK-SAME: %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i64 1084// CHECK-SAME: %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i64 1085// CHECK32-LABEL: func @subview_const_size( 1086// CHECK32-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1087// CHECK32-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1088// CHECK32-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i32 1089// CHECK32-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i32 1090// CHECK32-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i32 1091// CHECK32-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i32 1092// CHECK32-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i32 1093// CHECK32-SAME: %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i32 1094// CHECK32-SAME: %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i32 1095// CHECK32-SAME: %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i32 1096func @subview_const_size(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) { 1097 // The last "insertvalue" that populates the memref descriptor from the function arguments. 1098 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1099 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1100 1101 // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1102 // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1103 // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1104 // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1105 // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1106 // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1107 // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1108 // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1109 // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64 1110 // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64 1111 // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64 1112 // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64 1113 // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1114 // CHECK: %[[CST2:.*]] = llvm.mlir.constant(2 : i64) 1115 // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[CST2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1116 // CHECK: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64 1117 // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1118 // CHECK: %[[CST4:.*]] = llvm.mlir.constant(4 : i64) 1119 // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[CST4]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1120 // CHECK: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64 1121 // CHECK: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1122 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1123 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1124 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1125 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1126 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1127 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1128 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1129 // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1130 // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32 1131 // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32 1132 // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32 1133 // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32 1134 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1135 // CHECK32: %[[CST2:.*]] = llvm.mlir.constant(2 : i64) 1136 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[CST2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1137 // CHECK32: %[[DESCSTRIDE1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32 1138 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[DESCSTRIDE1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1139 // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64) 1140 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST4]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1141 // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32 1142 // CHECK32: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1143 %1 = subview %0[%arg0, %arg1][4, 2][%arg0, %arg1] : 1144 memref<64x4xf32, offset: 0, strides: [4, 1]> 1145 to memref<4x2xf32, offset: ?, strides: [?, ?]> 1146 return 1147} 1148 1149// CHECK-LABEL: func @subview_const_stride( 1150// CHECK-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1151// CHECK-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1152// CHECK-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i64 1153// CHECK-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i64 1154// CHECK-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i64 1155// CHECK-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i64 1156// CHECK-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i64 1157// CHECK-SAME: %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i64 1158// CHECK-SAME: %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i64 1159// CHECK-SAME: %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i64 1160// CHECK32-LABEL: func @subview_const_stride( 1161// CHECK32-SAME: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1162// CHECK32-SAME: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.ptr<float>, 1163// CHECK32-SAME: %[[ARG2:[a-zA-Z0-9]*]]: !llvm.i32 1164// CHECK32-SAME: %[[ARG3:[a-zA-Z0-9]*]]: !llvm.i32 1165// CHECK32-SAME: %[[ARG4:[a-zA-Z0-9]*]]: !llvm.i32 1166// CHECK32-SAME: %[[ARG5:[a-zA-Z0-9]*]]: !llvm.i32 1167// CHECK32-SAME: %[[ARG6:[a-zA-Z0-9]*]]: !llvm.i32 1168// CHECK32-SAME: %[[ARG7:[a-zA-Z0-9]*]]: !llvm.i32 1169// CHECK32-SAME: %[[ARG8:[a-zA-Z0-9]*]]: !llvm.i32 1170// CHECK32-SAME: %[[ARG9:[a-zA-Z0-9]*]]: !llvm.i32 1171func @subview_const_stride(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) { 1172 // The last "insertvalue" that populates the memref descriptor from the function arguments. 1173 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1174 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1175 1176 // CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1177 // CHECK: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1178 // CHECK: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1179 // CHECK: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1180 // CHECK: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1181 // CHECK: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1182 // CHECK: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1183 // CHECK: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1184 // CHECK: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i64 1185 // CHECK: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i64 1186 // CHECK: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i64 1187 // CHECK: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i64 1188 // CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1189 // CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[ARG8]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1190 // CHECK: %[[CST2:.*]] = llvm.mlir.constant(2 : i64) 1191 // CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[CST2]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1192 // CHECK: %[[DESC5:.*]] = llvm.insertvalue %[[ARG7]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1193 // CHECK: %[[CST4:.*]] = llvm.mlir.constant(4 : i64) 1194 // CHECK: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i64, array<2 x i64>, array<2 x i64>)> 1195 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1196 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1197 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1198 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1199 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1200 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1201 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1202 // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1203 // CHECK32: %[[OFFINC:.*]] = llvm.mul %[[ARG7]], %[[STRIDE0]] : !llvm.i32 1204 // CHECK32: %[[OFF1:.*]] = llvm.add %[[OFF]], %[[OFFINC]] : !llvm.i32 1205 // CHECK32: %[[OFFINC1:.*]] = llvm.mul %[[ARG8]], %[[STRIDE1]] : !llvm.i32 1206 // CHECK32: %[[OFF2:.*]] = llvm.add %[[OFF1]], %[[OFFINC1]] : !llvm.i32 1207 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFF2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1208 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG8]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1209 // CHECK32: %[[CST2:.*]] = llvm.mlir.constant(2 : i64) 1210 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST2]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1211 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[ARG7]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1212 // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64) 1213 // CHECK32: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1214 %1 = subview %0[%arg0, %arg1][%arg0, %arg1][1, 2] : 1215 memref<64x4xf32, offset: 0, strides: [4, 1]> 1216 to memref<?x?xf32, offset: ?, strides: [4, 2]> 1217 return 1218} 1219 1220// CHECK-LABEL: func @subview_const_stride_and_offset( 1221// CHECK32-LABEL: func @subview_const_stride_and_offset( 1222func @subview_const_stride_and_offset(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>) { 1223 // The last "insertvalue" that populates the memref descriptor from the function arguments. 1224 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1225 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1226 1227 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1228 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1229 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1230 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1231 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1232 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1233 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1234 // CHECK32: %[[CST8:.*]] = llvm.mlir.constant(8 : index) 1235 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[CST8]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1236 // CHECK32: %[[CST3:.*]] = llvm.mlir.constant(3 : i64) 1237 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[CST3]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1238 // CHECK32: %[[CST1:.*]] = llvm.mlir.constant(1 : i64) 1239 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1240 // CHECK32: %[[CST62:.*]] = llvm.mlir.constant(62 : i64) 1241 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST62]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1242 // CHECK32: %[[CST4:.*]] = llvm.mlir.constant(4 : i64) 1243 // CHECK32: llvm.insertvalue %[[CST4]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1244 %1 = subview %0[0, 8][62, 3][1, 1] : 1245 memref<64x4xf32, offset: 0, strides: [4, 1]> 1246 to memref<62x3xf32, offset: 8, strides: [4, 1]> 1247 return 1248} 1249 1250// CHECK-LABEL: func @subview_mixed_static_dynamic( 1251// CHECK-COUNT-2: !llvm.ptr<float>, 1252// CHECK-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i64, 1253// CHECK: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i64, 1254// CHECK: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i64, 1255// CHECK: %[[ARG2:.*]]: !llvm.i64) 1256// CHECK32-LABEL: func @subview_mixed_static_dynamic( 1257// CHECK32-COUNT-2: !llvm.ptr<float>, 1258// CHECK32-COUNT-5: {{%[a-zA-Z0-9]*}}: !llvm.i32, 1259// CHECK32: %[[ARG0:[a-zA-Z0-9]*]]: !llvm.i32, 1260// CHECK32: %[[ARG1:[a-zA-Z0-9]*]]: !llvm.i32, 1261// CHECK32: %[[ARG2:.*]]: !llvm.i32) 1262func @subview_mixed_static_dynamic(%0 : memref<64x4xf32, offset: 0, strides: [4, 1]>, %arg0 : index, %arg1 : index, %arg2 : index) { 1263 // The last "insertvalue" that populates the memref descriptor from the function arguments. 1264 // CHECK: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1265 // CHECK32: %[[MEMREF:.*]] = llvm.insertvalue %{{.*}}, %{{.*}}[4, 1] 1266 1267 // CHECK32: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1268 // CHECK32: %[[BITCAST0:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1269 // CHECK32: %[[DESC0:.*]] = llvm.insertvalue %[[BITCAST0]], %[[DESC]][0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1270 // CHECK32: %[[BITCAST1:.*]] = llvm.bitcast %{{.*}} : !llvm.ptr<float> to !llvm.ptr<float> 1271 // CHECK32: %[[DESC1:.*]] = llvm.insertvalue %[[BITCAST1]], %[[DESC0]][1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1272 // CHECK32: %[[STRIDE0:.*]] = llvm.extractvalue %[[MEMREF]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1273 // CHECK32: %[[STRIDE1:.*]] = llvm.extractvalue %[[MEMREF]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1274 // CHECK32: %[[OFF:.*]] = llvm.extractvalue %[[MEMREF]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1275 // CHECK32: %[[OFFM1:.*]] = llvm.mul %[[ARG1]], %[[STRIDE0]] : !llvm.i32 1276 // CHECK32: %[[OFFA1:.*]] = llvm.add %[[OFF]], %[[OFFM1]] : !llvm.i32 1277 // CHECK32: %[[CST8:.*]] = llvm.mlir.constant(8 : i64) : !llvm.i32 1278 // CHECK32: %[[OFFM2:.*]] = llvm.mul %[[CST8]], %[[STRIDE1]] : !llvm.i32 1279 // CHECK32: %[[OFFA2:.*]] = llvm.add %[[OFFA1]], %[[OFFM2]] : !llvm.i32 1280 // CHECK32: %[[DESC2:.*]] = llvm.insertvalue %[[OFFA2]], %[[DESC1]][2] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1281 1282 // CHECK32: %[[DESC3:.*]] = llvm.insertvalue %[[ARG2]], %[[DESC2]][3, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1283 // CHECK32: %[[CST1:.*]] = llvm.mlir.constant(1 : i64) : !llvm.i32 1284 // CHECK32: %[[DESC4:.*]] = llvm.insertvalue %[[CST1]], %[[DESC3]][4, 1] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1285 // CHECK32: %[[CST62:.*]] = llvm.mlir.constant(62 : i64) : !llvm.i32 1286 // CHECK32: %[[DESC5:.*]] = llvm.insertvalue %[[CST62]], %[[DESC4]][3, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1287 // CHECK32: %[[DESCSTRIDE0:.*]] = llvm.mul %[[ARG0]], %[[STRIDE0]] : !llvm.i32 1288 // CHECK32: llvm.insertvalue %[[DESCSTRIDE0]], %[[DESC5]][4, 0] : !llvm.struct<(ptr<float>, ptr<float>, i32, array<2 x i32>, array<2 x i32>)> 1289 %1 = subview %0[%arg1, 8][62, %arg2][%arg0, 1] : 1290 memref<64x4xf32, offset: 0, strides: [4, 1]> 1291 to memref<62x?xf32, offset: ?, strides: [?, 1]> 1292 return 1293} 1294 1295// ----- 1296 1297// CHECK-LABEL: func @atomic_rmw 1298func @atomic_rmw(%I : memref<10xi32>, %ival : i32, %F : memref<10xf32>, %fval : f32, %i : index) { 1299 atomic_rmw "assign" %fval, %F[%i] : (f32, memref<10xf32>) -> f32 1300 // CHECK: llvm.atomicrmw xchg %{{.*}}, %{{.*}} acq_rel 1301 atomic_rmw "addi" %ival, %I[%i] : (i32, memref<10xi32>) -> i32 1302 // CHECK: llvm.atomicrmw add %{{.*}}, %{{.*}} acq_rel 1303 atomic_rmw "maxs" %ival, %I[%i] : (i32, memref<10xi32>) -> i32 1304 // CHECK: llvm.atomicrmw max %{{.*}}, %{{.*}} acq_rel 1305 atomic_rmw "mins" %ival, %I[%i] : (i32, memref<10xi32>) -> i32 1306 // CHECK: llvm.atomicrmw min %{{.*}}, %{{.*}} acq_rel 1307 atomic_rmw "maxu" %ival, %I[%i] : (i32, memref<10xi32>) -> i32 1308 // CHECK: llvm.atomicrmw umax %{{.*}}, %{{.*}} acq_rel 1309 atomic_rmw "minu" %ival, %I[%i] : (i32, memref<10xi32>) -> i32 1310 // CHECK: llvm.atomicrmw umin %{{.*}}, %{{.*}} acq_rel 1311 atomic_rmw "addf" %fval, %F[%i] : (f32, memref<10xf32>) -> f32 1312 // CHECK: llvm.atomicrmw fadd %{{.*}}, %{{.*}} acq_rel 1313 return 1314} 1315 1316// ----- 1317 1318// CHECK-LABEL: func @generic_atomic_rmw 1319func @generic_atomic_rmw(%I : memref<10xi32>, %i : index) -> i32 { 1320 %x = generic_atomic_rmw %I[%i] : memref<10xi32> { 1321 ^bb0(%old_value : i32): 1322 %c1 = constant 1 : i32 1323 atomic_yield %c1 : i32 1324 } 1325 // CHECK: [[init:%.*]] = llvm.load %{{.*}} : !llvm.ptr<i32> 1326 // CHECK-NEXT: llvm.br ^bb1([[init]] : !llvm.i32) 1327 // CHECK-NEXT: ^bb1([[loaded:%.*]]: !llvm.i32): 1328 // CHECK-NEXT: [[c1:%.*]] = llvm.mlir.constant(1 : i32) 1329 // CHECK-NEXT: [[pair:%.*]] = llvm.cmpxchg %{{.*}}, [[loaded]], [[c1]] 1330 // CHECK-SAME: acq_rel monotonic : !llvm.i32 1331 // CHECK-NEXT: [[new:%.*]] = llvm.extractvalue [[pair]][0] 1332 // CHECK-NEXT: [[ok:%.*]] = llvm.extractvalue [[pair]][1] 1333 // CHECK-NEXT: llvm.cond_br [[ok]], ^bb2, ^bb1([[new]] : !llvm.i32) 1334 // CHECK-NEXT: ^bb2: 1335 %c2 = constant 2 : i32 1336 %add = addi %c2, %x : i32 1337 return %add : i32 1338 // CHECK-NEXT: [[c2:%.*]] = llvm.mlir.constant(2 : i32) 1339 // CHECK-NEXT: [[add:%.*]] = llvm.add [[c2]], [[new]] : !llvm.i32 1340 // CHECK-NEXT: llvm.return [[add]] 1341} 1342 1343// ----- 1344 1345// CHECK-LABEL: func @assume_alignment 1346func @assume_alignment(%0 : memref<4x4xf16>) { 1347 // CHECK: %[[PTR:.*]] = llvm.extractvalue %[[MEMREF:.*]][1] : !llvm.struct<(ptr<half>, ptr<half>, i64, array<2 x i64>, array<2 x i64>)> 1348 // CHECK-NEXT: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 1349 // CHECK-NEXT: %[[MASK:.*]] = llvm.mlir.constant(15 : index) : !llvm.i64 1350 // CHECK-NEXT: %[[INT:.*]] = llvm.ptrtoint %[[PTR]] : !llvm.ptr<half> to !llvm.i64 1351 // CHECK-NEXT: %[[MASKED_PTR:.*]] = llvm.and %[[INT]], %[[MASK:.*]] : !llvm.i64 1352 // CHECK-NEXT: %[[CONDITION:.*]] = llvm.icmp "eq" %[[MASKED_PTR]], %[[ZERO]] : !llvm.i64 1353 // CHECK-NEXT: "llvm.intr.assume"(%[[CONDITION]]) : (!llvm.i1) -> () 1354 assume_alignment %0, 16 : memref<4x4xf16> 1355 return 1356} 1357 1358// ----- 1359 1360// CHECK-LABEL: func @mlir_cast_to_llvm 1361// CHECK-SAME: %[[ARG:.*]]: 1362func @mlir_cast_to_llvm(%0 : vector<2xf16>) -> !llvm.vec<2 x half> { 1363 %1 = llvm.mlir.cast %0 : vector<2xf16> to !llvm.vec<2 x half> 1364 // CHECK-NEXT: llvm.return %[[ARG]] 1365 return %1 : !llvm.vec<2 x half> 1366} 1367 1368// CHECK-LABEL: func @mlir_cast_from_llvm 1369// CHECK-SAME: %[[ARG:.*]]: 1370func @mlir_cast_from_llvm(%0 : !llvm.vec<2 x half>) -> vector<2xf16> { 1371 %1 = llvm.mlir.cast %0 : !llvm.vec<2 x half> to vector<2xf16> 1372 // CHECK-NEXT: llvm.return %[[ARG]] 1373 return %1 : vector<2xf16> 1374} 1375 1376// ----- 1377 1378// CHECK-LABEL: func @mlir_cast_to_llvm 1379// CHECK-SAME: %[[ARG:.*]]: 1380func @mlir_cast_to_llvm(%0 : f16) -> !llvm.half { 1381 %1 = llvm.mlir.cast %0 : f16 to !llvm.half 1382 // CHECK-NEXT: llvm.return %[[ARG]] 1383 return %1 : !llvm.half 1384} 1385 1386// CHECK-LABEL: func @mlir_cast_from_llvm 1387// CHECK-SAME: %[[ARG:.*]]: 1388func @mlir_cast_from_llvm(%0 : !llvm.half) -> f16 { 1389 %1 = llvm.mlir.cast %0 : !llvm.half to f16 1390 // CHECK-NEXT: llvm.return %[[ARG]] 1391 return %1 : f16 1392} 1393 1394// ----- 1395 1396// CHECK-LABEL: func @bfloat 1397// CHECK-SAME: !llvm.bfloat) -> !llvm.bfloat 1398func @bfloat(%arg0: bf16) -> bf16 { 1399 return %arg0 : bf16 1400} 1401// CHECK-NEXT: return %{{.*}} : !llvm.bfloat 1402 1403// ----- 1404 1405// CHECK-LABEL: func @memref_index 1406// CHECK-SAME: %arg0: !llvm.ptr<i64>, %arg1: !llvm.ptr<i64>, 1407// CHECK-SAME: %arg2: !llvm.i64, %arg3: !llvm.i64, %arg4: !llvm.i64) 1408// CHECK-SAME: -> !llvm.struct<(ptr<i64>, ptr<i64>, i64, array<1 x i64>, array<1 x i64>)> 1409// CHECK32-LABEL: func @memref_index 1410// CHECK32-SAME: %arg0: !llvm.ptr<i32>, %arg1: !llvm.ptr<i32>, 1411// CHECK32-SAME: %arg2: !llvm.i32, %arg3: !llvm.i32, %arg4: !llvm.i32) 1412// CHECK32-SAME: -> !llvm.struct<(ptr<i32>, ptr<i32>, i32, array<1 x i32>, array<1 x i32>)> 1413func @memref_index(%arg0: memref<32xindex>) -> memref<32xindex> { 1414 return %arg0 : memref<32xindex> 1415} 1416 1417// ----- 1418 1419// CHECK-LABEL: func @rank_of_unranked 1420// CHECK32-LABEL: func @rank_of_unranked 1421func @rank_of_unranked(%unranked: memref<*xi32>) { 1422 %rank = rank %unranked : memref<*xi32> 1423 return 1424} 1425// CHECK-NEXT: llvm.mlir.undef 1426// CHECK-NEXT: llvm.insertvalue 1427// CHECK-NEXT: llvm.insertvalue 1428// CHECK-NEXT: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i64, ptr<i8>)> 1429// CHECK32: llvm.extractvalue %{{.*}}[0] : !llvm.struct<(i32, ptr<i8>)> 1430 1431// CHECK-LABEL: func @rank_of_ranked 1432// CHECK32-LABEL: func @rank_of_ranked 1433func @rank_of_ranked(%ranked: memref<?xi32>) { 1434 %rank = rank %ranked : memref<?xi32> 1435 return 1436} 1437// CHECK: llvm.mlir.constant(1 : index) : !llvm.i64 1438// CHECK32: llvm.mlir.constant(1 : index) : !llvm.i32 1439 1440// ----- 1441 1442// CHECK-LABEL: func @dim_of_unranked 1443// CHECK32-LABEL: func @dim_of_unranked 1444func @dim_of_unranked(%unranked: memref<*xi32>) -> index { 1445 %c0 = constant 0 : index 1446 %dim = dim %unranked, %c0 : memref<*xi32> 1447 return %dim : index 1448} 1449// CHECK-NEXT: llvm.mlir.undef : !llvm.struct<(i64, ptr<i8>)> 1450// CHECK-NEXT: llvm.insertvalue 1451// CHECK-NEXT: %[[UNRANKED_DESC:.*]] = llvm.insertvalue 1452// CHECK-NEXT: %[[C0:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 1453 1454// CHECK-NEXT: %[[RANKED_DESC:.*]] = llvm.extractvalue %[[UNRANKED_DESC]][1] 1455// CHECK-SAME: : !llvm.struct<(i64, ptr<i8>)> 1456 1457// CHECK-NEXT: %[[ZERO_D_DESC:.*]] = llvm.bitcast %[[RANKED_DESC]] 1458// CHECK-SAME: : !llvm.ptr<i8> to !llvm.ptr<struct<(ptr<i32>, ptr<i32>, i64)>> 1459 1460// CHECK-NEXT: %[[C2_i32:.*]] = llvm.mlir.constant(2 : i32) : !llvm.i32 1461// CHECK-NEXT: %[[C0_:.*]] = llvm.mlir.constant(0 : index) : !llvm.i64 1462 1463// CHECK-NEXT: %[[OFFSET_PTR:.*]] = llvm.getelementptr %[[ZERO_D_DESC]]{{\[}} 1464// CHECK-SAME: %[[C0_]], %[[C2_i32]]] : (!llvm.ptr<struct<(ptr<i32>, ptr<i32>, 1465// CHECK-SAME: i64)>>, !llvm.i64, !llvm.i32) -> !llvm.ptr<i64> 1466 1467// CHECK-NEXT: %[[C1:.*]] = llvm.mlir.constant(1 : index) : !llvm.i64 1468// CHECK-NEXT: %[[INDEX_INC:.*]] = llvm.add %[[C1]], %[[C0]] : !llvm.i64 1469 1470// CHECK-NEXT: %[[SIZE_PTR:.*]] = llvm.getelementptr %[[OFFSET_PTR]]{{\[}} 1471// CHECK-SAME: %[[INDEX_INC]]] : (!llvm.ptr<i64>, !llvm.i64) -> !llvm.ptr<i64> 1472 1473// CHECK-NEXT: %[[SIZE:.*]] = llvm.load %[[SIZE_PTR]] : !llvm.ptr<i64> 1474// CHECK-NEXT: llvm.return %[[SIZE]] : !llvm.i64 1475 1476// CHECK32: %[[SIZE:.*]] = llvm.load %{{.*}} : !llvm.ptr<i32> 1477// CHECK32-NEXT: llvm.return %[[SIZE]] : !llvm.i32 1478