RISCVCodeGenPrepare.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //===----- RISCVCodeGenPrepare.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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This is a RISCV specific version of CodeGenPrepare.
  10. // It munges the code in the input function to better prepare it for
  11. // SelectionDAG-based code generation. This works around limitations in it's
  12. // basic-block-at-a-time approach.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "RISCV.h"
  16. #include "RISCVTargetMachine.h"
  17. #include "llvm/ADT/Statistic.h"
  18. #include "llvm/Analysis/ValueTracking.h"
  19. #include "llvm/CodeGen/TargetPassConfig.h"
  20. #include "llvm/IR/InstVisitor.h"
  21. #include "llvm/IR/PatternMatch.h"
  22. #include "llvm/InitializePasses.h"
  23. #include "llvm/Pass.h"
  24. using namespace llvm;
  25. #define DEBUG_TYPE "riscv-codegenprepare"
  26. #define PASS_NAME "RISCV CodeGenPrepare"
  27. STATISTIC(NumZExtToSExt, "Number of SExt instructions converted to ZExt");
  28. namespace {
  29. class RISCVCodeGenPrepare : public FunctionPass,
  30. public InstVisitor<RISCVCodeGenPrepare, bool> {
  31. const DataLayout *DL;
  32. const RISCVSubtarget *ST;
  33. public:
  34. static char ID;
  35. RISCVCodeGenPrepare() : FunctionPass(ID) {}
  36. bool runOnFunction(Function &F) override;
  37. StringRef getPassName() const override { return PASS_NAME; }
  38. void getAnalysisUsage(AnalysisUsage &AU) const override {
  39. AU.setPreservesCFG();
  40. AU.addRequired<TargetPassConfig>();
  41. }
  42. bool visitInstruction(Instruction &I) { return false; }
  43. bool visitZExtInst(ZExtInst &I);
  44. bool visitAnd(BinaryOperator &BO);
  45. };
  46. } // end anonymous namespace
  47. bool RISCVCodeGenPrepare::visitZExtInst(ZExtInst &ZExt) {
  48. if (!ST->is64Bit())
  49. return false;
  50. Value *Src = ZExt.getOperand(0);
  51. // We only care about ZExt from i32 to i64.
  52. if (!ZExt.getType()->isIntegerTy(64) || !Src->getType()->isIntegerTy(32))
  53. return false;
  54. // Look for an opportunity to replace (i64 (zext (i32 X))) with a sext if we
  55. // can determine that the sign bit of X is zero via a dominating condition.
  56. // This often occurs with widened induction variables.
  57. if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src,
  58. Constant::getNullValue(Src->getType()), &ZExt,
  59. *DL).value_or(false)) {
  60. auto *SExt = new SExtInst(Src, ZExt.getType(), "", &ZExt);
  61. SExt->takeName(&ZExt);
  62. SExt->setDebugLoc(ZExt.getDebugLoc());
  63. ZExt.replaceAllUsesWith(SExt);
  64. ZExt.eraseFromParent();
  65. ++NumZExtToSExt;
  66. return true;
  67. }
  68. // Convert (zext (abs(i32 X, i1 1))) -> (sext (abs(i32 X, i1 1))). If abs of
  69. // INT_MIN is poison, the sign bit is zero.
  70. using namespace PatternMatch;
  71. if (match(Src, m_Intrinsic<Intrinsic::abs>(m_Value(), m_One()))) {
  72. auto *SExt = new SExtInst(Src, ZExt.getType(), "", &ZExt);
  73. SExt->takeName(&ZExt);
  74. SExt->setDebugLoc(ZExt.getDebugLoc());
  75. ZExt.replaceAllUsesWith(SExt);
  76. ZExt.eraseFromParent();
  77. ++NumZExtToSExt;
  78. return true;
  79. }
  80. return false;
  81. }
  82. // Try to optimize (i64 (and (zext/sext (i32 X), C1))) if C1 has bit 31 set,
  83. // but bits 63:32 are zero. If we can prove that bit 31 of X is 0, we can fill
  84. // the upper 32 bits with ones. A separate transform will turn (zext X) into
  85. // (sext X) for the same condition.
  86. bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) {
  87. if (!ST->is64Bit())
  88. return false;
  89. if (!BO.getType()->isIntegerTy(64))
  90. return false;
  91. // Left hand side should be sext or zext.
  92. Instruction *LHS = dyn_cast<Instruction>(BO.getOperand(0));
  93. if (!LHS || (!isa<SExtInst>(LHS) && !isa<ZExtInst>(LHS)))
  94. return false;
  95. Value *LHSSrc = LHS->getOperand(0);
  96. if (!LHSSrc->getType()->isIntegerTy(32))
  97. return false;
  98. // Right hand side should be a constant.
  99. Value *RHS = BO.getOperand(1);
  100. auto *CI = dyn_cast<ConstantInt>(RHS);
  101. if (!CI)
  102. return false;
  103. uint64_t C = CI->getZExtValue();
  104. // Look for constants that fit in 32 bits but not simm12, and can be made
  105. // into simm12 by sign extending bit 31. This will allow use of ANDI.
  106. // TODO: Is worth making simm32?
  107. if (!isUInt<32>(C) || isInt<12>(C) || !isInt<12>(SignExtend64<32>(C)))
  108. return false;
  109. // If we can determine the sign bit of the input is 0, we can replace the
  110. // And mask constant.
  111. if (!isImpliedByDomCondition(ICmpInst::ICMP_SGE, LHSSrc,
  112. Constant::getNullValue(LHSSrc->getType()),
  113. LHS, *DL).value_or(false))
  114. return false;
  115. // Sign extend the constant and replace the And operand.
  116. C = SignExtend64<32>(C);
  117. BO.setOperand(1, ConstantInt::get(LHS->getType(), C));
  118. return true;
  119. }
  120. bool RISCVCodeGenPrepare::runOnFunction(Function &F) {
  121. if (skipFunction(F))
  122. return false;
  123. auto &TPC = getAnalysis<TargetPassConfig>();
  124. auto &TM = TPC.getTM<RISCVTargetMachine>();
  125. ST = &TM.getSubtarget<RISCVSubtarget>(F);
  126. DL = &F.getParent()->getDataLayout();
  127. bool MadeChange = false;
  128. for (auto &BB : F)
  129. for (Instruction &I : llvm::make_early_inc_range(BB))
  130. MadeChange |= visit(I);
  131. return MadeChange;
  132. }
  133. INITIALIZE_PASS_BEGIN(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
  134. INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
  135. INITIALIZE_PASS_END(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
  136. char RISCVCodeGenPrepare::ID = 0;
  137. FunctionPass *llvm::createRISCVCodeGenPreparePass() {
  138. return new RISCVCodeGenPrepare();
  139. }