100255f41Svpykhtin //===- llvm/unittests/Target/AMDGPU/ExecMayBeModifiedBeforeAnyUse.cpp -----===//
200255f41Svpykhtin //
300255f41Svpykhtin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
400255f41Svpykhtin // See https://llvm.org/LICENSE.txt for license information.
500255f41Svpykhtin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
600255f41Svpykhtin //
700255f41Svpykhtin //===----------------------------------------------------------------------===//
800255f41Svpykhtin 
900255f41Svpykhtin #include "AMDGPUTargetMachine.h"
10560d7e04Sdfukalov #include "GCNSubtarget.h"
11560d7e04Sdfukalov #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
1200255f41Svpykhtin #include "llvm/CodeGen/MachineModuleInfo.h"
1300255f41Svpykhtin #include "llvm/CodeGen/TargetSubtargetInfo.h"
1400255f41Svpykhtin #include "llvm/MC/MCTargetOptions.h"
15*89b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
1600255f41Svpykhtin #include "llvm/Support/TargetSelect.h"
1700255f41Svpykhtin #include "llvm/Target/TargetMachine.h"
1800255f41Svpykhtin #include "gtest/gtest.h"
1900255f41Svpykhtin #include <thread>
2000255f41Svpykhtin 
2100255f41Svpykhtin using namespace llvm;
2200255f41Svpykhtin 
2300255f41Svpykhtin // implementation is in the llvm/unittests/Target/AMDGPU/DwarfRegMappings.cpp
2400255f41Svpykhtin std::unique_ptr<const GCNTargetMachine>
2500255f41Svpykhtin createTargetMachine(std::string TStr, StringRef CPU, StringRef FS);
2600255f41Svpykhtin 
TEST(AMDGPUExecMayBeModifiedBeforeAnyUse,TheTest)2700255f41Svpykhtin TEST(AMDGPUExecMayBeModifiedBeforeAnyUse, TheTest) {
2800255f41Svpykhtin   auto TM = createTargetMachine("amdgcn-amd-", "gfx906", "");
2900255f41Svpykhtin   if (!TM)
3000255f41Svpykhtin     return;
3100255f41Svpykhtin 
3200255f41Svpykhtin   GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
3300255f41Svpykhtin                   std::string(TM->getTargetFeatureString()), *TM);
3400255f41Svpykhtin 
3500255f41Svpykhtin   LLVMContext Ctx;
3600255f41Svpykhtin   Module Mod("Module", Ctx);
3700255f41Svpykhtin   Mod.setDataLayout(TM->createDataLayout());
3800255f41Svpykhtin 
3900255f41Svpykhtin   auto *Type = FunctionType::get(Type::getVoidTy(Ctx), false);
4000255f41Svpykhtin   auto *F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &Mod);
4100255f41Svpykhtin 
4200255f41Svpykhtin   MachineModuleInfo MMI(TM.get());
4300255f41Svpykhtin   auto MF = std::make_unique<MachineFunction>(*F, *TM, ST, 42, MMI);
4400255f41Svpykhtin   auto *BB = MF->CreateMachineBasicBlock();
4500255f41Svpykhtin   MF->push_back(BB);
4600255f41Svpykhtin 
4700255f41Svpykhtin   auto E = BB->end();
4800255f41Svpykhtin   DebugLoc DL;
4900255f41Svpykhtin   const auto &TII = *ST.getInstrInfo();
5000255f41Svpykhtin   auto &MRI = MF->getRegInfo();
5100255f41Svpykhtin 
5200255f41Svpykhtin   // create machine IR
5300255f41Svpykhtin   Register R = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
5400255f41Svpykhtin 
5500255f41Svpykhtin   MachineInstr *DefMI =
5600255f41Svpykhtin       BuildMI(*BB, E, DL, TII.get(AMDGPU::S_MOV_B32), R).addImm(42).getInstr();
5700255f41Svpykhtin 
5800255f41Svpykhtin   auto First =
5900255f41Svpykhtin       BuildMI(*BB, E, DL, TII.get(AMDGPU::S_NOP)).addReg(R, RegState::Implicit);
6000255f41Svpykhtin 
6100255f41Svpykhtin   BuildMI(*BB, E, DL, TII.get(AMDGPU::S_NOP)).addReg(R, RegState::Implicit);
6200255f41Svpykhtin 
6300255f41Svpykhtin   // this violates the continuous sequence of R's uses for the first S_NOP
6400255f41Svpykhtin   First.addReg(R, RegState::Implicit);
6500255f41Svpykhtin 
6600255f41Svpykhtin #ifdef DEBUG_THIS_TEST
6700255f41Svpykhtin   MF->dump();
6800255f41Svpykhtin   MRI.dumpUses(R);
6900255f41Svpykhtin #endif
7000255f41Svpykhtin 
7100255f41Svpykhtin   // make sure execMayBeModifiedBeforeAnyUse doesn't crash
7200255f41Svpykhtin   ASSERT_FALSE(execMayBeModifiedBeforeAnyUse(MRI, R, *DefMI));
7300255f41Svpykhtin }
74