Skip to content

Commit d350c49

Browse files
committed
[mlir][ArmSME] Verify ops on tile types post LLVM conversion
Unsupported ops on tile types can become dead after `-convert-arm-sme-to-llvm` resulting in incorrect results. Verify such operations don't exist post-conversion and fail if they do. Based on discussion from https://discourse.llvm.org/t/on-improving-arm-sme-lowering-resilience-in-mlir/78543
1 parent 73324cb commit d350c49

File tree

4 files changed

+132
-54
lines changed

4 files changed

+132
-54
lines changed

mlir/lib/Conversion/ArmSMEToLLVM/ArmSMEToLLVM.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "mlir/Dialect/ArmSME/IR/ArmSME.h"
1919
#include "mlir/Dialect/ArmSME/Transforms/Transforms.h"
2020
#include "mlir/Dialect/ArmSME/Utils/Utils.h"
21+
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
2122
#include "mlir/Dialect/Func/IR/FuncOps.h"
2223
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
2324
#include "mlir/Dialect/MemRef/IR/MemRef.h"
@@ -877,6 +878,26 @@ struct ConvertArmSMEToLLVMPass
877878

878879
if (failed(applyPartialConversion(function, target, std::move(patterns))))
879880
signalPassFailure();
881+
882+
// Walk the function and fail if there are unexpected operations on SME
883+
// tile types after conversion.
884+
function->walk([&](Operation *op) {
885+
// These ops are legal post conversion, skip these.
886+
if (isa<arm_sme::CopyTileOp, arm_sme::GetTileOp, cf::BranchOp>(op) ||
887+
!op->isRegistered())
888+
return;
889+
if (llvm::any_of(op->getResultTypes(),
890+
[](Type type) {
891+
return arm_sme::isValidSMETileVectorType(type);
892+
}) ||
893+
llvm::any_of(op->getOperandTypes(), [](Type type) {
894+
return arm_sme::isValidSMETileVectorType(type);
895+
})) {
896+
op->emitOpError("unexpected operation with SME tile type after "
897+
"conversion to LLVM");
898+
signalPassFailure();
899+
}
900+
});
880901
}
881902
};
882903

mlir/test/Conversion/ArmSMEToLLVM/arm-sme-to-llvm.mlir

Lines changed: 97 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -629,18 +629,18 @@ func.func @arm_sme_streaming_vl_double_words() -> index {
629629

630630
// CHECK-LABEL: arm_sme_fmopa_2way_f16f16_to_f32
631631
// CHECK: "arm_sme.intr.mopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xf16>, vector<[8]xf16>) -> ()
632-
func.func @arm_sme_fmopa_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) -> vector<[4]x[4]xf32> {
632+
func.func @arm_sme_fmopa_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) {
633633
%result = arm_sme.fmopa_2way %vecA, %vecB : vector<[8]xf16>, vector<[8]xf16> into vector<[4]x[4]xf32>
634-
return %result : vector<[4]x[4]xf32>
634+
"test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
635635
}
636636

637637
// -----
638638

639639
// CHECK-LABEL: arm_sme_fmopa_2way_bf16bf16_to_f32
640640
// CHECK: "arm_sme.intr.mopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xbf16>, vector<[8]xbf16>) -> ()
641-
func.func @arm_sme_fmopa_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) -> vector<[4]x[4]xf32> {
641+
func.func @arm_sme_fmopa_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) {
642642
%result = arm_sme.fmopa_2way %vecA, %vecB : vector<[8]xbf16>, vector<[8]xbf16> into vector<[4]x[4]xf32>
643-
return %result : vector<[4]x[4]xf32>
643+
"test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
644644
}
645645

646646
//===----------------------------------------------------------------------===//
@@ -651,18 +651,18 @@ func.func @arm_sme_fmopa_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: ve
651651

