| // RUN: mlir-opt --convert-nvvm-to-llvm --convert-arith-to-llvm --split-input-file %s | FileCheck %s |
| |
| // Same below, but using the `ConvertToLLVMPatternInterface` entry point |
| // and the generic `convert-to-llvm` pass. |
| // RUN: mlir-opt --convert-to-llvm --split-input-file %s | FileCheck %s |
| // RUN: mlir-opt --convert-to-llvm="allow-pattern-rollback=0" --split-input-file %s | FileCheck %s |
| |
| // CHECK-LABEL: @init_mbarrier |
| llvm.func @init_mbarrier(%barrier_gen : !llvm.ptr, %barrier : !llvm.ptr<3>, %count : i32, %pred : i1) { |
| //CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$2 mbarrier.init.shared.b64 [$0], $1;", "r,r,b" |
| nvvm.mbarrier.init %barrier, %count, predicate = %pred : !llvm.ptr<3>, i32, i1 |
| //CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$2 mbarrier.init.b64 [$0], $1;", "l,r,b" |
| nvvm.mbarrier.init %barrier_gen, %count, predicate = %pred : !llvm.ptr, i32, i1 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @init_mbarrier_arrive_expect_tx |
| llvm.func @init_mbarrier_arrive_expect_tx(%barrier : !llvm.ptr<3>, %txcount : i32, %pred : i1) { |
| //CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$2 mbarrier.arrive.expect_tx.shared.b64 _, [$0], $1;", "r,r,b" |
| nvvm.mbarrier.arrive.expect_tx %barrier, %txcount, predicate = %pred : !llvm.ptr<3>, i32, i1 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @init_mbarrier_arrive_expect_tx_generic |
| llvm.func @init_mbarrier_arrive_expect_tx_generic(%barrier : !llvm.ptr, %txcount : i32, %pred : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$2 mbarrier.arrive.expect_tx.b64 _, [$0], $1;", "l,r,b" |
| nvvm.mbarrier.arrive.expect_tx %barrier, %txcount, predicate = %pred : !llvm.ptr, i32, i1 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @init_mbarrier_try_wait_shared |
| llvm.func @init_mbarrier_try_wait_shared(%barrier : !llvm.ptr<3>, %ticks : i32, %phase : i32) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred P1; |
| // CHECK-SAME: LAB_WAIT: |
| // CHECK-SAME: mbarrier.try_wait.parity.shared.b64 P1, [$0], $1, $2; |
| // CHECK-SAME: @P1 bra.uni DONE; |
| // CHECK-SAME: bra.uni LAB_WAIT; |
| // CHECK-SAME: DONE: |
| // CHECK-SAME: }", |
| // CHECK-SAME: "r,r,r" |
| nvvm.mbarrier.try_wait.parity %barrier, %phase, %ticks : !llvm.ptr<3>, i32, i32 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @init_mbarrier_try_wait |
| llvm.func @init_mbarrier_try_wait(%barrier : !llvm.ptr, %ticks : i32, %phase : i32){ |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred P1; |
| // CHECK-SAME: LAB_WAIT: |
| // CHECK-SAME: mbarrier.try_wait.parity.b64 P1, [$0], $1, $2; |
| // CHECK-SAME: @P1 bra.uni DONE; |
| // CHECK-SAME: bra.uni LAB_WAIT; |
| // CHECK-SAME: DONE: |
| // CHECK-SAME: }", |
| // CHECK-SAME: "l,r,r" |
| nvvm.mbarrier.try_wait.parity %barrier, %phase, %ticks : !llvm.ptr, i32, i32 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @async_cp |
| func.func @async_cp(%dst: !llvm.ptr<3>, %src: !llvm.ptr<1>) { |
| // CHECK: nvvm.cp.async.shared.global %{{.*}}, %{{.*}}, 16, cache = ca : !llvm.ptr<3>, !llvm.ptr<1> |
| nvvm.cp.async.shared.global %dst, %src, 16, cache = ca : !llvm.ptr<3>, !llvm.ptr<1> |
| // CHECK: nvvm.cp.async.shared.global %{{.*}}, %{{.*}}, 16, cache = cg : !llvm.ptr<3>, !llvm.ptr<1> |
| nvvm.cp.async.shared.global %dst, %src, 16, cache = cg : !llvm.ptr<3>, !llvm.ptr<1> |
| return |
| } |
| |
| // CHECK-LABEL: @async_cp_zfill |
| func.func @async_cp_zfill(%dst: !llvm.ptr<3>, %src: !llvm.ptr<1>, %cpSize: i32) { |
| // CHECK: nvvm.cp.async.shared.global %{{.*}}, %{{.*}}, 16, cache = cg, %{{.*}} : !llvm.ptr<3>, !llvm.ptr<1>, i32 |
| nvvm.cp.async.shared.global %dst, %src, 16, cache = cg, %cpSize : !llvm.ptr<3>, !llvm.ptr<1>, i32 |
| // CHECK: nvvm.cp.async.shared.global %{{.*}}, %{{.*}}, 4, cache = ca, %{{.*}} : !llvm.ptr<3>, !llvm.ptr<1>, i32 |
| nvvm.cp.async.shared.global %dst, %src, 4, cache = ca, %cpSize : !llvm.ptr<3>, !llvm.ptr<1>, i32 |
| return |
| } |
| |
| // CHECK-LABEL: @cp_async_mbarrier_arrive |
| func.func @cp_async_mbarrier_arrive(%bar_shared: !llvm.ptr<3>, %bar_gen: !llvm.ptr) { |
| // CHECK: nvvm.cp.async.mbarrier.arrive %{{.*}} |
| nvvm.cp.async.mbarrier.arrive %bar_gen : !llvm.ptr |
| // CHECK: nvvm.cp.async.mbarrier.arrive %{{.*}} {noinc = true} |
| nvvm.cp.async.mbarrier.arrive %bar_gen {noinc = true} : !llvm.ptr |
| // CHECK: nvvm.cp.async.mbarrier.arrive %{{.*}} |
| nvvm.cp.async.mbarrier.arrive %bar_shared : !llvm.ptr<3> |
| // CHECK: nvvm.cp.async.mbarrier.arrive %{{.*}} {noinc = true} |
| nvvm.cp.async.mbarrier.arrive %bar_shared {noinc = true} : !llvm.ptr<3> |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @tma_load_3d_all |
| func.func @tma_load_3d_all(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %off0: i16, %off1: i16, %ctamask : i16, %cacheHint : i64, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$9 cp.async.bulk.tensor.3d.shared::cluster.global.mbarrier::complete_tx::bytes.im2col.multicast::cluster.L2::cache_hint [$0], [$1, {$2,$3,$4} ], [$5],{$6}, $7, $8;", "l,l,r,r,r,r,h,h,l,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2] im2col[%off0] multicast_mask = %ctamask l2_cache_hint = %cacheHint predicate = %p {mode = #nvvm.tma_load_mode<im2col>} : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_4d_all |
| func.func @tma_load_4d_all(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %off0: i16, %off1: i16, %ctamask : i16, %cacheHint : i64, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$11 cp.async.bulk.tensor.4d.shared::cluster.global.mbarrier::complete_tx::bytes.im2col.multicast::cluster.L2::cache_hint [$0], [$1, {$2,$3,$4,$5} ], [$6],{$7,$8}, $9, $10;", "l,l,r,r,r,r,r,h,h,h,l,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2,%crd3] im2col[%off0,%off1] multicast_mask = %ctamask l2_cache_hint = %cacheHint predicate = %p {mode = #nvvm.tma_load_mode<im2col>} : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_5d_all |
| func.func @tma_load_5d_all(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %crd4: i32, %off0: i16, %off1: i16, %off2: i16, %ctamask : i16, %cacheHint : i64, %p : i1) { |
| // CHECK: lvm.inline_asm has_side_effects asm_dialect = att "@$13 cp.async.bulk.tensor.5d.shared::cluster.global.mbarrier::complete_tx::bytes.im2col.multicast::cluster.L2::cache_hint [$0], [$1, {$2,$3,$4,$5,$6} ], [$7],{$8,$9,$10}, $11, $12;", "l,l,r,r,r,r,r,r,h,h,h,h,l,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2,%crd3,%crd4] im2col[%off0,%off1,%off2] multicast_mask = %ctamask l2_cache_hint = %cacheHint predicate = %p {mode = #nvvm.tma_load_mode<im2col>} : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_1d |
| func.func @tma_load_1d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$4 cp.async.bulk.tensor.1d.shared::cluster.global.mbarrier::complete_tx::bytes [$0], [$1, {$2} ], [$3];", "l,l,r,r,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0] predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_2d |
| func.func @tma_load_2d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$5 cp.async.bulk.tensor.2d.shared::cluster.global.mbarrier::complete_tx::bytes [$0], [$1, {$2,$3} ], [$4];", "l,l,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1] predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_3d |
| func.func @tma_load_3d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$6 cp.async.bulk.tensor.3d.shared::cluster.global.mbarrier::complete_tx::bytes [$0], [$1, {$2,$3,$4} ], [$5];", "l,l,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2] predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_4d |
| func.func @tma_load_4d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$7 cp.async.bulk.tensor.4d.shared::cluster.global.mbarrier::complete_tx::bytes [$0], [$1, {$2,$3,$4,$5} ], [$6];", "l,l,r,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2,%crd3] predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_5d |
| func.func @tma_load_5d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %crd4: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$8 cp.async.bulk.tensor.5d.shared::cluster.global.mbarrier::complete_tx::bytes [$0], [$1, {$2,$3,$4,$5,$6} ], [$7];", "l,l,r,r,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box[%crd0,%crd1,%crd2,%crd3,%crd4] predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_multicast1d |
| func.func @tma_load_multicast1d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %multicastMask : i16, %crd0: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$5 cp.async.bulk.tensor.1d.shared::cluster.global.mbarrier::complete_tx::bytes.multicast::cluster [$0], [$1, {$2} ], [$3], $4;", "l,l,r,r,h,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box [%crd0] multicast_mask = %multicastMask predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_multicast2d |
| func.func @tma_load_multicast2d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %multicastMask : i16, %crd0: i32, %crd1: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$6 cp.async.bulk.tensor.2d.shared::cluster.global.mbarrier::complete_tx::bytes.multicast::cluster [$0], [$1, {$2,$3} ], [$4], $5;", "l,l,r,r,r,h,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box [%crd0,%crd1] multicast_mask = %multicastMask predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_multicast3d |
| func.func @tma_load_multicast3d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %multicastMask : i16, %crd0: i32, %crd1: i32, %crd2: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$7 cp.async.bulk.tensor.3d.shared::cluster.global.mbarrier::complete_tx::bytes.multicast::cluster [$0], [$1, {$2,$3,$4} ], [$5], $6;", "l,l,r,r,r,r,h,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box [%crd0,%crd1,%crd2] multicast_mask = %multicastMask predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_multicast4d |
| func.func @tma_load_multicast4d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %multicastMask : i16, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$8 cp.async.bulk.tensor.4d.shared::cluster.global.mbarrier::complete_tx::bytes.multicast::cluster [$0], [$1, {$2,$3,$4,$5} ], [$6], $7;", "l,l,r,r,r,r,r,h,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box [%crd0,%crd1,%crd2,%crd3] multicast_mask = %multicastMask predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_load_multicast5d |
| func.func @tma_load_multicast5d(%tmaDescriptor: !llvm.ptr, %dest : !llvm.ptr<7>, %barrier: !llvm.ptr<3>, %multicastMask : i16, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %crd4: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$9 cp.async.bulk.tensor.5d.shared::cluster.global.mbarrier::complete_tx::bytes.multicast::cluster [$0], [$1, {$2,$3,$4,$5,$6} ], [$7], $8;", "l,l,r,r,r,r,r,r,h,b" |
| nvvm.cp.async.bulk.tensor.shared.cluster.global %dest, %tmaDescriptor, %barrier, box [%crd0,%crd1,%crd2,%crd3,%crd4] multicast_mask = %multicastMask predicate=%p : !llvm.ptr<7>, !llvm.ptr |
| return |
| } |
| |
| // CHECK-LABEL: @tma_store_1d |
| func.func @tma_store_1d(%tmaDescriptor: !llvm.ptr, %src : !llvm.ptr<3>, %crd0: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$3 cp.async.bulk.tensor.1d.global.shared::cta.bulk_group [$0, {$2} ], [$1];", "l,r,r,b" |
| nvvm.cp.async.bulk.tensor.global.shared.cta %tmaDescriptor, %src, box[%crd0], predicate=%p : !llvm.ptr, !llvm.ptr<3> |
| return |
| } |
| |
| // CHECK-LABEL: @tma_store_2d |
| func.func @tma_store_2d(%tmaDescriptor: !llvm.ptr, %src : !llvm.ptr<3>, %crd0: i32, %crd1: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$4 cp.async.bulk.tensor.2d.global.shared::cta.bulk_group [$0, {$2, $3} ], [$1];", "l,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.global.shared.cta %tmaDescriptor, %src, box[%crd0,%crd1], predicate=%p : !llvm.ptr, !llvm.ptr<3> |
| return |
| } |
| |
| // CHECK-LABEL: @tma_store_3d |
| func.func @tma_store_3d(%tmaDescriptor: !llvm.ptr, %src : !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$5 cp.async.bulk.tensor.3d.global.shared::cta.bulk_group [$0, {$2, $3, $4} ], [$1];", "l,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.global.shared.cta %tmaDescriptor, %src, box[%crd0,%crd1,%crd2], predicate=%p : !llvm.ptr, !llvm.ptr<3> |
| return |
| } |
| |
| // CHECK-LABEL: @tma_store_4d |
| func.func @tma_store_4d(%tmaDescriptor: !llvm.ptr, %src : !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %p : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$6 cp.async.bulk.tensor.4d.global.shared::cta.bulk_group [$0, {$2, $3, $4, $5} ], [$1];", "l,r,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.global.shared.cta %tmaDescriptor, %src, box[%crd0,%crd1,%crd2,%crd3], predicate=%p : !llvm.ptr, !llvm.ptr<3> |
| return |
| } |
| |
| // CHECK-LABEL: @tma_store_5d |
| func.func @tma_store_5d(%tmaDescriptor: !llvm.ptr, %src : !llvm.ptr<3>, %crd0: i32, %crd1: i32, %crd2: i32, %crd3: i32, %crd4: i32, %p : i1) { |
| // CHECK-NEXT: llvm.inline_asm has_side_effects asm_dialect = att "@$7 cp.async.bulk.tensor.5d.global.shared::cta.bulk_group [$0, {$2, $3, $4, $5, $6} ], [$1];", "l,r,r,r,r,r,r,b" |
| nvvm.cp.async.bulk.tensor.global.shared.cta %tmaDescriptor, %src, box[%crd0,%crd1,%crd2,%crd3,%crd4], predicate=%p : !llvm.ptr, !llvm.ptr<3> |
| return |
| } |
| |
| // CHECK-LABEL: @wgmma_execute |
| func.func @wgmma_execute() { |
| nvvm.wgmma.fence.aligned |
| nvvm.wgmma.commit.group.sync.aligned |
| nvvm.wgmma.wait.group.sync.aligned 0 |
| // CHECK: nvvm.wgmma.fence.aligned |
| // CHECK: nvvm.wgmma.commit.group.sync.aligned |
| // CHECK: nvvm.wgmma.wait.group.sync.aligned 0 |
| |
| |
| nvvm.wgmma.fence.aligned |
| nvvm.wgmma.commit.group.sync.aligned |
| nvvm.wgmma.wait.group.sync.aligned 5 |
| // CHECK: nvvm.wgmma.fence.aligned |
| // CHECK: nvvm.wgmma.commit.group.sync.aligned |
| // CHECK: nvvm.wgmma.wait.group.sync.aligned 5 |
| return |
| } |
| |
| |
| // ----- |
| |
| !mat64f32 = !llvm.struct<( |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32)> |
| |
| // CHECK-LABEL: @wgmma_f32_f16_f16( |
| // CHECK-SAME: %[[ARG0:.+]]: i64, %[[ARG1:.+]]: i64 |
| func.func @wgmma_f32_f16_f16(%descA : i64, %descB : i64) -> !mat64f32{ |
| // CHECK: %[[RES:.*]] = llvm.mlir.undef : !llvm.struct |
| // CHECK: %[[A1:.*]] = llvm.mlir.constant(0 : i32) : i32 |
| // CHECK: %[[A2:.*]] = llvm.mlir.constant(-1 : i32) : i32 |
| // CHECK: %[[A3:.*]] = llvm.mlir.constant(-1 : i32) : i32 |
| // CHECK: %[[A4:.*]] = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %[[A5:.*]] = llvm.mlir.constant(0 : i32) : i32 |
| // CHECK: %[[V0:.*]] = llvm.extractvalue %[[RES]][0] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V4:.*]] = llvm.extractvalue %[[RES]][4] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V11:.*]] = llvm.extractvalue %[[RES]][11] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V13:.*]] = llvm.extractvalue %[[RES]][13] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[RES1:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $34, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n32k16.f32.f16.f16 |
| // CHECK-SAME: {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15}, $32, $33, p, $35, $36, $37, $38;\0A}\0A", |
| // CHECK-SAME: "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,l,l,n,n,n,n,n" |
| // CHECK-SAME: %[[V0]], %{{.*}}, %{{.*}}, %{{.*}}, %[[V4]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[V11]], %{{.*}}, %[[V13]], %{{.*}}, %{{.*}}, %[[ARG0]], %[[ARG1]], %[[A1]], %[[A2]], %[[A3]], %[[A4]], %[[A5]] |
| // CHECK-SAME: : (f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, i64, i64, i32, i32, i32, i32, i32) |
| // CHECK-SAME: -> !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : i64) : i64 |
| // CHECK: %[[DESCa:.+]] = llvm.add %[[ARG0]], %[[C2]] : i64 |
| // CHECK: %[[DESCb:.+]] = llvm.add %[[ARG1]], %[[C2]] : i64 |
| // CHECK: %[[V0_2:.*]] = llvm.extractvalue %[[RES1]][0] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V4_2:.*]] = llvm.extractvalue %[[RES1]][4] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V11_2:.*]] = llvm.extractvalue %[[RES1]][11] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[V13_2:.*]] = llvm.extractvalue %[[RES1]][13] : !llvm.struct<(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32)> |
| // CHECK: %[[RES_2:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $34, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n32k16.f32.f16.f16 |
| // CHECK-SAME: {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15}, $32, $33, p, $35, $36, $37, $38;\0A}\0A", |
| // CHECK-SAME: "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,l,l,n,n,n,n,n" |
| // CHECK-SAME: %[[V0_2]], %{{.*}}, %{{.*}}, %{{.*}}, %[[V4_2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[V11_2]], %{{.*}}, %[[V13_2]], %{{.*}}, %{{.*}}, %[[DESCa]], %[[DESCb]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} |
| %result = llvm.mlir.undef : !mat64f32 |
| %result1 = nvvm.wgmma.mma_async |
| %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 32, k = 16>, |
| D [<f32>, #nvvm.wgmma_scale_out<zero>], |
| A [<f16>, #nvvm.wgmma_scale_in<neg>, <col>], |
| B [<f16>, #nvvm.wgmma_scale_in<neg>, <col>] |
| :!mat64f32 -> !mat64f32 |
| %c2 = arith.constant 2 : i64 |
| %descAnext = arith.addi %descA, %c2 : i64 |
| %descBnext = arith.addi %descB, %c2 : i64 |
| %result2 = nvvm.wgmma.mma_async |
| %descAnext, %descBnext, %result1, |
| #nvvm.shape<m = 64, n = 32, k = 16>, |
| D [<f32>, #nvvm.wgmma_scale_out<zero>], |
| A [<f16>, #nvvm.wgmma_scale_in<neg>, <col>], |
| B [<f16>, #nvvm.wgmma_scale_in<neg>, <col>] |
| : !mat64f32 -> !mat64f32 |
| return %result2 : !mat64f32 |
| } |
| |
| // ----- |
| |
| !mat16i32 = !llvm.struct<(i32, i32, i32, i32)> |
| |
| // CHECK-LABEL: @wgmma_s32_s8_s8_satfinite( |
| // CHECK-SAME: %[[ARG0:.+]]: i64, %[[ARG1:.+]]: i64 |
| func.func @wgmma_s32_s8_s8_satfinite(%descA : i64, %descB : i64) -> !mat16i32{ |
| %result = llvm.mlir.undef : !mat16i32 |
| // CHECK: %[[RES:.*]] = llvm.mlir.undef : !llvm.struct |
| // CHECK: %[[A1:.*]] = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %[[V0:.*]] = llvm.extractvalue %[[RES]][0] |
| // CHECK: %[[V1:.*]] = llvm.extractvalue %[[RES]][1] |
| // CHECK: %[[V2:.*]] = llvm.extractvalue %[[RES]][2] |
| // CHECK: %[[V3:.*]] = llvm.extractvalue %[[RES]][3] |
| // CHECK: %[[RES_2:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.s8.s8.satfinite |
| // CHECK-SAME: {$0, $1, $2, $3}, $8, $9, p;\0A}\0A", "=r,=r,=r,=r,0,1,2,3,l,l,n" |
| // CHECK-SAME: %[[V0]], %[[V1]], %[[V2]], %[[V3]], %[[ARG0]], %[[ARG1]], %[[A1]] : |
| // CHECK-SAME: (i32, i32, i32, i32, i64, i64, i32) -> !llvm.struct<(i32, i32, i32, i32)> |
| // CHECK: %[[V0_2:.*]] = llvm.extractvalue %[[RES_2]][0] |
| // CHECK: %[[V1_2:.*]] = llvm.extractvalue %[[RES_2]][1] |
| // CHECK: %[[V2_2:.*]] = llvm.extractvalue %[[RES_2]][2] |
| // CHECK: %[[V3_2:.*]] = llvm.extractvalue %[[RES_2]][3] |
| // CHECK: %[[RES_3:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.s8.s8.satfinite |
| // CHECK-SAME: {$0, $1, $2, $3}, $8, $9, p;\0A}\0A", |
| // CHECK-SAME: "=r,=r,=r,=r,0,1,2,3,l,l,n" |
| // CHECK-SAME: %[[V0_2]], %[[V1_2]], %[[V2_2]], %[[V3_2]], %[[ARG0]], %[[ARG1]], %{{.*}} |
| // CHECK: %[[V0_3:.*]] = llvm.extractvalue %[[RES_3]][0] |
| // CHECK: %[[V1_3:.*]] = llvm.extractvalue %[[RES_3]][1] |
| // CHECK: %[[V2_3:.*]] = llvm.extractvalue %[[RES_3]][2] |
| // CHECK: %[[V3_3:.*]] = llvm.extractvalue %[[RES_3]][3] |
| // CHECK: %[[RES1:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME:"{ |
| // CHECK-SAME:.reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.s8.s8.satfinite |
| // CHECK-SAME: {$0, $1, $2, $3}, $8, $9, p;\0A}\0A", "=r,=r,=r,=r,0,1,2,3,l,l,n" |
| // CHECK-SAME: %[[V0_3]], %[[V1_3]], %[[V2_3]], %[[V3_3]], %[[ARG0]], %[[ARG1]], %{{.*}} |
| %result1 = nvvm.wgmma.mma_async %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>, <satfinite>], |
| A [<s8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<s8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| %result2 = nvvm.wgmma.mma_async %descA, %descB, %result1, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>, <satfinite>], |
| A [<s8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<s8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| %result3 = nvvm.wgmma.mma_async %descA, %descB, %result2, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>, <satfinite>], |
| A [<s8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<s8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| return %result3 : !mat16i32 |
| } |
| |
| // CHECK-LABEL: @wgmma_s32_u8_u8( |
| // CHECK-SAME: %[[ARG0:.+]]: i64, %[[ARG1:.+]]: i64 |
| func.func @wgmma_s32_u8_u8(%descA : i64, %descB : i64) -> !mat16i32 { |
| // CHECK: %[[RES:.*]] = llvm.mlir.undef : !llvm.struct |
| // CHECK: %[[A1:.*]] = llvm.mlir.constant(1 : i32) : i32 |
| // CHECK: %[[V0:.*]] = llvm.extractvalue %[[RES]][0] |
| // CHECK: %[[V1:.*]] = llvm.extractvalue %[[RES]][1] |
| // CHECK: %[[V2:.*]] = llvm.extractvalue %[[RES]][2] |
| // CHECK: %[[V3:.*]] = llvm.extractvalue %[[RES]][3] |
| // CHECK: %[[RES_2:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.u8.u8 {$0, $1, $2, $3}, $8, $9, p; |
| // CHECK-SAME: }\0A", |
| // CHECK-SAME: "=r,=r,=r,=r,0,1,2,3,l,l,n" %[[V0]], %[[V1]], %[[V2]], %[[V3]], %[[ARG0]], %[[ARG1]], %[[A1]] : |
| // CHECK-SAME:(i32, i32, i32, i32, i64, i64, i32) -> !llvm.struct<(i32, i32, i32, i32)> |
| // CHECK: %[[V0_2:.*]] = llvm.extractvalue %[[RES_2]][0] |
| // CHECK: %[[V1_2:.*]] = llvm.extractvalue %[[RES_2]][1] |
| // CHECK: %[[V2_2:.*]] = llvm.extractvalue %[[RES_2]][2] |
| // CHECK: %[[V3_2:.*]] = llvm.extractvalue %[[RES_2]][3] |
| // CHECK: %[[RES_3:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME:"{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.u8.u8 {$0, $1, $2, $3}, $8, $9, p; |
| // CHECK-SAME: }\0A", |
| // CHECK-SAME: "=r,=r,=r,=r,0,1,2,3,l,l,n" %[[V0_2]], %[[V1_2]], %[[V2_2]], %[[V3_2]], %[[ARG0]], %[[ARG1]], %{{.*}} |
| // CHECK: %[[V0_3:.*]] = llvm.extractvalue %[[RES_3]][0] |
| // CHECK: %[[V1_3:.*]] = llvm.extractvalue %[[RES_3]][1] |
| // CHECK: %[[V2_3:.*]] = llvm.extractvalue %[[RES_3]][2] |
| // CHECK: %[[V3_3:.*]] = llvm.extractvalue %[[RES_3]][3] |
| // CHECK: %[[RES1:.*]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME:"{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $10, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n8k32.s32.u8.u8 {$0, $1, $2, $3}, $8, $9, p; |
| // CHECK-SAME:}\0A", |
| // CHECK-SAME:"=r,=r,=r,=r,0,1,2,3,l,l,n" %[[V0_3]], %[[V1_3]], %[[V2_3]], %[[V3_3]], %[[ARG0]], %[[ARG1]], %{{.*}} |
| %result = llvm.mlir.undef : !mat16i32 |
| %result1 = nvvm.wgmma.mma_async %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>], |
| A [<u8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<u8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| %result2 = nvvm.wgmma.mma_async %descA, %descB, %result1, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>], |
| A [<u8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<u8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| %result3 = nvvm.wgmma.mma_async %descA, %descB, %result2, |
| #nvvm.shape<m = 64, n = 8, k = 32>, |
| D [<s32>, #nvvm.wgmma_scale_out<one>], |
| A [<u8>, #nvvm.wgmma_scale_in<one>, <row>], |
| B [<u8>, #nvvm.wgmma_scale_in<one>, <col>] |
| : !mat16i32 -> !mat16i32 |
| return %result3 : !mat16i32 |
| } |
| |
| // ----- |
| |
| !mat32f32 = !llvm.struct<( |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32)> |
| |
| // CHECK-LABEL: @wgmma_f32_tf32_tf32 |
| func.func @wgmma_f32_tf32_tf32(%descA : i64, %descB : i64) -> !mat32f32 { |
| // CHECK: %[[RES:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME:"{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k8.f32.tf32.tf32 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| // CHECK: %[[RES_2:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{ |
| // CHECK-SAME: .reg .pred p; |
| // CHECK-SAME: setp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k8.f32.tf32.tf32 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| %result = llvm.mlir.undef : !mat32f32 |
| %result1 = nvvm.wgmma.mma_async %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 64, k = 8>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<tf32>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<tf32>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| %result2 = nvvm.wgmma.mma_async %descA, %descB, %result1, |
| #nvvm.shape<m = 64, n = 64, k = 8>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<tf32>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<tf32>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| return %result2 : !mat32f32 |
| } |
| |
| |
| // ----- |
| |
| !mat32f32 = !llvm.struct<( |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32)> |
| |
| // CHECK-LABEL: @wgmma_f32_e4m3_e4m3 |
| func.func @wgmma_f32_e4m3_e4m3(%descA : i64, %descB : i64) -> !mat32f32 { |
| // CHECK: %[[RES:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{\0A.reg .pred p;\0Asetp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k32.f32.e4m3.e4m3 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| // CHECK: %[[RES_2:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{\0A.reg .pred p;\0Asetp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k32.f32.e4m3.e4m3 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| %result = llvm.mlir.undef : !mat32f32 |
| %result1 = nvvm.wgmma.mma_async %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 64, k = 32>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| %result2 = nvvm.wgmma.mma_async %descA, %descB, %result1, |
| #nvvm.shape<m = 64, n = 64, k = 32>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| return %result2 : !mat32f32 |
| } |
| |
| // ----- |
| |
| !mat32f32 = !llvm.struct<( |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32, |
| f32, f32, f32, f32, f32, f32, f32, f32)> |
| |
| // CHECK-LABEL: @wgmma_f32_e5m2_e4m3 |
| func.func @wgmma_f32_e5m2_e4m3(%descA : i64, %descB : i64) -> !mat32f32 { |
| // CHECK: %[[RES:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{\0A.reg .pred p;\0Asetp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k32.f32.e5m2.e4m3 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| // CHECK: %[[RES_2:.+]] = llvm.inline_asm has_side_effects asm_dialect = att |
| // CHECK-SAME: "{\0A.reg .pred p;\0Asetp.ne.b32 p, $66, 0; |
| // CHECK-SAME: wgmma.mma_async.sync.aligned.m64n64k32.f32.e5m2.e4m3 {$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31}, $64, $65, p, $67, $68;\0A}\0A", "=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,=f,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,l,l,n,n,n" |
| %result = llvm.mlir.undef : !mat32f32 |
| %result1 = nvvm.wgmma.mma_async %descA, %descB, %result, |
| #nvvm.shape<m = 64, n = 64, k = 32>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<e5m2>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| %result2 = nvvm.wgmma.mma_async %descA, %descB, %result1, |
| #nvvm.shape<m = 64, n = 64, k = 32>, |
| D [#nvvm.wgmma_type<f32>, #nvvm.wgmma_scale_out<one>], |
| A [#nvvm.wgmma_type<e5m2>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<row>], |
| B [#nvvm.wgmma_type<e4m3>, #nvvm.wgmma_scale_in<one>, #nvvm.mma_layout<col>] |
| : !mat32f32 -> !mat32f32 |
| return %result2 : !mat32f32 |
| } |
| |
| // ----- |
| |
| func.func @elect_one_leader_sync() { |
| // CHECK: %[[RES:.*]] = nvvm.elect.sync -> i1 |
| %cnd = nvvm.elect.sync -> i1 |
| return |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: @test_nvvm_prefetch |
| llvm.func @test_nvvm_prefetch(%desc : !llvm.ptr, %pred : i1) { |
| //CHECK: nvvm.prefetch tensormap, %{{.*}} |
| nvvm.prefetch tensormap, %desc : !llvm.ptr |
| //CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$1 prefetch.tensormap [$0];", "l,b" |
| nvvm.prefetch tensormap, %desc, predicate = %pred : !llvm.ptr, i1 |
| llvm.return |
| } |
| |
| // ----- |
| |
| func.func @set_max_register() { |
| // CHECK: nvvm.setmaxregister increase 232 |
| nvvm.setmaxregister increase 232 |
| |
| // CHECK: nvvm.setmaxregister decrease 40 |
| nvvm.setmaxregister decrease 40 |
| func.return |
| } |
| |
| // ----- |
| |
| func.func @cp_async_bulk_commit() { |
| // CHECK: nvvm.cp.async.bulk.commit.group |
| nvvm.cp.async.bulk.commit.group |
| func.return |
| } |
| |
| // ----- |
| |
| func.func @cp_async_bulk_wait_group() { |
| // CHECK: nvvm.cp.async.bulk.wait_group 1 |
| // CHECK: nvvm.cp.async.bulk.wait_group 0 |
| // CHECK: nvvm.cp.async.bulk.wait_group 5 {read} |
| // CHECK: nvvm.cp.async.bulk.wait_group 0 {read} |
| nvvm.cp.async.bulk.wait_group 1 |
| nvvm.cp.async.bulk.wait_group 0 |
| nvvm.cp.async.bulk.wait_group 5 {read} |
| nvvm.cp.async.bulk.wait_group 0 {read} |
| func.return |
| } |
| |
| // ----- |
| |
| // CHECK-LABEL: @llvm_nvvm_barrier_arrive |
| // CHECK-SAME: (%[[barId:.*]]: i32, %[[numberOfThreads:.*]]: i32) |
| llvm.func @llvm_nvvm_barrier_arrive(%barID : i32, %numberOfThreads : i32) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "bar.arrive 0, $0;", "r" %[[numberOfThreads]] : (i32) -> () |
| nvvm.barrier.arrive number_of_threads = %numberOfThreads |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "bar.arrive $0, $1;", "r,r" %[[barId]], %[[numberOfThreads]] : (i32, i32) -> () |
| nvvm.barrier.arrive id = %barID number_of_threads = %numberOfThreads |
| llvm.return |
| } |
| |
| |
| // ----- |
| |
| llvm.func @init_mbarrier( |
| %barrier_gen : !llvm.ptr, |
| %barrier : !llvm.ptr<3>, |
| %count : i32, |
| %pred : i1) { |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "mbarrier.init.b64 [$0], $1;", "l,r" |
| nvvm.inline_ptx "mbarrier.init.b64 [{$r0}], {$r1};" ro (%barrier_gen, %count : !llvm.ptr, i32) |
| // CHECK: llvm.inline_asm has_side_effects asm_dialect = att "@$2 mbarrier.init.b64 [$0], $1;", "l,r,b" |
| nvvm.inline_ptx "mbarrier.init.b64 [{$r0}], {$r1};" ro (%barrier_gen, %count : !llvm.ptr, i32), predicate = %pred |
| llvm.return |
| } |
| // ----- |
| |
| llvm.func @ex2(%input : f32, %pred : i1) { |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "ex2.approx.ftz.f32 $0, $1;", "=f,f" %{{.*}} : (f32) -> f32 |
| %0 = nvvm.inline_ptx "ex2.approx.ftz.f32 {$w0}, {$r0};" ro (%input : f32) -> f32 |
| |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "@$1 ex2.approx.ftz.f32 $0, $1;", "=f,f,b" %{{.*}}, %{{.*}} : (f32, i1) -> f32 |
| %1 = nvvm.inline_ptx "ex2.approx.ftz.f32 {$w0}, {$r0};" ro (%input : f32), predicate = %pred -> f32 |
| llvm.return |
| } |
| |
| // CHECK-LABEL: @multi_return( |
| // CHECK-SAME: %[[arg0:[a-zA-Z0-9_]+]]: i32, %[[arg1:[a-zA-Z0-9_]+]]: i32) |
| llvm.func @multi_return(%a : i32, %b : i32) -> i32 { |
| // CHECK: %[[S1:.+]] = llvm.inline_asm has_side_effects asm_dialect = att "{.reg .pred p; setp.ge.s32 p, $2, $3; selp.s32 $0, $2,$3, p; selp.s32 $1, $2,$3, p;}", "=r,=r,r,r" %[[arg0]], %[[arg1]] : (i32, i32) -> !llvm.struct<(i32, i32)> |
| // CHECK: %[[S2:.+]] = llvm.extractvalue %[[S1]][0] : !llvm.struct<(i32, i32)> |
| // CHECK: %[[S3:.+]] = llvm.extractvalue %[[S1]][1] : !llvm.struct<(i32, i32)> |
| // CHECK: %[[S4:.+]] = llvm.add %[[S2]], %[[S3]] : i32 |
| // CHECK: llvm.return %[[S4]] : i32 |
| %r1, %r2 = nvvm.inline_ptx "{.reg .pred p; setp.ge.s32 p, {$r0}, {$r1}; selp.s32 {$w0}, {$r0},{$r1}, p; selp.s32 {$w1}, {$r0},{$r1}, p;}" |
| ro (%a, %b : i32,i32) -> i32,i32 |
| %r3 = llvm.add %r1, %r2 : i32 |
| llvm.return %r3 : i32 |
| } |
| |
| // CHECK-LABEL: @inline_ptx_multi_rw( |
| // CHECK-SAME: %[[arg0:[a-zA-Z0-9_]+]]: i32, %[[arg1:[a-zA-Z0-9_]+]]: i32, %[[arg2:[a-zA-Z0-9_]+]]: f32, %[[arg3:[a-zA-Z0-9_]+]]: f32) |
| llvm.func @inline_ptx_multi_rw(%a : i32, %b : i32, %rw_c : f32, %rw_d : f32) -> f32 { |
| // CHECK: %[[S0:.+]] = llvm.inline_asm has_side_effects asm_dialect = att "{.reg .pred p; setp.ge.s32 p, $2, $3; selp.s32 $0, $2,$3, p; selp.s32 $1, $2,$3, p;}", |
| // CHECK-SAME: "=f,=f,r,r,0,1" |
| // CHECK-SAME: %[[arg2]], %[[arg3]], %[[arg0]], %[[arg1]] |
| // CHECK-SAME: : (f32, f32, i32, i32) -> !llvm.struct<(f32, f32)> |
| // CHECK: %[[S1:.+]] = llvm.extractvalue %[[S0]][0] : !llvm.struct<(f32, f32)> |
| // CHECK: %[[S2:.+]] = llvm.extractvalue %[[S0]][1] : !llvm.struct<(f32, f32)> |
| // CHECK: %[[S3:.+]] = llvm.fadd %[[S1]], %[[S2]] : f32 |
| // CHECK: llvm.return %[[S3]] : f32 |
| nvvm.inline_ptx "{.reg .pred p; setp.ge.s32 p, {$r0}, {$r1}; selp.s32 {$rw0}, {$r0},{$r1}, p; selp.s32 {$rw1}, {$r0},{$r1}, p;}" |
| ro (%a, %b : i32,i32) |
| rw (%rw_c, %rw_d: f32,f32) |
| %r4 = llvm.fadd %rw_c, %rw_d : f32 |
| llvm.return %r4 : f32 |
| } |
| |
| // CHECK-LABEL: @inline_ptx_multi_rw_r( |
| // CHECK-SAME: %[[arg0:[a-zA-Z0-9_]+]]: i32, %[[arg1:[a-zA-Z0-9_]+]]: i32, %[[arg2:[a-zA-Z0-9_]+]]: f32, %[[arg3:[a-zA-Z0-9_]+]]: f32) |
| llvm.func @inline_ptx_multi_rw_r(%a : i32, %b : i32, %rw_c : f32, %rw_d : f32) -> f32 { |
| // CHECK: %[[S0:.+]] = llvm.inline_asm has_side_effects asm_dialect = att "{.reg .pred p; setp.ge.s32 p, $4, $5; selp.s32 $0, $4,$5, p; selp.s32 $1, $4,$5, p; selp.s32 $2, $4,$5, p; selp.s32 $3, $4,$5, p;}", |
| // CHECK-SAME: "=f,=f,=r,=r,r,r,0,1" |
| // CHECK-SAME: %[[arg2]], %[[arg3]], %[[arg0]], %[[arg1]] : |
| // CHECK-SAME: (f32, f32, i32, i32) -> !llvm.struct<(f32, f32, i32, i32)> |
| // CHECK: %[[S1:.+]] = llvm.extractvalue %[[S0]][0] : !llvm.struct<(f32, f32, i32, i32)> |
| // CHECK: %[[S2:.+]] = llvm.extractvalue %[[S0]][1] : !llvm.struct<(f32, f32, i32, i32)> |
| // CHECK: %[[S3:.+]] = llvm.extractvalue %[[S0]][2] : !llvm.struct<(f32, f32, i32, i32)> |
| // CHECK: %[[S4:.+]] = llvm.extractvalue %[[S0]][3] : !llvm.struct<(f32, f32, i32, i32)> |
| // CHECK: %[[S5:.+]] = llvm.add %[[S3]], %[[S4]] : i32 |
| // CHECK: %[[S6:.+]] = llvm.sitofp %[[S5]] : i32 to f32 |
| // CHECK: %[[S7:.+]] = llvm.fadd %[[S1]], %[[S2]] : f32 |
| // CHECK: %[[S8:.+]] = llvm.fadd %[[S6]], %[[S2]] : f32 |
| // CHECK: llvm.return %[[S8]] : f32 |
| |
| %wo0, %wo1 = nvvm.inline_ptx "{.reg .pred p; setp.ge.s32 p, {$r0}, {$r1}; selp.s32 {$rw0}, {$r0},{$r1}, p; selp.s32 {$rw1}, {$r0},{$r1}, p; selp.s32 {$w0}, {$r0},{$r1}, p; selp.s32 {$w1}, {$r0},{$r1}, p;}" |
| ro (%a, %b : i32,i32) |
| rw (%rw_c, %rw_d: f32,f32) -> i32,i32 |
| %r3 = llvm.add %wo0, %wo1 : i32 |
| %r3f = llvm.sitofp %r3 : i32 to f32 |
| %r4 = llvm.fadd %rw_c, %rw_d : f32 |
| %r5 = llvm.fadd %r3f, %rw_d : f32 |
| llvm.return %r5 : f32 |
| } |
| |
| // ----- |
| |
| llvm.func @inline_ptx_pack_4i8(%src : vector<4xi8>, %mask : i32, %zero: i32) { |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "dp4a.s32.s32 $0, $1, $2, $3;", "=r,r,r,r" %{{.*}}, %{{.*}}, %{{.*}} : (vector<4xi8>, i32, i32) -> i32 |
| %wo0 = nvvm.inline_ptx "dp4a.s32.s32 {$w0}, {$r0}, {$r1}, {$r2};" |
| ro(%src, %mask, %zero : vector<4xi8>, i32, i32) |
| -> i32 |
| llvm.return |
| } |
| |
| llvm.func @inline_ptx_pack_2bf16(%a : f32, %b : f32) { |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "cvt.rn.satfinite.bf16x2.f32 $0, $1, $2;", "=f,f,f" %{{.*}}, %{{.*}} : (f32, f32) -> vector<2xbf16> |
| %wo0 = nvvm.inline_ptx "cvt.rn.satfinite.bf16x2.f32 {$w0}, {$r0}, {$r1};" |
| ro(%a, %b : f32, f32) |
| -> vector<2xbf16> |
| llvm.return |
| } |
| |
| llvm.func @inline_ptx_cvt_rn_e4m3x2_f16x2(%a : i16) { |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "cvt.rz.satfinite.ue8m0x2.bf16x2 $0, $1", "=f,h" %{{.*}} : (i16) -> vector<2xbf16> |
| %wo0 = nvvm.inline_ptx "cvt.rz.satfinite.ue8m0x2.bf16x2 {$w0}, {$r0}" |
| ro(%a : i16) |
| -> vector<2xbf16> |
| llvm.return |
| } |
| |
| llvm.func @cvt_i8_bf16(%a : i8) { |
| // CHECK: %{{.*}} = llvm.inline_asm has_side_effects asm_dialect = att "{\0A\09.reg .b16 r;\0A\09.reg .b8 s;\0A\09mov.b16 {s,_}, $0;\0A\09cvt.rn.bf16.s8 r, s;\0A\09mov.b16 $1, r;\0A\09", "=h,h" %{{.*}} : (i16) -> i16 |
| %za = llvm.zext %a : i8 to i16 |
| %wo0 = nvvm.inline_ptx "{\n\t.reg .b16 r;\n\t.reg .b8 s;\n\tmov.b16 {s,_}, {$w0};\n\tcvt.rn.bf16.s8 r, s;\n\tmov.b16 {$r0}, r;\n\t" |
| ro(%za : i16) |
| -> i16 |
| llvm.return |
| } |