Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVCodeGenPrepare.cpp
blob7bc7e3924ca70261f9e9c953342348c4080430d2
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.
14 //===----------------------------------------------------------------------===//
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"
26 using namespace llvm;
28 #define DEBUG_TYPE "riscv-codegenprepare"
29 #define PASS_NAME "RISC-V CodeGenPrepare"
31 STATISTIC(NumZExtToSExt, "Number of SExt instructions converted to ZExt");
33 namespace {
35 class RISCVCodeGenPrepare : public FunctionPass,
36 public InstVisitor<RISCVCodeGenPrepare, bool> {
37 const DataLayout *DL;
38 const RISCVSubtarget *ST;
40 public:
41 static char ID;
43 RISCVCodeGenPrepare() : FunctionPass(ID) {}
45 bool runOnFunction(Function &F) override;
47 StringRef getPassName() const override { return PASS_NAME; }
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesCFG();
51 AU.addRequired<TargetPassConfig>();
54 bool visitInstruction(Instruction &I) { return false; }
55 bool visitZExtInst(ZExtInst &I);
56 bool visitAnd(BinaryOperator &BO);
59 } // end anonymous namespace
61 bool RISCVCodeGenPrepare::visitZExtInst(ZExtInst &ZExt) {
62 if (!ST->is64Bit())
63 return false;
65 if (ZExt.hasNonNeg())
66 return false;
68 Value *Src = ZExt.getOperand(0);
70 // We only care about ZExt from i32 to i64.
71 if (!ZExt.getType()->isIntegerTy(64) || !Src->getType()->isIntegerTy(32))
72 return false;
74 // Look for an opportunity to infer nneg on a zext if we can determine that
75 // the sign bit of X is zero via a dominating condition. This often occurs
76 // with widened induction variables.
77 if (isImpliedByDomCondition(ICmpInst::ICMP_SGE, Src,
78 Constant::getNullValue(Src->getType()), &ZExt,
79 *DL).value_or(false)) {
80 ZExt.setNonNeg(true);
81 ++NumZExtToSExt;
82 return true;
85 // Convert (zext (abs(i32 X, i1 1))) -> (zext nneg (abs(i32 X, i1 1))). If abs of
86 // INT_MIN is poison, the sign bit is zero.
87 // TODO: Move this to instcombine now that we have zext nneg in IR.
88 using namespace PatternMatch;
89 if (match(Src, m_Intrinsic<Intrinsic::abs>(m_Value(), m_One()))) {
90 ZExt.setNonNeg(true);
91 ++NumZExtToSExt;
92 return true;
95 return false;
98 // Try to optimize (i64 (and (zext/sext (i32 X), C1))) if C1 has bit 31 set,
99 // but bits 63:32 are zero. If we know that bit 31 of X is 0, we can fill
100 // the upper 32 bits with ones.
101 bool RISCVCodeGenPrepare::visitAnd(BinaryOperator &BO) {
102 if (!ST->is64Bit())
103 return false;
105 if (!BO.getType()->isIntegerTy(64))
106 return false;
108 auto canBeSignExtend = [](Instruction *I) {
109 if (isa<SExtInst>(I))
110 return true;
111 if (isa<ZExtInst>(I))
112 return I->hasNonNeg();
113 return false;
116 // Left hand side should be a sext or zext nneg.
117 Instruction *LHS = dyn_cast<Instruction>(BO.getOperand(0));
118 if (!LHS || !canBeSignExtend(LHS))
119 return false;
121 Value *LHSSrc = LHS->getOperand(0);
122 if (!LHSSrc->getType()->isIntegerTy(32))
123 return false;
125 // Right hand side should be a constant.
126 Value *RHS = BO.getOperand(1);
128 auto *CI = dyn_cast<ConstantInt>(RHS);
129 if (!CI)
130 return false;
131 uint64_t C = CI->getZExtValue();
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;
139 // Sign extend the constant and replace the And operand.
140 C = SignExtend64<32>(C);
141 BO.setOperand(1, ConstantInt::get(LHS->getType(), C));
143 return true;
146 bool RISCVCodeGenPrepare::runOnFunction(Function &F) {
147 if (skipFunction(F))
148 return false;
150 auto &TPC = getAnalysis<TargetPassConfig>();
151 auto &TM = TPC.getTM<RISCVTargetMachine>();
152 ST = &TM.getSubtarget<RISCVSubtarget>(F);
154 DL = &F.getParent()->getDataLayout();
156 bool MadeChange = false;
157 for (auto &BB : F)
158 for (Instruction &I : llvm::make_early_inc_range(BB))
159 MadeChange |= visit(I);
161 return MadeChange;
164 INITIALIZE_PASS_BEGIN(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
165 INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
166 INITIALIZE_PASS_END(RISCVCodeGenPrepare, DEBUG_TYPE, PASS_NAME, false, false)
168 char RISCVCodeGenPrepare::ID = 0;
170 FunctionPass *llvm::createRISCVCodeGenPreparePass() {
171 return new RISCVCodeGenPrepare();