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