[llvm] [VE] Add unittest for intrinsics (PR #66730)

Kazushi Marukawa via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 19:43:22 PDT 2023


https://github.com/kaz7 created https://github.com/llvm/llvm-project/pull/66730

Add unittest for VE intrinsics instructions.

>From fe08cae3bcbdda3d38a08ea4303c95413ceb8c36 Mon Sep 17 00:00:00 2001
From: "Kazushi (Jam) Marukawa" <marukawa at nec.com>
Date: Tue, 19 Sep 2023 04:16:15 +0200
Subject: [PATCH] [VE] Add unittest for intrinsics

---
 llvm/unittests/Target/VE/CMakeLists.txt       |  20 ++
 llvm/unittests/Target/VE/MachineInstrTest.cpp | 315 ++++++++++++++++++
 2 files changed, 335 insertions(+)
 create mode 100644 llvm/unittests/Target/VE/CMakeLists.txt
 create mode 100644 llvm/unittests/Target/VE/MachineInstrTest.cpp

diff --git a/llvm/unittests/Target/VE/CMakeLists.txt b/llvm/unittests/Target/VE/CMakeLists.txt
new file mode 100644
index 000000000000000..9e6576fc7bc0e8e
--- /dev/null
+++ b/llvm/unittests/Target/VE/CMakeLists.txt
@@ -0,0 +1,20 @@
+include_directories(
+  ${LLVM_SOURCE_DIR}/lib/Target/VE
+  ${LLVM_BINARY_DIR}/lib/Target/VE
+  )
+
+set(LLVM_LINK_COMPONENTS
+  VECodeGen
+  VEDesc
+  VEInfo
+  CodeGen
+  GlobalISel
+  MC
+  SelectionDAG
+  Support
+  Target
+)
+
+add_llvm_target_unittest(VETests
+  MachineInstrTest.cpp
+  )
diff --git a/llvm/unittests/Target/VE/MachineInstrTest.cpp b/llvm/unittests/Target/VE/MachineInstrTest.cpp
new file mode 100644
index 000000000000000..52181b9d6074ece
--- /dev/null
+++ b/llvm/unittests/Target/VE/MachineInstrTest.cpp
@@ -0,0 +1,315 @@
+//===- MachineInstrTest.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "VEInstrInfo.h"
+#include "VESubtarget.h"
+#include "VETargetMachine.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+TEST(VETest, VLIndex) {
+  using namespace VE;
+
+  // Return expected VL register index in each MI's operands.  Aurora VE has
+  // multiple instruction formats for each instruction.  So, we defines
+  // instructions hierarchically and tests a part of whole instructions.
+  // This function returns -1 to N as expected index, or -2 as default.
+  // We skip a test on an instructions that this functions returns -2.
+  auto VLIndex = [](unsigned Opcode) {
+    switch (Opcode) {
+    default:
+      break;
+    case VLDNCrz:
+      return -1;
+    case VLDUNCrzl:
+    case VLDLSXrzl_v:
+    case VLDLZXNCirL:
+    case VLD2DNCrrL_v:
+    case VLDU2DNCrzL_v:
+    case VLDL2DSXizL_v:
+    case VLDL2DZXNCirl:
+      return 3;
+    case VSTOTrrv:
+      return -1;
+    case VSTUNCrzvl:
+    case VSTLNCOTizvL:
+    case VST2Dirvl:
+      return 3;
+    case VSTU2DNCrzvml:
+    case VSTL2DNCOTrzvml:
+      return 4;
+    case VGTNCsrzm_v:
+      return -1;
+    case VGTUNCvrzl:
+    case VGTLSXvrzl_v:
+    case VGTLZXNCsirL:
+      return 4;
+    case VGTNCsrrmL_v:
+    case VGTUNCvrzmL:
+    case VGTLSXsizml_v:
+      return 5;
+    case VSCNCsrzvm:
+      return -1;
+    case VSCUNCvrzvl:
+    case VSCLNCsirvL:
+      return 4;
+    case VSCOTsrrvmL:
+    case VSCUNCOTvrzvmL:
+    case VSCLsizvml:
+      return 5;
+    case PFCHVrr:
+      return -1;
+    case PFCHVrrl:
+    case PFCHVNCrzL:
+      return 2;
+    case VBRDrm:
+      return -1;
+    case VBRDrl:
+      return 2;
+    case VBRDimL_v:
+      return 3;
+    case VMVrvm_v:
+      return -1;
+    case VMVivl:
+      return 3;
+    case VMVrvmL_v:
+      return 4;
+    case VADDULvv_v:
+    case PVADDULOrvm:
+      return -1;
+    case VADDUWvvl_v:
+    case PVADDUUPrvL:
+      return 3;
+    case PVADDUvvmL_v:
+    case VADDSWSXivml:
+    case VADDSLivml:
+      return 4;
+    case VDIVULvv_v:
+    case VDIVSWSXrvm:
+      return -1;
+    case VDIVUWvrl_v:
+    case VDIVSWZXviL:
+      return 3;
+    case VDIVSLivmL_v:
+    case VDIVSWSXivml:
+      return 4;
+    // We test casually if instructions are defined using a multiclass already
+    // tested.
+    case VSUBSLivml:
+    case VMULSLivml:
+    case VCMPSLivml:
+    case VMAXSLivml:
+      return 4;
+    case VANDvv_v:
+    case PVANDLOrvm:
+      return -1;
+    case PVANDvvl_v:
+    case PVANDUPrvL:
+      return 3;
+    case VORvvmL_v:
+    case PVORLOmvml:
+    case VXORmvml:
+    case VEQVmvml:
+      return 4;
+    case VLDZv:
+      return -1;
+    case VPCNTvL:
+      return 2;
+    case VBRVvml:
+      return 3;
+    case VSEQ:
+      return -1;
+    case VSEQL:
+      return 1;
+    case VSEQml:
+      return 2;
+    case VSLLvv_v:
+    case PVSLLLOvrm:
+      return -1;
+    case PVSLLvvl_v:
+    case PVSRLUPvrL:
+      return 3;
+    case VSLLvimL_v:
+    case PVSRLLOvrml:
+    case VSLALvimL_v:
+    case VSRALvimL_v:
+      return 4;
+    case VSLDvvr_v:
+    case VSLDvvim:
+      return -1;
+    case VSLDvvrl_v:
+    case VSRDvviL:
+      return 4;
+    case VSLDvvimL_v:
+    case VSRDvvrml:
+      return 5;
+    case VSFAvrr_v:
+    case VSFAvrmm_v:
+      return -1;
+    case VSFAvirl_v:
+    case VSFAvirL:
+      return 4;
+    case VSFAvimml:
+    case VSFAvimmL_v:
+      return 5;
+    case VFADDDivml:
+    case VFSUBDivml:
+    case VFMULDivml:
+    case VFDIVDivml:
+    case VFCMPDivml:
+    case VFMAXDivml:
+      return 4;
+    case VFSQRTDv_v:
+    case VFSQRTSvm:
+      return -1;
+    case VFSQRTDvl_v:
+    case VFSQRTDvL:
+      return 2;
+    case VFSQRTDvmL_v:
+    case VFSQRTDvml:
+    case VFSQRTDvmL:
+      return 3;
+    case VFMADDvvv_v:
+    case PVFMADLOvrvm:
+      return -1;
+    case PVFMADvivl_v:
+    case PVFMADUPvrvL:
+      return 4;
+    case VFMADSivvmL_v:
+    case PVFMADLOvrvml:
+    case VFMSBDivvmL_v:
+    case VFNMADDivvmL_v:
+    case VFNMSBDivvmL_v:
+      return 5;
+    case VRCPDvmL:
+    case VRSQRTDvmL:
+    case VRSQRTDNEXvmL:
+      return 3;
+    case VCVTWDSXv:
+    case VCVTWDZXvm_v:
+      return -1;
+    case VCVTWSSXvl_v:
+    case VCVTWSZXvL:
+      return 3;
+    case PVCVTWSLOvmL_v:
+    case PVCVTWSUPvml:
+    case PVCVTWSvmL:
+    case VCVTLDvml:
+      return 4;
+    case VCVTDWvml:
+    case VCVTDLvml:
+    case VCVTSDvml:
+    case VCVTDSvml:
+    case VSUMWSXvml:
+    case VSUMLvml:
+    case VFSUMDvml:
+    case VRMAXSWFSTSXvml:
+    case VRMAXSLFSTvml:
+    case VFRMAXDFSTvml:
+    case VRANDvml:
+    case VRORvml:
+    case VRXORvml:
+      return 3;
+    case VFIADvr_v:
+    case VFIASvi_v:
+      return -1;
+    case VFIADvrl_v:
+    case VFIASviL_v:
+    case VFISDviL_v:
+    case VFIMDviL_v:
+      return 3;
+    case VFIAMDvvr_v:
+    case VFIAMSvvi_v:
+      return -1;
+    case VFISMDvvrl_v:
+    case VFISMSvviL_v:
+    case VFIMADvviL_v:
+    case VFIMSDvviL_v:
+      return 4;
+    case VMRGivml:
+      return 4;
+    case VCPvml:
+    case VEXvml:
+      return 3;
+    case VSHFvvr:
+    case VSHFvvr_v:
+      return -1;
+    case VSHFvvrl:
+    case VSHFvvrL_v:
+      return 4;
+    case VFMKLv:
+    case VFMKLvm:
+      return -1;
+    case VFMKLvl:
+    case VFMKLvL:
+      return 3;
+    case VFMKLvml:
+    case VFMKLvmL:
+      return 4;
+    case VFMKLal:
+    case VFMKLnaL:
+      return 1;
+    case VFMKLaml:
+    case VFMKLnamL:
+    case VFMKWnamL:
+    case VFMKDnamL:
+      return 2;
+    case TOVMm:
+    case PCVMm:
+    case LZVMm:
+      return -1;
+    case TOVMml:
+    case PCVMmL:
+    case LZVMml:
+      return 2;
+    }
+    return -2;
+  };
+
+  LLVMInitializeVETargetInfo();
+  LLVMInitializeVETarget();
+  LLVMInitializeVETargetMC();
+
+  auto TT(Triple::normalize("ve-unknown-linux-gnu"));
+  std::string Error;
+  const Target *T = TargetRegistry::lookupTarget(TT, Error);
+  if (!T) {
+    dbgs() << Error;
+    return;
+  }
+
+  TargetOptions Options;
+  auto TM = std::unique_ptr<LLVMTargetMachine>(
+    static_cast<LLVMTargetMachine*>(
+      T->createTargetMachine(TT, "", "", Options, std::nullopt, std::nullopt,
+                             CodeGenOptLevel::Default)));
+  VESubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
+                 std::string(TM->getTargetFeatureString()),
+                 *static_cast<const VETargetMachine *>(TM.get()));
+  const VEInstrInfo *TII = ST.getInstrInfo();
+  auto MII = TM->getMCInstrInfo();
+
+  for (unsigned i = 0; i < VE::INSTRUCTION_LIST_END; ++i) {
+    // Skip -2 (default value)
+    if (VLIndex(i) == -2)
+      continue;
+
+    const MCInstrDesc &Desc = TII->get(i);
+
+    uint64_t Flags = Desc.TSFlags;
+    ASSERT_EQ(VLIndex(i), GET_VLINDEX(Flags))
+              << MII->getName(i)
+              << ": mismatched expected VL register index in its argument\n";
+  }
+}



More information about the llvm-commits mailing list