brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 95266dc Raw
161 lines · cpp
1//===--------- llvm/unittests/Target/AMDGPU/LiveRegUnits.cpp --------------===//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 "AMDGPUTargetMachine.h"10#include "AMDGPUUnitTests.h"11#include "GCNSubtarget.h"12#include "llvm/CodeGen/MIRParser/MIRParser.h"13#include "llvm/CodeGen/MachineModuleInfo.h"14#include "llvm/MC/TargetRegistry.h"15#include "llvm/Support/SourceMgr.h"16#include "llvm/Support/TargetSelect.h"17#include "llvm/TargetParser/TargetParser.h"18#include "gtest/gtest.h"19 20#include "AMDGPUGenSubtargetInfo.inc"21 22using namespace llvm;23 24// FIXME: Consolidate parseMIR and other common helpers (this one is copied from25// unittests/MIR/MachineMetadata.cpp).26std::unique_ptr<Module> parseMIR(LLVMContext &Context, const TargetMachine &TM,27                                 StringRef MIRCode, const char *FnName,28                                 MachineModuleInfo &MMI) {29  SMDiagnostic Diagnostic;30  std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);31  auto MIR = createMIRParser(std::move(MBuffer), Context);32  if (!MIR)33    return nullptr;34 35  std::unique_ptr<Module> Mod = MIR->parseIRModule();36  if (!Mod)37    return nullptr;38 39  Mod->setDataLayout(TM.createDataLayout());40 41  if (MIR->parseMachineFunctions(*Mod, MMI)) {42    return nullptr;43  }44 45  return Mod;46}47 48TEST(AMDGPULiveRegUnits, TestVGPRBlockLoadStore) {49  auto TM = createAMDGPUTargetMachine("amdgcn-amd-", "gfx1200", "");50  ASSERT_TRUE(TM) << "No target machine";51 52  GCNSubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),53                  std::string(TM->getTargetFeatureString()), *TM);54 55  // Add a very simple MIR snippet that saves and restores a block of VGPRs. The56  // body of the function, represented by a S_NOP, clobbers one CSR (v42) and57  // one caller-saved register (v49), and reads one CSR (v61) and one58  // callee-saved register (v53).59  StringRef MIRString = R"MIR(60name:            vgpr-block-insts61stack:62- { id: 0, name: '', type: spill-slot, offset: 0, size: 16, alignment: 4,63    stack-id: default, callee-saved-register: '$vgpr40_vgpr41_vgpr42_vgpr43_vgpr44_vgpr45_vgpr46_vgpr47_vgpr48_vgpr49_vgpr50_vgpr51_vgpr52_vgpr53_vgpr54_vgpr55_vgpr56_vgpr57_vgpr58_vgpr59_vgpr60_vgpr61_vgpr62_vgpr63_vgpr64_vgpr65_vgpr66_vgpr67_vgpr68_vgpr69_vgpr70_vgpr71',64    callee-saved-restored: true, debug-info-variable: '', debug-info-expression: '',65    debug-info-location: '' }66body:             |67  bb.0:68    liveins: $sgpr30_sgpr31, $vgpr42_vgpr43_vgpr44_vgpr45_vgpr46_vgpr47_vgpr48_vgpr49_vgpr50_vgpr51_vgpr52_vgpr53_vgpr54_vgpr55_vgpr56_vgpr57_vgpr58_vgpr59_vgpr60_vgpr61_vgpr62_vgpr63_vgpr64_vgpr65_vgpr66_vgpr67_vgpr68_vgpr69_vgpr70_vgpr71_vgpr72_vgpr7369 70    $m0 = S_MOV_B32 171    SCRATCH_STORE_BLOCK_SADDR $vgpr42_vgpr43_vgpr44_vgpr45_vgpr46_vgpr47_vgpr48_vgpr49_vgpr50_vgpr51_vgpr52_vgpr53_vgpr54_vgpr55_vgpr56_vgpr57_vgpr58_vgpr59_vgpr60_vgpr61_vgpr62_vgpr63_vgpr64_vgpr65_vgpr66_vgpr67_vgpr68_vgpr69_vgpr70_vgpr71_vgpr72_vgpr73, $sgpr32, 0, 0, implicit $exec, implicit $flat_scr, implicit $m0 :: (store (s1024) into %stack.0, align 4, addrspace 5)72    S_NOP 0, implicit-def $vgpr42, implicit-def $vgpr49, implicit $vgpr53, implicit $vgpr6173    $m0 = S_MOV_B32 174   $vgpr42_vgpr43_vgpr44_vgpr45_vgpr46_vgpr47_vgpr48_vgpr49_vgpr50_vgpr51_vgpr52_vgpr53_vgpr54_vgpr55_vgpr56_vgpr57_vgpr58_vgpr59_vgpr60_vgpr61_vgpr62_vgpr63_vgpr64_vgpr65_vgpr66_vgpr67_vgpr68_vgpr69_vgpr70_vgpr71_vgpr72_vgpr73 = SCRATCH_LOAD_BLOCK_SADDR $sgpr32, 0, 0, implicit $exec, implicit $flat_scr, implicit $m0, implicit $vgpr43, implicit $vgpr44, implicit $vgpr45, implicit $vgpr46, implicit $vgpr47, implicit $vgpr56, implicit $vgpr57, implicit $vgpr58, implicit $vgpr59, implicit $vgpr60, implicit $vgpr61, implicit $vgpr62, implicit $vgpr63, implicit $vgpr72, implicit $vgpr73 :: (load (s1024) from %stack.0, align 4, addrspace 5)75    S_SETPC_B64_return $sgpr30_sgpr3176...77)MIR";78 79  LLVMContext Context;80  MachineModuleInfo MMI(TM.get());81  auto M = parseMIR(Context, *TM, MIRString, "vgpr-block-insts", MMI);82 83  auto *MF = MMI.getMachineFunction(*M->getFunction("vgpr-block-insts"));84  auto *MBB = MF->getBlockNumbered(0);85 86  auto MIt = --MBB->instr_end();87 88  LiveRegUnits LiveUnits;89  LiveUnits.init(*ST.getRegisterInfo());90 91  LiveUnits.addLiveOuts(*MBB);92  LiveUnits.stepBackward(*MIt);93 94  // Right after the restore, we expect all the CSRs to be unavailable.95  // Check v40-v88 (callee and caller saved regs interleaved in blocks of 8).96  for (unsigned I = 0; I < 8; ++I) {97    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;98    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR48 + I)) << "I = " << I;99    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR56 + I)) << "I = " << I;100    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR64 + I)) << "I = " << I;101    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR72 + I)) << "I = " << I;102    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR80 + I)) << "I = " << I;103  }104 105  --MIt;106  LiveUnits.stepBackward(*MIt);107 108  // Right before the restore, we expect the CSRs that are actually transferred109  // (in this case v42) to be available. Everything else should be the same as110  // before.111  for (unsigned I = 0; I < 8; ++I) {112    if (I == 2)113      EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;114    else115      EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;116    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR48 + I)) << "I = " << I;117    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR56 + I)) << "I = " << I;118    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR64 + I)) << "I = " << I;119    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR72 + I)) << "I = " << I;120    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR80 + I)) << "I = " << I;121  }122 123  --MIt; // Set m0 has no effect on VGPRs.124  LiveUnits.stepBackward(*MIt);125  --MIt; // S_NOP.126  LiveUnits.stepBackward(*MIt);127 128  // The S_NOP uses one of the caller-saved registers (v53), so that won't be129  // available anymore.130  for (unsigned I = 0; I < 8; ++I) {131    if (I == 2)132      EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;133    else134      EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;135    if (I == 5)136      EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR48 + I)) << "I = " << I;137    else138      EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR48 + I)) << "I = " << I;139    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR56 + I)) << "I = " << I;140    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR64 + I)) << "I = " << I;141    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR72 + I)) << "I = " << I;142    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR80 + I)) << "I = " << I;143  }144 145  --MIt;146  LiveUnits.stepBackward(*MIt);147 148  // Right before the save, all the VGPRs in the block that we're saving will be149  // unavailable, regardless of whether they're callee or caller saved. This is150  // unfortunate and should probably be fixed somehow.151  // VGPRs outside the block will only be unavailable if they're callee saved.152  for (unsigned I = 0; I < 8; ++I) {153    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR40 + I)) << "I = " << I;154    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR48 + I)) << "I = " << I;155    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR56 + I)) << "I = " << I;156    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR64 + I)) << "I = " << I;157    EXPECT_FALSE(LiveUnits.available(AMDGPU::VGPR72 + I)) << "I = " << I;158    EXPECT_TRUE(LiveUnits.available(AMDGPU::VGPR80 + I)) << "I = " << I;159  }160}161