125 lines · cpp
1//===-- SnippetGeneratorTest.cpp --------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../Common/AssemblerUtils.h"10#include "LlvmState.h"11#include "MCInstrDescView.h"12#include "MipsInstrInfo.h"13#include "ParallelSnippetGenerator.h"14#include "RegisterAliasing.h"15#include "SerialSnippetGenerator.h"16#include "TestBase.h"17 18namespace llvm {19namespace exegesis {20namespace {21 22using testing::AnyOf;23using testing::ElementsAre;24using testing::HasSubstr;25using testing::SizeIs;26 27MATCHER(IsInvalid, "") { return !arg.isValid(); }28MATCHER(IsReg, "") { return arg.isReg(); }29 30template <typename SnippetGeneratorT>31class MipsSnippetGeneratorTest : public MipsTestBase {32protected:33 MipsSnippetGeneratorTest() : Generator(State, SnippetGenerator::Options()) {}34 35 std::vector<CodeTemplate> checkAndGetCodeTemplates(unsigned Opcode) {36 randomGenerator().seed(0); // Initialize seed.37 const Instruction &Instr = State.getIC().getInstr(Opcode);38 auto CodeTemplateOrError = Generator.generateCodeTemplates(39 &Instr, State.getRATC().emptyRegisters());40 EXPECT_FALSE(CodeTemplateOrError.takeError()); // Valid configuration.41 return std::move(CodeTemplateOrError.get());42 }43 44 SnippetGeneratorT Generator;45};46 47using MipsSerialSnippetGeneratorTest = MipsSnippetGeneratorTest<SerialSnippetGenerator>;48 49using MipsParallelSnippetGeneratorTest =50 MipsSnippetGeneratorTest<ParallelSnippetGenerator>;51 52TEST_F(MipsSerialSnippetGeneratorTest, ImplicitSelfDependencyThroughExplicitRegs) {53 // - ADD54 // - Op0 Explicit Def RegClass(GPR32)55 // - Op1 Explicit Use RegClass(GPR32)56 // - Op2 Explicit Use RegClass(GPR32)57 // - Var0 [Op0]58 // - Var1 [Op1]59 // - Var2 [Op2]60 // - hasAliasingRegisters61 const unsigned Opcode = Mips::ADD;62 const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);63 ASSERT_THAT(CodeTemplates, SizeIs(1));64 const auto &CT = CodeTemplates[0];65 EXPECT_THAT(CT.Execution, ExecutionMode::SERIAL_VIA_EXPLICIT_REGS);66 ASSERT_THAT(CT.Instructions, SizeIs(1));67 const InstructionTemplate &IT = CT.Instructions[0];68 EXPECT_THAT(IT.getOpcode(), Opcode);69 ASSERT_THAT(IT.getVariableValues(), SizeIs(3));70 EXPECT_THAT(IT.getVariableValues(),71 AnyOf(ElementsAre(IsReg(), IsInvalid(), IsReg()),72 ElementsAre(IsReg(), IsReg(), IsInvalid())))73 << "Op0 is either set to Op1 or to Op2";74}75 76TEST_F(MipsSerialSnippetGeneratorTest,77 ImplicitSelfDependencyThroughExplicitRegsForbidAll) {78 // - XOR79 // - Op0 Explicit Def RegClass(GPR32)80 // - Op1 Explicit Use RegClass(GPR32)81 // - Op2 Explicit Use RegClass(GPR32)82 // - Var0 [Op0]83 // - Var1 [Op1]84 // - Var2 [Op2]85 // - hasAliasingRegisters86 randomGenerator().seed(0); // Initialize seed.87 const Instruction &Instr = State.getIC().getInstr(Mips::XOR);88 auto AllRegisters = State.getRATC().emptyRegisters();89 AllRegisters.flip();90 auto Error =91 Generator.generateCodeTemplates(&Instr, AllRegisters).takeError();92 EXPECT_TRUE((bool)Error);93 consumeError(std::move(Error));94}95 96TEST_F(MipsParallelSnippetGeneratorTest, MemoryUse) {97 // LB reads from memory.98 // - LB99 // - Op0 Explicit Def RegClass(GPR32)100 // - Op1 Explicit Use Memory RegClass(MSA128F16)101 // - Op2 Explicit Use Memory102 // - Var0 [Op0]103 // - Var1 [Op1]104 // - Var2 [Op2]105 // - hasMemoryOperands106 const unsigned Opcode = Mips::LB;107 const auto CodeTemplates = checkAndGetCodeTemplates(Opcode);108 ASSERT_THAT(CodeTemplates, SizeIs(1));109 const auto &CT = CodeTemplates[0];110 EXPECT_THAT(CT.Info,111 HasSubstr("instruction is parallel, repeating a random one."));112 EXPECT_THAT(CT.Execution, ExecutionMode::UNKNOWN);113 ASSERT_THAT(CT.Instructions,114 SizeIs(ParallelSnippetGenerator::kMinNumDifferentAddresses));115 const InstructionTemplate &IT = CT.Instructions[0];116 EXPECT_THAT(IT.getOpcode(), Opcode);117 ASSERT_THAT(IT.getVariableValues(), SizeIs(3));118 EXPECT_EQ(IT.getVariableValues()[0].getReg(), 0u);119 EXPECT_EQ(IT.getVariableValues()[2].getImm(), 0);120}121 122} // namespace123} // namespace exegesis124} // namespace llvm125