652652
// CHECK-LABEL: arm_sme_fmops_2way_f16f16_to_f32
653653
// CHECK: "arm_sme.intr.mops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xf16>, vector<[8]xf16>) -> ()
654-
func.func @arm_sme_fmops_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) -> vector<[4]x[4]xf32> {
654+
func.func @arm_sme_fmops_2way_f16f16_to_f32(%vecA: vector<[8]xf16>, %vecB: vector<[8]xf16>) {
655655
%result = arm_sme.fmops_2way %vecA, %vecB : vector<[8]xf16>, vector<[8]xf16> into vector<[4]x[4]xf32>
656-
return %result : vector<[4]x[4]xf32>
656+
"test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
657657
}
658658

659659
// -----
660660

661661
// CHECK-LABEL: arm_sme_fmops_2way_bf16bf16_to_f32
662662
// CHECK: "arm_sme.intr.mops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xbf16>, vector<[8]xbf16>) -> ()
663-
func.func @arm_sme_fmops_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) -> vector<[4]x[4]xf32> {
663+
func.func @arm_sme_fmops_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: vector<[8]xbf16>) {
664664
%result = arm_sme.fmops_2way %vecA, %vecB : vector<[8]xbf16>, vector<[8]xbf16> into vector<[4]x[4]xf32>
665-
return %result : vector<[4]x[4]xf32>
665+
"test.some_use"(%result) : (vector<[4]x[4]xf32>) -> ()
666666
}
667667

668668
//===----------------------------------------------------------------------===//
@@ -673,9 +673,9 @@ func.func @arm_sme_fmops_2way_bf16bf16_to_f32(%vecA: vector<[8]xbf16>, %vecB: ve
673673

674674
// CHECK-LABEL: arm_sme_smopa_2way_i16i16_to_i32
675675
// CHECK: "arm_sme.intr.smopa.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
676-
func.func @arm_sme_smopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[4]x[4]xi32> {
676+
func.func @arm_sme_smopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
677677
%result = arm_sme.smopa_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
678-
return %result : vector<[4]x[4]xi32>
678+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
679679
}
680680

681681
//===----------------------------------------------------------------------===//
@@ -686,9 +686,9 @@ func.func @arm_sme_smopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vecto
686686

687687
// CHECK-LABEL: arm_sme_smops_2way_i16i16_to_i32
688688
// CHECK: "arm_sme.intr.smops.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
689-
func.func @arm_sme_smops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[4]x[4]xi32> {
689+
func.func @arm_sme_smops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
690690
%result = arm_sme.smops_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
691-
return %result : vector<[4]x[4]xi32>
691+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
692692
}
693693

694694
//===----------------------------------------------------------------------===//
@@ -699,9 +699,10 @@ func.func @arm_sme_smops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vecto
699699

700700
// CHECK-LABEL: arm_sme_umopa_2way_i16i16_to_i32
701701
// CHECK: "arm_sme.intr.umopa.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
702-
func.func @arm_sme_umopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[4]x[4]xi32> {
702+
func.func @arm_sme_umopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
703703
%result = arm_sme.umopa_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
704-
return %result : vector<[4]x[4]xi32>
704+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
705+
return
705706
}
706707

707708
//===----------------------------------------------------------------------===//
@@ -712,9 +713,10 @@ func.func @arm_sme_umopa_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vecto
712713

713714
// CHECK-LABEL: arm_sme_umops_2way_i16i16_to_i32
714715
// CHECK: "arm_sme.intr.umops.za32"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
715-
func.func @arm_sme_umops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[4]x[4]xi32> {
716+
func.func @arm_sme_umops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
716717
%result = arm_sme.umops_2way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[4]x[4]xi32>
717-
return %result : vector<[4]x[4]xi32>
718+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
719+
return
718720
}
719721

720722
//===----------------------------------------------------------------------===//
@@ -725,18 +727,20 @@ func.func @arm_sme_umops_2way_i16i16_to_i32(%vecA: vector<[8]xi16>, %vecB: vecto
725727

726728
// CHECK-LABEL: arm_sme_smopa_4way_i8i8_to_i32
727729
// CHECK: "arm_sme.intr.smopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
728-
func.func @arm_sme_smopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
730+
func.func @arm_sme_smopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
729731
%result = arm_sme.smopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
730-
return %result : vector<[4]x[4]xi32>
732+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
733+
return
731734
}
732735

733736
// -----
734737

735738
// CHECK-LABEL: arm_sme_smopa_4way_i16i16_to_i64
736739
// CHECK: "arm_sme.intr.smopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
737-
func.func @arm_sme_smopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
740+
func.func @arm_sme_smopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
738741
%result = arm_sme.smopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
739-
return %result : vector<[2]x[2]xi64>
742+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
743+
return
740744
}
741745

742746
//===----------------------------------------------------------------------===//
@@ -747,18 +751,20 @@ func.func @arm_sme_smopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vecto
747751

