11a8468baSCraig Topper //===----- RISCVCodeGenPrepare.cpp ----------------------------------------===//
21a8468baSCraig Topper //
31a8468baSCraig Topper // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41a8468baSCraig Topper // See https://llvm.org/LICENSE.txt for license information.
51a8468baSCraig Topper // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61a8468baSCraig Topper //
71a8468baSCraig Topper //===----------------------------------------------------------------------===//
81a8468baSCraig Topper //
91a8468baSCraig Topper // This is a RISCV specific version of CodeGenPrepare.
101a8468baSCraig Topper // It munges the code in the input function to better prepare it for
111a8468baSCraig Topper // SelectionDAG-based code generation. This works around limitations in it's
121a8468baSCraig Topper // basic-block-at-a-time approach.
131a8468baSCraig Topper //
141a8468baSCraig Topper //===----------------------------------------------------------------------===//
151a8468baSCraig Topper 
161a8468baSCraig Topper #include "RISCV.h"
171a8468baSCraig Topper #include "RISCVTargetMachine.h"
181a8468baSCraig Topper #include "llvm/ADT/Statistic.h"
191a8468baSCraig Topper #include "llvm/Analysis/ValueTracking.h"
201a8468baSCraig Topper #include "llvm/CodeGen/TargetPassConfig.h"
211db6d6dcSCraig Topper #include "llvm/IR/PatternMatch.h"
221a8468baSCraig Topper #include "llvm/InitializePasses.h"
231a8468baSCraig Topper #include "llvm/Pass.h"
241a8468baSCraig Topper 
251a8468baSCraig Topper using namespace llvm;
261a8468baSCraig Topper 
271a8468baSCraig Topper #define DEBUG_TYPE "riscv-codegenprepare"
281a8468baSCraig Topper #define PASS_NAME "RISCV CodeGenPrepare"
291a8468baSCraig Topper 
301a8468baSCraig Topper STATISTIC(NumZExtToSExt, "Number of SExt instructions converted to ZExt");
311a8468baSCraig Topper 
321a8468baSCraig Topper namespace {
331a8468baSCraig Topper 
341a8468baSCraig Topper class RISCVCodeGenPrepare : public FunctionPass {
351a8468baSCraig Topper   const DataLayout *DL;
361a8468baSCraig Topper   const RISCVSubtarget *ST;
371a8468baSCraig Topper 
381a8468baSCraig Topper public:
391a8468baSCraig Topper   static char ID;
401a8468baSCraig Topper 
RISCVCodeGenPrepare()411a8468baSCraig Topper   RISCVCodeGenPrepare() : FunctionPass(ID) {}
421a8468baSCraig Topper 
431a8468baSCraig Topper   bool runOnFunction(Function &F) override;
441a8468baSCraig Topper 
getPassName() const451a8468baSCraig Topper   StringRef getPassName() const override { return PASS_NAME; }
461a8468baSCraig Topper 
getAnalysisUsage(AnalysisUsage & AU) const471a8468baSCraig Topper   void getAnalysisUsage(AnalysisUsage &AU) const override {
481a8468baSCraig Topper     AU.setPreservesCFG();
491a8468baSCraig Topper     AU.addRequired<TargetPassConfig>();
501a8468baSCraig Topper   }
511a8468baSCraig Topper 
521a8468baSCraig Topper private:
531a8468baSCraig Topper   bool optimizeZExt(ZExtInst *I);
548cc48309SCraig Topper   bool optimizeAndExt(BinaryOperator *BO);
551a8468baSCraig Topper };
561a8468baSCraig Topper 
571a8468baSCraig Topper } // end anonymous namespace
581a8468baSCraig Topper 
optimizeZExt(ZExtInst * ZExt)591a8468baSCraig Topper bool RISCVCodeGenPrepare::optimizeZExt(ZExtInst *ZExt) {
601a8468baSCraig Topper   if (!ST->is64Bit())
611a8468baSCraig Topper     return false;
621a8468baSCraig Topper 
631a8468baSCraig Topper   Value *Src = ZExt->getOperand(0);
641a8468baSCraig Topper 
651a8468baSCraig Topper   // We only care about ZExt from i32 to i64.
661a8468baSCraig Topper   if (!ZExt->getType()->isIntegerTy(64) || !Src->getType()->isIntegerTy(32))
671a8468baSCraig Topper     return false;
681a8468baSCraig Topper 
691a8468baSCraig Topper   // Look for an opportunity to replace (i64 (zext (i32 X))) with a sext if we
701a8468baSCraig Topper   // can determine that the sign bit of X is zero via a dominating condition.
711a8468baSCraig Topper   // This often occurs with widened induction variables.
721a8468baSCraig Topper   if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src,
731a8468baSCraig Topper                               Constant::getNullValue(Src->getType()), ZExt,
74*f1f55a9fSCraig Topper                               *DL).value_or(false)) {
7573f766caSCraig Topper     auto *SExt = new SExtInst(Src, ZExt->getType(), "", ZExt);
761a8468baSCraig Topper     SExt->takeName(ZExt);
7773f766caSCraig Topper     SExt->setDebugLoc(ZExt->getDebugLoc());
781a8468baSCraig Topper 
791a8468baSCraig Topper     ZExt->replaceAllUsesWith(SExt);
801a8468baSCraig Topper     ZExt->eraseFromParent();
811a8468baSCraig Topper     ++NumZExtToSExt;
821a8468baSCraig Topper     return true;
831a8468baSCraig Topper   }
841a8468baSCraig Topper 
851db6d6dcSCraig Topper   // Convert (zext (abs(i32 X, i1 1))) -> (sext (abs(i32 X, i1 1))). If abs of
861db6d6dcSCraig Topper   // INT_MIN is poison, the sign bit is zero.
871db6d6dcSCraig Topper   using namespace PatternMatch;
881db6d6dcSCraig Topper   if (match(Src, m_Intrinsic<Intrinsic::abs>(m_Value(), m_One()))) {
891db6d6dcSCraig Topper     auto *SExt = new SExtInst(Src, ZExt->getType(), "", ZExt);
901db6d6dcSCraig Topper     SExt->takeName(ZExt);
911db6d6dcSCraig Topper     SExt->setDebugLoc(ZExt->getDebugLoc());
921db6d6dcSCraig Topper 
931db6d6dcSCraig Topper     ZExt->replaceAllUsesWith(SExt);
941db6d6dcSCraig Topper     ZExt->eraseFromParent();
951db6d6dcSCraig Topper     ++NumZExtToSExt;
961db6d6dcSCraig Topper     return true;
971db6d6dcSCraig Topper   }
981db6d6dcSCraig Topper 
991a8468baSCraig Topper   return false;
1001a8468baSCraig Topper }
1011a8468baSCraig Topper 
1028cc48309SCraig Topper // Try to optimize (i64 (and (zext/sext (i32 X), C1))) if C1 has bit 31 set,
1038cc48309SCraig Topper // but bits 63:32 are zero. If we can prove that bit 31 of X is 0, we can fill
1048cc48309SCraig Topper // the upper 32 bits with ones. A separate transform will turn (zext X) into
1058cc48309SCraig Topper // (sext X) for the same condition.
optimizeAndExt(BinaryOperator * BO)1068cc48309SCraig Topper bool RISCVCodeGenPrepare::optimizeAndExt(BinaryOperator *BO) {
1078cc48309SCraig Topper   if (!ST->is64Bit())
1088cc48309SCraig Topper     return false;
1098cc48309SCraig Topper 
1108cc48309SCraig Topper   if (BO->getOpcode() != Instruction::And)
1118cc48309SCraig Topper     return false;
1128cc48309SCraig Topper 
1138cc48309SCraig Topper   if (!BO->getType()->isIntegerTy(64))
1148cc48309SCraig Topper     return false;
1158cc48309SCraig Topper 
1168cc48309SCraig Topper   // Left hand side should be sext or zext.
1178cc48309SCraig Topper   Instruction *LHS = dyn_cast<Instruction>(BO->getOperand(0));
1188cc48309SCraig Topper   if (!LHS || (!isa<SExtInst>(LHS) && !isa<ZExtInst>(LHS)))
1198cc48309SCraig Topper     return false;
1208cc48309SCraig Topper 
1218cc48309SCraig Topper   Value *LHSSrc = LHS->getOperand(0);
1228cc48309SCraig Topper   if (!LHSSrc->getType()->isIntegerTy(32))
1238cc48309SCraig Topper     return false;
1248cc48309SCraig Topper 
1258cc48309SCraig Topper   // Right hand side should be a constant.
1268cc48309SCraig Topper   Value *RHS = BO->getOperand(1);
1278cc48309SCraig Topper 
1288cc48309SCraig Topper   auto *CI = dyn_cast<ConstantInt>(RHS);
1298cc48309SCraig Topper   if (!CI)
1308cc48309SCraig Topper     return false;
1318cc48309SCraig Topper   uint64_t C = CI->getZExtValue();
1328cc48309SCraig Topper 
1338cc48309SCraig Topper   // Look for constants that fit in 32 bits but not simm12, and can be made
1348cc48309SCraig Topper   // into simm12 by sign extending bit 31. This will allow use of ANDI.
1358cc48309SCraig Topper   // TODO: Is worth making simm32?
1368cc48309SCraig Topper   if (!isUInt<32>(C) || isInt<12>(C) || !isInt<12>(SignExtend64<32>(C)))
1378cc48309SCraig Topper     return false;
1388cc48309SCraig Topper 
1398cc48309SCraig Topper   // If we can determine the sign bit of the input is 0, we can replace the
1408cc48309SCraig Topper   // And mask constant.
1418cc48309SCraig Topper   if (!isImpliedByDomCondition(ICmpInst::ICMP_SGE, LHSSrc,
1428cc48309SCraig Topper                                Constant::getNullValue(LHSSrc->getType()),
143*f1f55a9fSCraig Topper                                LHS, *DL).value_or(false))
1448cc48309SCraig Topper     return false;
1458cc48309SCraig Topper 
1468cc48309SCraig Topper   // Sign extend the constant and replace the And operand.
1478cc48309SCraig Topper   C = SignExtend64<32>(C);
1488cc48309SCraig Topper   BO->setOperand(1, ConstantInt::get(LHS->getType(), C));
1498cc48309SCraig Topper 
1508cc48309SCraig Topper   return true;
1518cc48309SCraig Topper }
1528cc48309SCraig Topper 
runOnFunction(Function & F)1531a8468baSCraig Topper bool RISCVCodeGenPrepare::runOnFunction(Function &F) {
1541a8468baSCraig Topper   if (skipFunction(F))
1551a8468baSCraig Topper     return false;
1561a8468baSCraig Topper 
1571a8468baSCraig Topper   auto &TPC = getAnalysis<TargetPassConfig>();
1581a8468baSCraig Topper   auto &TM = TPC.getTM<RISCVTargetMachine>();
1591a8468baSCraig Topper   ST = &TM.getSubtarget<RISCVSubtarget>(F);
1601a8468baSCraig Topper 
1611a8468baSCraig Topper   DL = &F.getParent()->getDataLayout();
1621a8468baSCraig Topper 
1631a8468baSCraig Topper   bool MadeChange = false;
1641a8468baSCraig Topper   for (auto &BB : F) {
1651a8468baSCraig Topper     for (Instruction &I : llvm::make_early_inc_range(BB)) {
1661a8468baSCraig Topper       if (auto *ZExt = dyn_cast<ZExtInst>(&I))
1671a8468baSCraig Topper         MadeChange |= optimizeZExt(ZExt);
1688cc48309SCraig Topper       else if (I.getOpcode() == Instruction::And)
1698cc48309SCraig Topper         MadeChange |= optimizeAndExt(cast<BinaryOperator>(&I));
1701a8468baSCraig Topper     }
1711a8468baSCraig Topper   }
1721a8468baSCraig Topper 
1731a8468baSCraig Topper   return MadeChange;
1741a8468baSCraig Topper }
1751a8468baSCraig Topper 
1761a8468baSCraig Topper INITIALIZE_PASS_BEGIN(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
1771a8468baSCraig Topper INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
1781a8468baSCraig Topper INITIALIZE_PASS_END(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
1791a8468baSCraig Topper 
1801a8468baSCraig Topper char RISCVCodeGenPrepare::ID = 0;
1811a8468baSCraig Topper 
createRISCVCodeGenPreparePass()1821a8468baSCraig Topper FunctionPass *llvm::createRISCVCodeGenPreparePass() {
1831a8468baSCraig Topper   return new RISCVCodeGenPrepare();
1841a8468baSCraig Topper }
185