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 namespace { 32 33 class RISCVCodeGenPrepare : public FunctionPass, 34 public InstVisitor<RISCVCodeGenPrepare, bool> { 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 bool visitInstruction(Instruction &I) { return false; } 53 bool visitAnd(BinaryOperator &BO); 54 }; 55 56 } // end anonymous namespace 57 58 // Try to optimize (i64 (and (zext/sext (i32 X), C1))) if C1 has bit 31 set, 59 // but bits 63:32 are zero. If we know that bit 31 of X is 0, we can fill 60 // the upper 32 bits with ones. 61 bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) { 62 if (!ST->is64Bit()) 63 return false; 64 65 if (!BO.getType()->isIntegerTy(64)) 66 return false; 67 68 auto canBeSignExtend = [](Instruction *I) { 69 if (isa<SExtInst>(I)) 70 return true; 71 if (isa<ZExtInst>(I)) 72 return I->hasNonNeg(); 73 return false; 74 }; 75 76 // Left hand side should be a sext or zext nneg. 77 Instruction *LHS = dyn_cast<Instruction>(BO.getOperand(0)); 78 if (!LHS || !canBeSignExtend(LHS)) 79 return false; 80 81 Value *LHSSrc = LHS->getOperand(0); 82 if (!LHSSrc->getType()->isIntegerTy(32)) 83 return false; 84 85 // Right hand side should be a constant. 86 Value *RHS = BO.getOperand(1); 87 88 auto *CI = dyn_cast<ConstantInt>(RHS); 89 if (!CI) 90 return false; 91 uint64_t C = CI->getZExtValue(); 92 93 // Look for constants that fit in 32 bits but not simm12, and can be made 94 // into simm12 by sign extending bit 31. This will allow use of ANDI. 95 // TODO: Is worth making simm32? 96 if (!isUInt<32>(C) || isInt<12>(C) || !isInt<12>(SignExtend64<32>(C))) 97 return false; 98 99 // Sign extend the constant and replace the And operand. 100 C = SignExtend64<32>(C); 101 BO.setOperand(1, ConstantInt::get(LHS->getType(), C)); 102 103 return true; 104 } 105 106 bool RISCVCodeGenPrepare::runOnFunction(Function &F) { 107 if (skipFunction(F)) 108 return false; 109 110 auto &TPC = getAnalysis<TargetPassConfig>(); 111 auto &TM = TPC.getTM<RISCVTargetMachine>(); 112 ST = &TM.getSubtarget<RISCVSubtarget>(F); 113 114 DL = &F.getParent()->getDataLayout(); 115 116 bool MadeChange = false; 117 for (auto &BB : F) 118 for (Instruction &I : llvm::make_early_inc_range(BB)) 119 MadeChange |= visit(I); 120 121 return MadeChange; 122 } 123 124 INITIALIZE_PASS_BEGIN(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false) 125 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) 126 INITIALIZE_PASS_END(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false) 127 128 char RISCVCodeGenPrepare::ID = 0; 129 130 FunctionPass *llvm::createRISCVCodeGenPreparePass() { 131 return new RISCVCodeGenPrepare(); 132 } 133