xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SILowerI1Copies.cpp - Lower I1 Copies -----------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker /// i1 values are usually inserted by the CFG Structurize pass and they are
9*9880d681SAndroid Build Coastguard Worker /// unique in that they can be copied from VALU to SALU registers.
10*9880d681SAndroid Build Coastguard Worker /// This is not possible for any other value type.  Since there are no
11*9880d681SAndroid Build Coastguard Worker /// MOV instructions for i1, we to use V_CMP_* and V_CNDMASK to move the i1.
12*9880d681SAndroid Build Coastguard Worker ///
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "si-i1-copies"
17*9880d681SAndroid Build Coastguard Worker #include "AMDGPU.h"
18*9880d681SAndroid Build Coastguard Worker #include "AMDGPUSubtarget.h"
19*9880d681SAndroid Build Coastguard Worker #include "SIInstrInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/LiveIntervalAnalysis.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker using namespace llvm;
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker namespace {
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker class SILowerI1Copies : public MachineFunctionPass {
34*9880d681SAndroid Build Coastguard Worker public:
35*9880d681SAndroid Build Coastguard Worker   static char ID;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker public:
SILowerI1Copies()38*9880d681SAndroid Build Coastguard Worker   SILowerI1Copies() : MachineFunctionPass(ID) {
39*9880d681SAndroid Build Coastguard Worker     initializeSILowerI1CopiesPass(*PassRegistry::getPassRegistry());
40*9880d681SAndroid Build Coastguard Worker   }
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker   bool runOnMachineFunction(MachineFunction &MF) override;
43*9880d681SAndroid Build Coastguard Worker 
getPassName() const44*9880d681SAndroid Build Coastguard Worker   const char *getPassName() const override {
45*9880d681SAndroid Build Coastguard Worker     return "SI Lower i1 Copies";
46*9880d681SAndroid Build Coastguard Worker   }
47*9880d681SAndroid Build Coastguard Worker 
getAnalysisUsage(AnalysisUsage & AU) const48*9880d681SAndroid Build Coastguard Worker   void getAnalysisUsage(AnalysisUsage &AU) const override {
49*9880d681SAndroid Build Coastguard Worker     AU.setPreservesCFG();
50*9880d681SAndroid Build Coastguard Worker     MachineFunctionPass::getAnalysisUsage(AU);
51*9880d681SAndroid Build Coastguard Worker   }
52*9880d681SAndroid Build Coastguard Worker };
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker } // End anonymous namespace.
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(SILowerI1Copies, DEBUG_TYPE,
57*9880d681SAndroid Build Coastguard Worker                 "SI Lower i1 Copies", false, false)
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker char SILowerI1Copies::ID = 0;
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker char &llvm::SILowerI1CopiesID = SILowerI1Copies::ID;
62*9880d681SAndroid Build Coastguard Worker 
createSILowerI1CopiesPass()63*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createSILowerI1CopiesPass() {
64*9880d681SAndroid Build Coastguard Worker   return new SILowerI1Copies();
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)67*9880d681SAndroid Build Coastguard Worker bool SILowerI1Copies::runOnMachineFunction(MachineFunction &MF) {
68*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF.getRegInfo();
69*9880d681SAndroid Build Coastguard Worker   const SISubtarget &ST = MF.getSubtarget<SISubtarget>();
70*9880d681SAndroid Build Coastguard Worker   const SIInstrInfo *TII = ST.getInstrInfo();
71*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI = &TII->getRegisterInfo();
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker   std::vector<unsigned> I1Defs;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker   for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
76*9880d681SAndroid Build Coastguard Worker                                                   BI != BE; ++BI) {
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB = *BI;
79*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator I, Next;
80*9880d681SAndroid Build Coastguard Worker     for (I = MBB.begin(); I != MBB.end(); I = Next) {
81*9880d681SAndroid Build Coastguard Worker       Next = std::next(I);
82*9880d681SAndroid Build Coastguard Worker       MachineInstr &MI = *I;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker       if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF) {
85*9880d681SAndroid Build Coastguard Worker         unsigned Reg = MI.getOperand(0).getReg();
86*9880d681SAndroid Build Coastguard Worker         const TargetRegisterClass *RC = MRI.getRegClass(Reg);
87*9880d681SAndroid Build Coastguard Worker         if (RC == &AMDGPU::VReg_1RegClass)
88*9880d681SAndroid Build Coastguard Worker           MRI.setRegClass(Reg, &AMDGPU::SReg_64RegClass);
89*9880d681SAndroid Build Coastguard Worker         continue;
90*9880d681SAndroid Build Coastguard Worker       }
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker       if (MI.getOpcode() != AMDGPU::COPY)
93*9880d681SAndroid Build Coastguard Worker         continue;
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Dst = MI.getOperand(0);
96*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Src = MI.getOperand(1);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker       if (!TargetRegisterInfo::isVirtualRegister(Src.getReg()) ||
99*9880d681SAndroid Build Coastguard Worker           !TargetRegisterInfo::isVirtualRegister(Dst.getReg()))
100*9880d681SAndroid Build Coastguard Worker         continue;
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *DstRC = MRI.getRegClass(Dst.getReg());
103*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *SrcRC = MRI.getRegClass(Src.getReg());
104*9880d681SAndroid Build Coastguard Worker 
105*9880d681SAndroid Build Coastguard Worker       if (DstRC == &AMDGPU::VReg_1RegClass &&
106*9880d681SAndroid Build Coastguard Worker           TRI->getCommonSubClass(SrcRC, &AMDGPU::SGPR_64RegClass)) {
107*9880d681SAndroid Build Coastguard Worker         I1Defs.push_back(Dst.getReg());
108*9880d681SAndroid Build Coastguard Worker         DebugLoc DL = MI.getDebugLoc();
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker         MachineInstr *DefInst = MRI.getUniqueVRegDef(Src.getReg());
111*9880d681SAndroid Build Coastguard Worker         if (DefInst->getOpcode() == AMDGPU::S_MOV_B64) {
112*9880d681SAndroid Build Coastguard Worker           if (DefInst->getOperand(1).isImm()) {
113*9880d681SAndroid Build Coastguard Worker             I1Defs.push_back(Dst.getReg());
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker             int64_t Val = DefInst->getOperand(1).getImm();
116*9880d681SAndroid Build Coastguard Worker             assert(Val == 0 || Val == -1);
117*9880d681SAndroid Build Coastguard Worker 
118*9880d681SAndroid Build Coastguard Worker             BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_MOV_B32_e32))
119*9880d681SAndroid Build Coastguard Worker               .addOperand(Dst)
120*9880d681SAndroid Build Coastguard Worker               .addImm(Val);
121*9880d681SAndroid Build Coastguard Worker             MI.eraseFromParent();
122*9880d681SAndroid Build Coastguard Worker             continue;
123*9880d681SAndroid Build Coastguard Worker           }
124*9880d681SAndroid Build Coastguard Worker         }
125*9880d681SAndroid Build Coastguard Worker 
126*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, &MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64))
127*9880d681SAndroid Build Coastguard Worker           .addOperand(Dst)
128*9880d681SAndroid Build Coastguard Worker           .addImm(0)
129*9880d681SAndroid Build Coastguard Worker           .addImm(-1)
130*9880d681SAndroid Build Coastguard Worker           .addOperand(Src);
131*9880d681SAndroid Build Coastguard Worker         MI.eraseFromParent();
132*9880d681SAndroid Build Coastguard Worker       } else if (TRI->getCommonSubClass(DstRC, &AMDGPU::SGPR_64RegClass) &&
133*9880d681SAndroid Build Coastguard Worker                  SrcRC == &AMDGPU::VReg_1RegClass) {
134*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, &MI, MI.getDebugLoc(), TII->get(AMDGPU::V_CMP_NE_I32_e64))
135*9880d681SAndroid Build Coastguard Worker           .addOperand(Dst)
136*9880d681SAndroid Build Coastguard Worker           .addOperand(Src)
137*9880d681SAndroid Build Coastguard Worker           .addImm(0);
138*9880d681SAndroid Build Coastguard Worker         MI.eraseFromParent();
139*9880d681SAndroid Build Coastguard Worker       }
140*9880d681SAndroid Build Coastguard Worker     }
141*9880d681SAndroid Build Coastguard Worker   }
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   for (unsigned Reg : I1Defs)
144*9880d681SAndroid Build Coastguard Worker     MRI.setRegClass(Reg, &AMDGPU::VGPR_32RegClass);
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   return false;
147*9880d681SAndroid Build Coastguard Worker }
148