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