748752
// CHECK-LABEL: arm_sme_smops_4way_i8i8_to_i32
749753
// CHECK: "arm_sme.intr.smops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
750-
func.func @arm_sme_smops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
754+
func.func @arm_sme_smops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
751755
%result = arm_sme.smops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
752-
return %result : vector<[4]x[4]xi32>
756+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
757+
return
753758
}
754759

755760
// -----
756761

757762
// CHECK-LABEL: arm_sme_smops_4way_i16i16_to_i64
758763
// CHECK: "arm_sme.intr.smops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
759-
func.func @arm_sme_smops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
764+
func.func @arm_sme_smops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
760765
%result = arm_sme.smops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
761-
return %result : vector<[2]x[2]xi64>
766+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
767+
return
762768
}
763769

764770
//===----------------------------------------------------------------------===//
@@ -769,18 +775,20 @@ func.func @arm_sme_smops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vecto
769775

770776
// CHECK-LABEL: arm_sme_umopa_4way_i8i8_to_i32
771777
// CHECK: "arm_sme.intr.umopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
772-
func.func @arm_sme_umopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
778+
func.func @arm_sme_umopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
773779
%result = arm_sme.umopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
774-
return %result : vector<[4]x[4]xi32>
780+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
781+
return
775782
}
776783

777784
// -----
778785

779786
// CHECK-LABEL: arm_sme_umopa_4way_i16i16_to_i64
780787
// CHECK: "arm_sme.intr.umopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
781-
func.func @arm_sme_umopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
788+
func.func @arm_sme_umopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
782789
%result = arm_sme.umopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
783-
return %result : vector<[2]x[2]xi64>
790+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
791+
return
784792
}
785793

786794
//===----------------------------------------------------------------------===//
@@ -791,18 +799,20 @@ func.func @arm_sme_umopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vecto
791799

792800
// CHECK-LABEL: arm_sme_umops_4way_i8i8_to_i32
793801
// CHECK: "arm_sme.intr.umops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
794-
func.func @arm_sme_umops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
802+
func.func @arm_sme_umops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
795803
%result = arm_sme.umops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
796-
return %result : vector<[4]x[4]xi32>
804+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
805+
return
797806
}
798807

799808
// -----
800809

801810
// CHECK-LABEL: arm_sme_umops_4way_i16i16_to_i64
802811
// CHECK: "arm_sme.intr.umops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
803-
func.func @arm_sme_umops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
812+
func.func @arm_sme_umops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
804813
%result = arm_sme.umops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
805-
return %result : vector<[2]x[2]xi64>
814+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
815+
return
806816
}
807817

808818
//===----------------------------------------------------------------------===//
@@ -813,18 +823,20 @@ func.func @arm_sme_umops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vecto
813823

814824
// CHECK-LABEL: arm_sme_sumopa_4way_i8i8_to_i32
815825
// CHECK: "arm_sme.intr.sumopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
816-
func.func @arm_sme_sumopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
826+
func.func @arm_sme_sumopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
817827
%result = arm_sme.sumopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
818-
return %result : vector<[4]x[4]xi32>
828+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
829+
return
819830
}
820831

821832
// -----
822833

823834
// CHECK-LABEL: arm_sme_sumopa_4way_i16i16_to_i64
824835
// CHECK: "arm_sme.intr.sumopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
825-
func.func @arm_sme_sumopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
836+
func.func @arm_sme_sumopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
826837
%result = arm_sme.sumopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
827-
return %result : vector<[2]x[2]xi64>
838+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
839+
return
828840
}
829841

830842
//===----------------------------------------------------------------------===//
@@ -835,18 +847,20 @@ func.func @arm_sme_sumopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vect
835847

836848
// CHECK-LABEL: arm_sme_sumops_4way_i8i8_to_i32
837849
// CHECK: "arm_sme.intr.sumops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
838-
func.func @arm_sme_sumops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
850+
func.func @arm_sme_sumops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
839851
%result = arm_sme.sumops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
840-
return %result : vector<[4]x[4]xi32>
852+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
853+
return
841854
}
842855

843856
// -----
844857

845858
// CHECK-LABEL: arm_sme_sumops_4way_i16i16_to_i64
846859
// CHECK: "arm_sme.intr.sumops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
847-
func.func @arm_sme_sumops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
860+
func.func @arm_sme_sumops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
848861
%result = arm_sme.sumops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
849-
return %result : vector<[2]x[2]xi64>
862+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
863+
return
850864
}
851865

