xref: /llvm-project/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrMapsTest.cpp (revision 358d65463b215a18e731b3a5494d51e1bcbd1356)
1e902c696Svporpo //===- InstrMapsTest.cpp --------------------------------------------------===//
2e902c696Svporpo //
3e902c696Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e902c696Svporpo // See https://llvm.org/LICENSE.txt for license information.
5e902c696Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e902c696Svporpo //
7e902c696Svporpo //===----------------------------------------------------------------------===//
8e902c696Svporpo 
9e902c696Svporpo #include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
10e902c696Svporpo #include "llvm/ADT/SmallSet.h"
11e902c696Svporpo #include "llvm/AsmParser/Parser.h"
12e902c696Svporpo #include "llvm/SandboxIR/Function.h"
13e902c696Svporpo #include "llvm/SandboxIR/Instruction.h"
14e902c696Svporpo #include "llvm/Support/SourceMgr.h"
15e902c696Svporpo #include "gmock/gmock.h"
16e902c696Svporpo #include "gtest/gtest.h"
17e902c696Svporpo 
18e902c696Svporpo using namespace llvm;
19e902c696Svporpo 
20e902c696Svporpo struct InstrMapsTest : public testing::Test {
21e902c696Svporpo   LLVMContext C;
22e902c696Svporpo   std::unique_ptr<Module> M;
23e902c696Svporpo 
24e902c696Svporpo   void parseIR(LLVMContext &C, const char *IR) {
25e902c696Svporpo     SMDiagnostic Err;
26e902c696Svporpo     M = parseAssemblyString(IR, Err, C);
27e902c696Svporpo     if (!M)
28e902c696Svporpo       Err.print("InstrMapsTest", errs());
29e902c696Svporpo   }
30e902c696Svporpo };
31e902c696Svporpo 
32e902c696Svporpo TEST_F(InstrMapsTest, Basic) {
33e902c696Svporpo   parseIR(C, R"IR(
34e902c696Svporpo define void @foo(i8 %v0, i8 %v1, i8 %v2, i8 %v3, <2 x i8> %vec) {
35e902c696Svporpo   %add0 = add i8 %v0, %v0
36e902c696Svporpo   %add1 = add i8 %v1, %v1
37e902c696Svporpo   %add2 = add i8 %v2, %v2
38e902c696Svporpo   %add3 = add i8 %v3, %v3
39e902c696Svporpo   %vadd0 = add <2 x i8> %vec, %vec
40e902c696Svporpo   ret void
41e902c696Svporpo }
42e902c696Svporpo )IR");
43e902c696Svporpo   llvm::Function *LLVMF = &*M->getFunction("foo");
44e902c696Svporpo   sandboxir::Context Ctx(C);
45e902c696Svporpo   auto *F = Ctx.createFunction(LLVMF);
46e902c696Svporpo   auto *BB = &*F->begin();
47e902c696Svporpo   auto It = BB->begin();
48e902c696Svporpo 
49e902c696Svporpo   auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
50e902c696Svporpo   auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
51e902c696Svporpo   auto *Add2 = cast<sandboxir::BinaryOperator>(&*It++);
52e902c696Svporpo   auto *Add3 = cast<sandboxir::BinaryOperator>(&*It++);
53e902c696Svporpo   auto *VAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
54e902c696Svporpo   [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
55e902c696Svporpo 
56d6315affSvporpo   sandboxir::InstrMaps IMaps(Ctx);
57e902c696Svporpo   // Check with empty IMaps.
58e902c696Svporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add0), nullptr);
59e902c696Svporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add1), nullptr);
60e902c696Svporpo   EXPECT_FALSE(IMaps.getOrigLane(Add0, Add0));
61e902c696Svporpo   // Check with 1 match.
62e902c696Svporpo   IMaps.registerVector({Add0, Add1}, VAdd0);
63e902c696Svporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add0), VAdd0);
64e902c696Svporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add1), VAdd0);
65e902c696Svporpo   EXPECT_FALSE(IMaps.getOrigLane(VAdd0, VAdd0)); // Bad Orig value
66e902c696Svporpo   EXPECT_FALSE(IMaps.getOrigLane(Add0, Add0));   // Bad Vector value
6713c76178SKazu Hirata   EXPECT_EQ(*IMaps.getOrigLane(VAdd0, Add0), 0U);
6813c76178SKazu Hirata   EXPECT_EQ(*IMaps.getOrigLane(VAdd0, Add1), 1U);
69e902c696Svporpo   // Check when the same vector maps to different original values (which is
70e902c696Svporpo   // common for vector constants).
71e902c696Svporpo   IMaps.registerVector({Add2, Add3}, VAdd0);
7213c76178SKazu Hirata   EXPECT_EQ(*IMaps.getOrigLane(VAdd0, Add2), 0U);
7313c76178SKazu Hirata   EXPECT_EQ(*IMaps.getOrigLane(VAdd0, Add3), 1U);
74e902c696Svporpo   // Check when we register for a second time.
75e902c696Svporpo #ifndef NDEBUG
76e902c696Svporpo   EXPECT_DEATH(IMaps.registerVector({Add1, Add0}, VAdd0), ".*exists.*");
77e902c696Svporpo #endif // NDEBUG
78d6315affSvporpo   // Check callbacks: erase original instr.
79d6315affSvporpo   Add0->eraseFromParent();
80d6315affSvporpo   EXPECT_FALSE(IMaps.getOrigLane(VAdd0, Add0));
81*358d6546SKazu Hirata   EXPECT_EQ(*IMaps.getOrigLane(VAdd0, Add1), 1U);
82d6315affSvporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add0), nullptr);
83d6315affSvporpo   // Check callbacks: erase vector instr.
84d6315affSvporpo   VAdd0->eraseFromParent();
85d6315affSvporpo   EXPECT_FALSE(IMaps.getOrigLane(VAdd0, Add1));
86d6315affSvporpo   EXPECT_EQ(IMaps.getVectorForOrig(Add1), nullptr);
87e902c696Svporpo }
88