xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp (revision 71ac745d76c3ba442e753daff1870893f272b29d)
10b57cec5SDimitry Andric //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines an instruction selector for the MIPS target.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "MipsISelDAGToDAG.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/MipsBaseInfo.h"
150b57cec5SDimitry Andric #include "Mips.h"
160b57cec5SDimitry Andric #include "Mips16ISelDAGToDAG.h"
170b57cec5SDimitry Andric #include "MipsMachineFunction.h"
180b57cec5SDimitry Andric #include "MipsRegisterInfo.h"
190b57cec5SDimitry Andric #include "MipsSEISelDAGToDAG.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
25647cbc5dSDimitry Andric #include "llvm/CodeGen/SelectionDAG.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAGNodes.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/StackProtector.h"
280b57cec5SDimitry Andric #include "llvm/IR/CFG.h"
290b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
300b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
310b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
320b57cec5SDimitry Andric #include "llvm/IR/Type.h"
330b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
340b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
35647cbc5dSDimitry Andric #include "llvm/Support/KnownBits.h"
360b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
370b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
380b57cec5SDimitry Andric using namespace llvm;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric #define DEBUG_TYPE "mips-isel"
41bdd1243dSDimitry Andric #define PASS_NAME "MIPS DAG->DAG Pattern Instruction Selection"
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
440b57cec5SDimitry Andric // Instruction Selector Implementation
450b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
480b57cec5SDimitry Andric // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
490b57cec5SDimitry Andric // instructions for SelectionDAG operations.
500b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
510b57cec5SDimitry Andric 
520fca6ea1SDimitry Andric void MipsDAGToDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
530b57cec5SDimitry Andric   // There are multiple MipsDAGToDAGISel instances added to the pass pipeline.
540b57cec5SDimitry Andric   // We need to preserve StackProtector for the next one.
550b57cec5SDimitry Andric   AU.addPreserved<StackProtector>();
560fca6ea1SDimitry Andric   SelectionDAGISelLegacy::getAnalysisUsage(AU);
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
6081ad6265SDimitry Andric   Subtarget = &MF.getSubtarget<MipsSubtarget>();
610b57cec5SDimitry Andric   bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   processFunctionAfterISel(MF);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   return Ret;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric /// getGlobalBaseReg - Output the instructions required to put the
690b57cec5SDimitry Andric /// GOT address into a register.
700b57cec5SDimitry Andric SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
715ffd83dbSDimitry Andric   Register GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(*MF);
720b57cec5SDimitry Andric   return CurDAG->getRegister(GlobalBaseReg, getTargetLowering()->getPointerTy(
730b57cec5SDimitry Andric                                                 CurDAG->getDataLayout()))
740b57cec5SDimitry Andric       .getNode();
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric /// ComplexPattern used on MipsInstrInfo
780b57cec5SDimitry Andric /// Used on Mips Load/Store instructions
790b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
800b57cec5SDimitry Andric                                         SDValue &Offset) const {
810b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
820b57cec5SDimitry Andric   return false;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
860b57cec5SDimitry Andric                                          SDValue &Offset) const {
870b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
880b57cec5SDimitry Andric   return false;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
920b57cec5SDimitry Andric                                      SDValue &Offset) const {
930b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
940b57cec5SDimitry Andric   return false;
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,
980b57cec5SDimitry Andric                                        SDValue &Offset) const {
990b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1000b57cec5SDimitry Andric   return false;
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,
1040b57cec5SDimitry Andric                                        SDValue &Offset) const {
1050b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1060b57cec5SDimitry Andric   return false;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,
1100b57cec5SDimitry Andric                                        SDValue &Offset) const {
1110b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1120b57cec5SDimitry Andric   return false;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
1160b57cec5SDimitry Andric                                            SDValue &Offset) const {
1170b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1180b57cec5SDimitry Andric   return false;
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,
1220b57cec5SDimitry Andric                                            SDValue &Offset) const {
1230b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1240b57cec5SDimitry Andric   return false;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,
1280b57cec5SDimitry Andric                                                SDValue &Offset) const {
1290b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1300b57cec5SDimitry Andric   return false;
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,
1340b57cec5SDimitry Andric                                                SDValue &Offset) const {
1350b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1360b57cec5SDimitry Andric   return false;
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,
1400b57cec5SDimitry Andric                                                SDValue &Offset) const {
1410b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1420b57cec5SDimitry Andric   return false;
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddr16(SDValue Addr, SDValue &Base,
1460b57cec5SDimitry Andric                                     SDValue &Offset) {
1470b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1480b57cec5SDimitry Andric   return false;
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectAddr16SP(SDValue Addr, SDValue &Base,
1520b57cec5SDimitry Andric                                       SDValue &Offset) {
1530b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1540b57cec5SDimitry Andric   return false;
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,
1580b57cec5SDimitry Andric                                     unsigned MinSizeInBits) const {
1590b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1600b57cec5SDimitry Andric   return false;
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
1640b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1650b57cec5SDimitry Andric   return false;
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
1690b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1700b57cec5SDimitry Andric   return false;
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
1740b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1750b57cec5SDimitry Andric   return false;
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
1790b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1800b57cec5SDimitry Andric   return false;
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
1840b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1850b57cec5SDimitry Andric   return false;
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
1890b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1900b57cec5SDimitry Andric   return false;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
1940b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
1950b57cec5SDimitry Andric   return false;
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
1990b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
2000b57cec5SDimitry Andric   return false;
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
2040b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
2050b57cec5SDimitry Andric   return false;
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
2090b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
2100b57cec5SDimitry Andric   return false;
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
2140b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
2150b57cec5SDimitry Andric   return false;
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
2190b57cec5SDimitry Andric   llvm_unreachable("Unimplemented function.");
2200b57cec5SDimitry Andric   return false;
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric 
223*71ac745dSDimitry Andric bool MipsDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {
224*71ac745dSDimitry Andric   llvm_unreachable("Unimplemented function.");
225*71ac745dSDimitry Andric }
226*71ac745dSDimitry Andric 
2278bcb0991SDimitry Andric /// Convert vector addition with vector subtraction if that allows to encode
2288bcb0991SDimitry Andric /// constant as an immediate and thus avoid extra 'ldi' instruction.
2298bcb0991SDimitry Andric /// add X, <-1, -1...> --> sub X, <1, 1...>
2308bcb0991SDimitry Andric bool MipsDAGToDAGISel::selectVecAddAsVecSubIfProfitable(SDNode *Node) {
2318bcb0991SDimitry Andric   assert(Node->getOpcode() == ISD::ADD && "Should only get 'add' here.");
2328bcb0991SDimitry Andric 
2338bcb0991SDimitry Andric   EVT VT = Node->getValueType(0);
2348bcb0991SDimitry Andric   assert(VT.isVector() && "Should only be called for vectors.");
2358bcb0991SDimitry Andric 
2368bcb0991SDimitry Andric   SDValue X = Node->getOperand(0);
2378bcb0991SDimitry Andric   SDValue C = Node->getOperand(1);
2388bcb0991SDimitry Andric 
2398bcb0991SDimitry Andric   auto *BVN = dyn_cast<BuildVectorSDNode>(C);
2408bcb0991SDimitry Andric   if (!BVN)
2418bcb0991SDimitry Andric     return false;
2428bcb0991SDimitry Andric 
2438bcb0991SDimitry Andric   APInt SplatValue, SplatUndef;
2448bcb0991SDimitry Andric   unsigned SplatBitSize;
2458bcb0991SDimitry Andric   bool HasAnyUndefs;
2468bcb0991SDimitry Andric 
2478bcb0991SDimitry Andric   if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,
2488bcb0991SDimitry Andric                             8, !Subtarget->isLittle()))
2498bcb0991SDimitry Andric     return false;
2508bcb0991SDimitry Andric 
2518bcb0991SDimitry Andric   auto IsInlineConstant = [](const APInt &Imm) { return Imm.isIntN(5); };
2528bcb0991SDimitry Andric 
2538bcb0991SDimitry Andric   if (IsInlineConstant(SplatValue))
2548bcb0991SDimitry Andric     return false; // Can already be encoded as an immediate.
2558bcb0991SDimitry Andric 
2568bcb0991SDimitry Andric   APInt NegSplatValue = 0 - SplatValue;
2578bcb0991SDimitry Andric   if (!IsInlineConstant(NegSplatValue))
2588bcb0991SDimitry Andric     return false; // Even if we negate it it won't help.
2598bcb0991SDimitry Andric 
2608bcb0991SDimitry Andric   SDLoc DL(Node);
2618bcb0991SDimitry Andric 
2628bcb0991SDimitry Andric   SDValue NegC = CurDAG->FoldConstantArithmetic(
2635ffd83dbSDimitry Andric       ISD::SUB, DL, VT, {CurDAG->getConstant(0, DL, VT), C});
2648bcb0991SDimitry Andric   assert(NegC && "Constant-folding failed!");
2658bcb0991SDimitry Andric   SDValue NewNode = CurDAG->getNode(ISD::SUB, DL, VT, X, NegC);
2668bcb0991SDimitry Andric 
2678bcb0991SDimitry Andric   ReplaceNode(Node, NewNode.getNode());
2688bcb0991SDimitry Andric   SelectCode(NewNode.getNode());
2698bcb0991SDimitry Andric   return true;
2708bcb0991SDimitry Andric }
2718bcb0991SDimitry Andric 
2720b57cec5SDimitry Andric /// Select instructions not customized! Used for
2730b57cec5SDimitry Andric /// expanded, promoted and normal instructions
2740b57cec5SDimitry Andric void MipsDAGToDAGISel::Select(SDNode *Node) {
2750b57cec5SDimitry Andric   unsigned Opcode = Node->getOpcode();
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   // If we have a custom node, we already have selected!
2780b57cec5SDimitry Andric   if (Node->isMachineOpcode()) {
2790b57cec5SDimitry Andric     LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
2800b57cec5SDimitry Andric     Node->setNodeId(-1);
2810b57cec5SDimitry Andric     return;
2820b57cec5SDimitry Andric   }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   // See if subclasses can handle this node.
2850b57cec5SDimitry Andric   if (trySelect(Node))
2860b57cec5SDimitry Andric     return;
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   switch(Opcode) {
2890b57cec5SDimitry Andric   default: break;
2900b57cec5SDimitry Andric 
2918bcb0991SDimitry Andric   case ISD::ADD:
2928bcb0991SDimitry Andric     if (Node->getSimpleValueType(0).isVector() &&
2938bcb0991SDimitry Andric         selectVecAddAsVecSubIfProfitable(Node))
2948bcb0991SDimitry Andric       return;
2958bcb0991SDimitry Andric     break;
2968bcb0991SDimitry Andric 
2970b57cec5SDimitry Andric   // Get target GOT address.
2980b57cec5SDimitry Andric   case ISD::GLOBAL_OFFSET_TABLE:
2990b57cec5SDimitry Andric     ReplaceNode(Node, getGlobalBaseReg());
3000b57cec5SDimitry Andric     return;
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric #ifndef NDEBUG
3030b57cec5SDimitry Andric   case ISD::LOAD:
3040b57cec5SDimitry Andric   case ISD::STORE:
3050b57cec5SDimitry Andric     assert((Subtarget->systemSupportsUnalignedAccess() ||
306bdd1243dSDimitry Andric             cast<MemSDNode>(Node)->getAlign() >=
307bdd1243dSDimitry Andric                 cast<MemSDNode>(Node)->getMemoryVT().getStoreSize()) &&
3080b57cec5SDimitry Andric            "Unexpected unaligned loads/stores.");
3090b57cec5SDimitry Andric     break;
3100b57cec5SDimitry Andric #endif
3110b57cec5SDimitry Andric   }
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   // Select the default instruction
3140b57cec5SDimitry Andric   SelectCode(Node);
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3175f757f3fSDimitry Andric bool MipsDAGToDAGISel::SelectInlineAsmMemoryOperand(
3185f757f3fSDimitry Andric     const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
3190b57cec5SDimitry Andric     std::vector<SDValue> &OutOps) {
3200b57cec5SDimitry Andric   // All memory constraints can at least accept raw pointers.
3210b57cec5SDimitry Andric   switch(ConstraintID) {
3220b57cec5SDimitry Andric   default:
3230b57cec5SDimitry Andric     llvm_unreachable("Unexpected asm memory constraint");
3245f757f3fSDimitry Andric   case InlineAsm::ConstraintCode::m:
3255f757f3fSDimitry Andric   case InlineAsm::ConstraintCode::R:
3265f757f3fSDimitry Andric   case InlineAsm::ConstraintCode::ZC:
3270b57cec5SDimitry Andric     OutOps.push_back(Op);
3280b57cec5SDimitry Andric     return false;
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric   return true;
3310b57cec5SDimitry Andric }
332bdd1243dSDimitry Andric 
333647cbc5dSDimitry Andric bool MipsDAGToDAGISel::isUnneededShiftMask(SDNode *N,
334647cbc5dSDimitry Andric                                            unsigned ShAmtBits) const {
335647cbc5dSDimitry Andric   assert(N->getOpcode() == ISD::AND && "Unexpected opcode");
336647cbc5dSDimitry Andric 
337647cbc5dSDimitry Andric   const APInt &RHS = N->getConstantOperandAPInt(1);
338647cbc5dSDimitry Andric   if (RHS.countr_one() >= ShAmtBits) {
339647cbc5dSDimitry Andric     LLVM_DEBUG(
340647cbc5dSDimitry Andric         dbgs()
341647cbc5dSDimitry Andric         << DEBUG_TYPE
342647cbc5dSDimitry Andric         << " Need optimize 'and & shl/srl/sra' and operand value bits is "
343647cbc5dSDimitry Andric         << RHS.countr_one() << "\n");
344647cbc5dSDimitry Andric     return true;
345647cbc5dSDimitry Andric   }
346647cbc5dSDimitry Andric 
347647cbc5dSDimitry Andric   KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0));
348647cbc5dSDimitry Andric   return (Known.Zero | RHS).countr_one() >= ShAmtBits;
349647cbc5dSDimitry Andric }
350647cbc5dSDimitry Andric 
3510fca6ea1SDimitry Andric char MipsDAGToDAGISelLegacy::ID = 0;
352bdd1243dSDimitry Andric 
3530fca6ea1SDimitry Andric MipsDAGToDAGISelLegacy::MipsDAGToDAGISelLegacy(
3540fca6ea1SDimitry Andric     std::unique_ptr<SelectionDAGISel> S)
3550fca6ea1SDimitry Andric     : SelectionDAGISelLegacy(ID, std::move(S)) {}
3560fca6ea1SDimitry Andric 
3570fca6ea1SDimitry Andric INITIALIZE_PASS(MipsDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
358