2020#include " llvm/Analysis/ValueLatticeUtils.h"
2121#include " llvm/Analysis/ValueTracking.h"
2222#include " llvm/IR/InstVisitor.h"
23+ #include " llvm/IR/PatternMatch.h"
2324#include " llvm/Support/Casting.h"
2425#include " llvm/Support/Debug.h"
2526#include " llvm/Support/ErrorHandling.h"
3031#include < vector>
3132
3233using namespace llvm ;
34+ using namespace PatternMatch ;
3335
3436#define DEBUG_TYPE " sccp"
3537
@@ -83,20 +85,28 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
8385 return true ;
8486}
8587
88+ // / Helper for getting ranges from \p Solver. Instructions inserted during
89+ // / simplification are unavailable in the solver, so we return a full range for
90+ // / them.
91+ static ConstantRange getRange (Value *Op, SCCPSolver &Solver,
92+ const SmallPtrSetImpl<Value *> &InsertedValues) {
93+ if (auto *Const = dyn_cast<Constant>(Op))
94+ return Const->toConstantRange ();
95+ if (InsertedValues.contains (Op)) {
96+ unsigned Bitwidth = Op->getType ()->getScalarSizeInBits ();
97+ return ConstantRange::getFull (Bitwidth);
98+ }
99+ return Solver.getLatticeValueFor (Op).asConstantRange (Op->getType (),
100+ /* UndefAllowed=*/ false );
101+ }
102+
86103// / Try to use \p Inst's value range from \p Solver to infer the NUW flag.
87104static bool refineInstruction (SCCPSolver &Solver,
88105 const SmallPtrSetImpl<Value *> &InsertedValues,
89106 Instruction &Inst) {
90107 bool Changed = false ;
91108 auto GetRange = [&Solver, &InsertedValues](Value *Op) {
92- if (auto *Const = dyn_cast<Constant>(Op))
93- return Const->toConstantRange ();
94- if (InsertedValues.contains (Op)) {
95- unsigned Bitwidth = Op->getType ()->getScalarSizeInBits ();
96- return ConstantRange::getFull (Bitwidth);
97- }
98- return Solver.getLatticeValueFor (Op).asConstantRange (
99- Op->getType (), /* UndefAllowed=*/ false );
109+ return getRange (Op, Solver, InsertedValues);
100110 };
101111
102112 if (isa<OverflowingBinaryOperator>(Inst)) {
@@ -167,16 +177,8 @@ static bool replaceSignedInst(SCCPSolver &Solver,
167177 SmallPtrSetImpl<Value *> &InsertedValues,
168178 Instruction &Inst) {
169179 // Determine if a signed value is known to be >= 0.
170- auto isNonNegative = [&Solver](Value *V) {
171- // If this value was constant-folded, it may not have a solver entry.
172- // Handle integers. Otherwise, return false.
173- if (auto *C = dyn_cast<Constant>(V)) {
174- auto *CInt = dyn_cast<ConstantInt>(C);
175- return CInt && !CInt->isNegative ();
176- }
177- const ValueLatticeElement &IV = Solver.getLatticeValueFor (V);
178- return IV.isConstantRange (/* UndefAllowed=*/ false ) &&
179- IV.getConstantRange ().isAllNonNegative ();
180+ auto isNonNegative = [&Solver, &InsertedValues](Value *V) {
181+ return getRange (V, Solver, InsertedValues).isAllNonNegative ();
180182 };
181183
182184 Instruction *NewInst = nullptr ;
@@ -185,7 +187,7 @@ static bool replaceSignedInst(SCCPSolver &Solver,
185187 case Instruction::SExt: {
186188 // If the source value is not negative, this is a zext/uitofp.
187189 Value *Op0 = Inst.getOperand (0 );
188- if (InsertedValues. count (Op0) || !isNonNegative (Op0))
190+ if (!isNonNegative (Op0))
189191 return false ;
190192 NewInst = CastInst::Create (Inst.getOpcode () == Instruction::SExt
191193 ? Instruction::ZExt
@@ -197,7 +199,7 @@ static bool replaceSignedInst(SCCPSolver &Solver,
197199 case Instruction::AShr: {
198200 // If the shifted value is not negative, this is a logical shift right.
199201 Value *Op0 = Inst.getOperand (0 );
200- if (InsertedValues. count (Op0) || !isNonNegative (Op0))
202+ if (!isNonNegative (Op0))
201203 return false ;
202204 NewInst = BinaryOperator::CreateLShr (Op0, Inst.getOperand (1 ), " " , Inst.getIterator ());
203205 NewInst->setIsExact (Inst.isExact ());
@@ -207,8 +209,7 @@ static bool replaceSignedInst(SCCPSolver &Solver,
207209 case Instruction::SRem: {
208210 // If both operands are not negative, this is the same as udiv/urem.
209211 Value *Op0 = Inst.getOperand (0 ), *Op1 = Inst.getOperand (1 );
210- if (InsertedValues.count (Op0) || InsertedValues.count (Op1) ||
211- !isNonNegative (Op0) || !isNonNegative (Op1))
212+ if (!isNonNegative (Op0) || !isNonNegative (Op1))
212213 return false ;
213214 auto NewOpcode = Inst.getOpcode () == Instruction::SDiv ? Instruction::UDiv
214215 : Instruction::URem;
@@ -232,6 +233,26 @@ static bool replaceSignedInst(SCCPSolver &Solver,
232233 return true ;
233234}
234235
236+ // / Try to use \p Inst's value range from \p Solver to simplify it.
237+ static Value *simplifyInstruction (SCCPSolver &Solver,
238+ SmallPtrSetImpl<Value *> &InsertedValues,
239+ Instruction &Inst) {
240+ auto GetRange = [&Solver, &InsertedValues](Value *Op) {
241+ return getRange (Op, Solver, InsertedValues);
242+ };
243+
244+ Value *X;
245+ const APInt *RHSC;
246+ // Remove masking operations.
247+ if (match (&Inst, m_And (m_Value (X), m_LowBitMask (RHSC)))) {
248+ ConstantRange LRange = GetRange (Inst.getOperand (0 ));
249+ if (LRange.getUnsignedMax ().ule (*RHSC))
250+ return X;
251+ }
252+
253+ return nullptr ;
254+ }
255+
235256bool SCCPSolver::simplifyInstsInBlock (BasicBlock &BB,
236257 SmallPtrSetImpl<Value *> &InsertedValues,
237258 Statistic &InstRemovedStat,
@@ -251,6 +272,11 @@ bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
251272 ++InstReplacedStat;
252273 } else if (refineInstruction (*this , InsertedValues, Inst)) {
253274 MadeChanges = true ;
275+ } else if (auto *V = simplifyInstruction (*this , InsertedValues, Inst)) {
276+ Inst.replaceAllUsesWith (V);
277+ Inst.eraseFromParent ();
278+ ++InstRemovedStat;
279+ MadeChanges = true ;
254280 }
255281 }
256282 return MadeChanges;
0 commit comments