852866
//===----------------------------------------------------------------------===//
@@ -857,18 +871,20 @@ func.func @arm_sme_sumops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vect
857871

858872
// CHECK-LABEL: arm_sme_usmopa_4way_i8i8_to_i32
859873
// CHECK: "arm_sme.intr.usmopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
860-
func.func @arm_sme_usmopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
861-
%reuslt = arm_sme.usmopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
862-
return %reuslt : vector<[4]x[4]xi32>
874+
func.func @arm_sme_usmopa_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
875+
%result = arm_sme.usmopa_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
876+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
877+
return
863878
}
864879

865880
// -----
866881

867882
// CHECK-LABEL: arm_sme_usmopa_4way_i16i16_to_i64
868883
// CHECK: "arm_sme.intr.usmopa.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
869-
func.func @arm_sme_usmopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
870-
%reuslt = arm_sme.usmopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
871-
return %reuslt : vector<[2]x[2]xi64>
884+
func.func @arm_sme_usmopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
885+
%result = arm_sme.usmopa_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
886+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
887+
return
872888
}
873889

874890
//===----------------------------------------------------------------------===//
@@ -879,16 +895,45 @@ func.func @arm_sme_usmopa_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vect
879895

880896
// CHECK-LABEL: arm_sme_usmops_4way_i8i8_to_i32
881897
// CHECK: "arm_sme.intr.usmops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[16]xi1>, vector<[16]xi1>, vector<[16]xi8>, vector<[16]xi8>) -> ()
882-
func.func @arm_sme_usmops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) -> vector<[4]x[4]xi32> {
883-
%reuslt = arm_sme.usmops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
884-
return %reuslt : vector<[4]x[4]xi32>
898+
func.func @arm_sme_usmops_4way_i8i8_to_i32(%vecA: vector<[16]xi8>, %vecB: vector<[16]xi8>) {
899+
%result = arm_sme.usmops_4way %vecA, %vecB : vector<[16]xi8>, vector<[16]xi8> into vector<[4]x[4]xi32>
900+
"test.some_use"(%result) : (vector<[4]x[4]xi32>) -> ()
901+
return
885902
}
886903

887904
// -----
888905

889906
// CHECK-LABEL: arm_sme_usmops_4way_i16i16_to_i64
890907
// CHECK: "arm_sme.intr.usmops.wide"({{.*}}) <{tile_id = 0 : i32}> : (vector<[8]xi1>, vector<[8]xi1>, vector<[8]xi16>, vector<[8]xi16>) -> ()
891-
func.func @arm_sme_usmops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) -> vector<[2]x[2]xi64> {
892-
%reuslt = arm_sme.usmops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
893-
return %reuslt : vector<[2]x[2]xi64>
908+
func.func @arm_sme_usmops_4way_i16i16_to_i64(%vecA: vector<[8]xi16>, %vecB: vector<[8]xi16>) {
909+
%result = arm_sme.usmops_4way %vecA, %vecB : vector<[8]xi16>, vector<[8]xi16> into vector<[2]x[2]xi64>
910+
"test.some_use"(%result) : (vector<[2]x[2]xi64>) -> ()
911+
return
912+
}
913+
914+
//===----------------------------------------------------------------------===//
915+
// Operations on SME tile types allowed after conversion
916+
//===----------------------------------------------------------------------===//
917+
918+
// -----
919+
920+
// The following operations on SME tile types are permitted after conversion:
921+
//
922+
// - arm_sme.copy_tile
923+
// - arm_sme.get_tile
924+
// - cf.br
925+
// - any unregistered op such as 'test.some_use'.
926+
//
927+
// this test verifies this. Conversion will fail for operations with SME tile
928+
// types not in this list, this is tested in 'unsupported.mlir'.
929+
930+
func.func @ops_on_tiles_legal_post_conversion(%ub : index) {
931+
%c0 = arith.constant 0 : index
932+
%c1 = arith.constant 1 : index
933+
%tile = arm_sme.get_tile : vector<[4]x[4]xf32>
934+
%copy = arm_sme.copy_tile %tile : vector<[4]x[4]xf32>
935+
cf.br ^bb1(%copy : vector<[4]x[4]xf32>)
936+
^bb1(%x : vector<[4]x[4]xf32>):
937+
"test.some_use"(%x) : (vector<[4]x[4]xf32>) -> ()
938+
return
894939
}

0 commit comments

Comments
 (0)