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