Skip to content

Commit 732015f

Browse files
committed
Add new file
1 parent 6507e0a commit 732015f

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
//===-- SISAbs16Fixup.cpp - Lower I1 Copies -----------------------------===//
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-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This pass matches the pattern for 16-bit ABS instructions after they have
10+
// been lowered to for execution on the Scalar Unit.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "AMDGPU.h"
15+
#include "GCNSubtarget.h"
16+
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
17+
#include "SIRegisterInfo.h"
18+
#include "llvm/CodeGen/MachineFunctionPass.h"
19+
#include "llvm/CodeGen/MachineRegisterInfo.h"
20+
#include "llvm/CodeGen/MachineSSAUpdater.h"
21+
#include "llvm/InitializePasses.h"
22+
23+
#define DEBUG_TYPE "si-abs16-pattern"
24+
25+
using namespace llvm;
26+
27+
static Register pierceCopies(Register R, MachineRegisterInfo& MRI) {
28+
MachineInstr *CopyMI = MRI.getVRegDef(R);
29+
while (CopyMI && CopyMI->getOpcode() == AMDGPU::COPY) {
30+
Register T = CopyMI->getOperand(1).getReg();
31+
if (!T.isVirtual())
32+
break;
33+
34+
R = T;
35+
CopyMI = MRI.getVRegDef(R);
36+
}
37+
38+
return R;
39+
}
40+
41+
static MachineInstr *matchExpandAbsPattern(MachineInstr &MI,
42+
MachineRegisterInfo &MRI) {
43+
std::array<MachineInstr *, 2> SextInstructions;
44+
for (unsigned I = 0; I < SextInstructions.size(); I++)
45+
{
46+
SextInstructions[I] = MRI.getVRegDef(MI.getOperand(I + 1).getReg());
47+
if (SextInstructions[I]->getOpcode() != AMDGPU::S_SEXT_I32_I16)
48+
return nullptr;
49+
}
50+
51+
Register AbsSource;
52+
MachineInstr* SubIns = nullptr;
53+
for (MachineInstr *SextMI : SextInstructions) {
54+
Register SextReg = SextMI->getOperand(1).getReg();
55+
MachineInstr* OperandMI = MRI.getVRegDef(SextReg);
56+
if (OperandMI->getOpcode() == AMDGPU::S_SUB_I32)
57+
if(!SubIns)
58+
SubIns = OperandMI;
59+
else
60+
return nullptr;
61+
else
62+
AbsSource = pierceCopies(SextReg,MRI);
63+
}
64+
65+
if (!SubIns)
66+
return nullptr;
67+
68+
if (MRI.getRegClass(AbsSource) != &AMDGPU::SGPR_32RegClass)
69+
return nullptr;
70+
71+
MachineInstr &MustBeZero =
72+
*MRI.getVRegDef(pierceCopies(SubIns->getOperand(1).getReg(), MRI));
73+
if (MustBeZero.getOpcode() != AMDGPU::S_MOV_B32 ||
74+
MustBeZero.getOperand(1).getImm())
75+
return nullptr;
76+
77+
if (pierceCopies(SubIns->getOperand(2).getReg(), MRI) != AbsSource)
78+
return nullptr;
79+
80+
return MRI.getVRegDef(AbsSource);
81+
}
82+
83+
static bool runSAbs16Fixup(MachineFunction &MF) {
84+
MachineRegisterInfo &MRI = MF.getRegInfo();
85+
const SIInstrInfo &TII = *MF.getSubtarget<GCNSubtarget>().getInstrInfo();
86+
87+
bool Changed = false;
88+
89+
for (MachineBasicBlock &MBB : MF)
90+
for (MachineInstr &MI : make_early_inc_range(MBB)) {
91+
bool IsPositive = MI.getOpcode() == AMDGPU::S_MAX_I32;
92+
bool IsNegative = MI.getOpcode() == AMDGPU::S_MIN_I32;
93+
MachineInstr* AbsSourceMI;
94+
if ((!IsPositive && !IsNegative) ||
95+
!(AbsSourceMI = matchExpandAbsPattern(MI, MRI)))
96+
continue;
97+
98+
Register SextDestReg =
99+
MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
100+
Register AbsDestReg =
101+
IsNegative ? MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass)
102+
: MI.getOperand(0).getReg();
103+
104+
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_SEXT_I32_I16),
105+
SextDestReg)
106+
.addReg(AbsSourceMI->getOperand(0).getReg());
107+
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_ABS_I32), AbsDestReg)
108+
.addReg(SextDestReg);
109+
110+
if(IsNegative)
111+
BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_SUB_I32),
112+
MI.getOperand(0).getReg())
113+
.addImm(0)
114+
.addReg(AbsDestReg);
115+
116+
MI.eraseFromParent();
117+
Changed = true;
118+
}
119+
120+
return Changed;
121+
}
122+
123+
PreservedAnalyses SISAbs16FixupPass::run(MachineFunction &MF,
124+
MachineFunctionAnalysisManager &MFAM) {
125+
bool Changed = runSAbs16Fixup(MF);
126+
if (!Changed)
127+
return PreservedAnalyses::all();
128+
129+
// TODO: Probably preserves most.
130+
PreservedAnalyses PA;
131+
PA.preserveSet<CFGAnalyses>();
132+
return PA;
133+
}
134+
135+
class SISAbs16FixupLegacy : public MachineFunctionPass {
136+
public:
137+
static char ID;
138+
139+
SISAbs16FixupLegacy() : MachineFunctionPass(ID) {
140+
initializeSISAbs16FixupLegacyPass(*PassRegistry::getPassRegistry());
141+
}
142+
143+
bool runOnMachineFunction(MachineFunction &MF) override;
144+
145+
StringRef getPassName() const override { return "SI SAbs16 Fixup"; }
146+
147+
void getAnalysisUsage(AnalysisUsage &AU) const override {
148+
AU.setPreservesCFG();
149+
MachineFunctionPass::getAnalysisUsage(AU);
150+
}
151+
};
152+
153+
bool SISAbs16FixupLegacy::runOnMachineFunction(MachineFunction &MF) {
154+
return runSAbs16Fixup(MF);
155+
}
156+
157+
INITIALIZE_PASS_BEGIN(SISAbs16FixupLegacy, DEBUG_TYPE, "SI SAbs16 Fixup",
158+
false, false)
159+
INITIALIZE_PASS_END(SISAbs16FixupLegacy, DEBUG_TYPE, "SI SAbs16 Fixup",
160+
false, false)
161+
162+
char SISAbs16FixupLegacy::ID = 0;
163+
164+
char &llvm::SISAbs16FixupLegacyID = SISAbs16FixupLegacy::ID;
165+
166+
FunctionPass *llvm::createSISAbs16FixupLegacyPass() {
167+
return new SISAbs16FixupLegacy();
168+
}

0 commit comments

Comments
 (0)