1 //===-- InstructionSimplify.h - Fold instrs into simpler forms --*- C++ -*-===// 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 file declares routines for folding instructions into simpler forms 10 // that do not require creating new instructions. This does constant folding 11 // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either 12 // returning a constant ("and i32 %x, 0" -> "0") or an already existing value 13 // ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction 14 // then it dominates the original instruction. 15 // 16 // These routines implicitly resolve undef uses. The easiest way to be safe when 17 // using these routines to obtain simplified values for existing instructions is 18 // to always replace all uses of the instructions with the resulting simplified 19 // values. This will prevent other code from seeing the same undef uses and 20 // resolving them to different values. 21 // 22 // They require that all the IR that they encounter be valid and inserted into a 23 // parent function. 24 // 25 // Additionally, these routines can't simplify to the instructions that are not 26 // def-reachable, meaning we can't just scan the basic block for instructions 27 // to simplify to. 28 // 29 //===----------------------------------------------------------------------===// 30 31 #ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H 32 #define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H 33 34 #include "llvm/Analysis/SimplifyQuery.h" 35 36 namespace llvm { 37 38 template <typename T, typename... TArgs> class AnalysisManager; 39 template <class T> class ArrayRef; 40 class AssumptionCache; 41 class BinaryOperator; 42 class CallBase; 43 class DataLayout; 44 class DominatorTree; 45 class Function; 46 class Instruction; 47 struct LoopStandardAnalysisResults; 48 class Pass; 49 template <class T, unsigned n> class SmallSetVector; 50 class TargetLibraryInfo; 51 class Type; 52 class Value; 53 54 // NOTE: the explicit multiple argument versions of these functions are 55 // deprecated. 56 // Please use the SimplifyQuery versions in new code. 57 58 /// Given operands for an Add, fold the result or return null. 59 Value *simplifyAddInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, 60 const SimplifyQuery &Q); 61 62 /// Given operands for a Sub, fold the result or return null. 63 Value *simplifySubInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, 64 const SimplifyQuery &Q); 65 66 /// Given operands for a Mul, fold the result or return null. 67 Value *simplifyMulInst(Value *LHS, Value *RHS, bool IsNSW, bool IsNUW, 68 const SimplifyQuery &Q); 69 70 /// Given operands for an SDiv, fold the result or return null. 71 Value *simplifySDivInst(Value *LHS, Value *RHS, bool IsExact, 72 const SimplifyQuery &Q); 73 74 /// Given operands for a UDiv, fold the result or return null. 75 Value *simplifyUDivInst(Value *LHS, Value *RHS, bool IsExact, 76 const SimplifyQuery &Q); 77 78 /// Given operands for an SRem, fold the result or return null. 79 Value *simplifySRemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); 80 81 /// Given operands for a URem, fold the result or return null. 82 Value *simplifyURemInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); 83 84 /// Given operand for an FNeg, fold the result or return null. 85 Value *simplifyFNegInst(Value *Op, FastMathFlags FMF, const SimplifyQuery &Q); 86 87 88 /// Given operands for an FAdd, fold the result or return null. 89 Value * 90 simplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF, 91 const SimplifyQuery &Q, 92 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 93 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 94 95 /// Given operands for an FSub, fold the result or return null. 96 Value * 97 simplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF, 98 const SimplifyQuery &Q, 99 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 100 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 101 102 /// Given operands for an FMul, fold the result or return null. 103 Value * 104 simplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF, 105 const SimplifyQuery &Q, 106 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 107 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 108 109 /// Given operands for the multiplication of a FMA, fold the result or return 110 /// null. In contrast to simplifyFMulInst, this function will not perform 111 /// simplifications whose unrounded results differ when rounded to the argument 112 /// type. 113 Value *simplifyFMAFMul(Value *LHS, Value *RHS, FastMathFlags FMF, 114 const SimplifyQuery &Q, 115 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 116 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 117 118 /// Given operands for an FDiv, fold the result or return null. 119 Value * 120 simplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF, 121 const SimplifyQuery &Q, 122 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 123 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 124 125 /// Given operands for an FRem, fold the result or return null. 126 Value * 127 simplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF, 128 const SimplifyQuery &Q, 129 fp::ExceptionBehavior ExBehavior = fp::ebIgnore, 130 RoundingMode Rounding = RoundingMode::NearestTiesToEven); 131 132 /// Given operands for a Shl, fold the result or return null. 133 Value *simplifyShlInst(Value *Op0, Value *Op1, bool IsNSW, bool IsNUW, 134 const SimplifyQuery &Q); 135 136 /// Given operands for a LShr, fold the result or return null. 137 Value *simplifyLShrInst(Value *Op0, Value *Op1, bool IsExact, 138 const SimplifyQuery &Q); 139 140 /// Given operands for a AShr, fold the result or return nulll. 141 Value *simplifyAShrInst(Value *Op0, Value *Op1, bool IsExact, 142 const SimplifyQuery &Q); 143 144 /// Given operands for an And, fold the result or return null. 145 Value *simplifyAndInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); 146 147 /// Given operands for an Or, fold the result or return null. 148 Value *simplifyOrInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); 149 150 /// Given operands for an Xor, fold the result or return null. 151 Value *simplifyXorInst(Value *LHS, Value *RHS, const SimplifyQuery &Q); 152 153 /// Given operands for an ICmpInst, fold the result or return null. 154 Value *simplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, 155 const SimplifyQuery &Q); 156 157 /// Given operands for an FCmpInst, fold the result or return null. 158 Value *simplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS, 159 FastMathFlags FMF, const SimplifyQuery &Q); 160 161 /// Given operands for a SelectInst, fold the result or return null. 162 Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, 163 const SimplifyQuery &Q); 164 165 /// Given operands for a GetElementPtrInst, fold the result or return null. 166 Value *simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef<Value *> Indices, 167 bool InBounds, const SimplifyQuery &Q); 168 169 /// Given operands for an InsertValueInst, fold the result or return null. 170 Value *simplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs, 171 const SimplifyQuery &Q); 172 173 /// Given operands for an InsertElement, fold the result or return null. 174 Value *simplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx, 175 const SimplifyQuery &Q); 176 177 /// Given operands for an ExtractValueInst, fold the result or return null. 178 Value *simplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs, 179 const SimplifyQuery &Q); 180 181 /// Given operands for an ExtractElementInst, fold the result or return null. 182 Value *simplifyExtractElementInst(Value *Vec, Value *Idx, 183 const SimplifyQuery &Q); 184 185 /// Given operands for a CastInst, fold the result or return null. 186 Value *simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, 187 const SimplifyQuery &Q); 188 189 /// Given operands for a ShuffleVectorInst, fold the result or return null. 190 /// See class ShuffleVectorInst for a description of the mask representation. 191 Value *simplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef<int> Mask, 192 Type *RetTy, const SimplifyQuery &Q); 193 194 //=== Helper functions for higher up the class hierarchy. 195 196 /// Given operands for a CmpInst, fold the result or return null. 197 Value *simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, 198 const SimplifyQuery &Q); 199 200 /// Given operand for a UnaryOperator, fold the result or return null. 201 Value *simplifyUnOp(unsigned Opcode, Value *Op, const SimplifyQuery &Q); 202 203 /// Given operand for a UnaryOperator, fold the result or return null. 204 /// Try to use FastMathFlags when folding the result. 205 Value *simplifyUnOp(unsigned Opcode, Value *Op, FastMathFlags FMF, 206 const SimplifyQuery &Q); 207 208 /// Given operands for a BinaryOperator, fold the result or return null. 209 Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, 210 const SimplifyQuery &Q); 211 212 /// Given operands for a BinaryOperator, fold the result or return null. 213 /// Try to use FastMathFlags when folding the result. 214 Value *simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, FastMathFlags FMF, 215 const SimplifyQuery &Q); 216 217 /// Given a callsite, callee, and arguments, fold the result or return null. 218 Value *simplifyCall(CallBase *Call, Value *Callee, ArrayRef<Value *> Args, 219 const SimplifyQuery &Q); 220 221 /// Given a constrained FP intrinsic call, tries to compute its simplified 222 /// version. Returns a simplified result or null. 223 /// 224 /// This function provides an additional contract: it guarantees that if 225 /// simplification succeeds that the intrinsic is side effect free. As a result, 226 /// successful simplification can be used to delete the intrinsic not just 227 /// replace its result. 228 Value *simplifyConstrainedFPCall(CallBase *Call, const SimplifyQuery &Q); 229 230 /// Given an operand for a Freeze, see if we can fold the result. 231 /// If not, this returns null. 232 Value *simplifyFreezeInst(Value *Op, const SimplifyQuery &Q); 233 234 /// Given a load instruction and its pointer operand, fold the result or return 235 /// null. 236 Value *simplifyLoadInst(LoadInst *LI, Value *PtrOp, const SimplifyQuery &Q); 237 238 /// See if we can compute a simplified version of this instruction. If not, 239 /// return null. 240 Value *simplifyInstruction(Instruction *I, const SimplifyQuery &Q); 241 242 /// Like \p simplifyInstruction but the operands of \p I are replaced with 243 /// \p NewOps. Returns a simplified value, or null if none was found. 244 Value * 245 simplifyInstructionWithOperands(Instruction *I, ArrayRef<Value *> NewOps, 246 const SimplifyQuery &Q); 247 248 /// See if V simplifies when its operand Op is replaced with RepOp. If not, 249 /// return null. 250 /// AllowRefinement specifies whether the simplification can be a refinement 251 /// (e.g. 0 instead of poison), or whether it needs to be strictly identical. 252 /// Op and RepOp can be assumed to not be poison when determining refinement. 253 /// 254 /// If DropFlags is passed, then the replacement result is only valid if 255 /// poison-generating flags/metadata on those instructions are dropped. This 256 /// is only useful in conjunction with AllowRefinement=false. 257 Value * 258 simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp, 259 const SimplifyQuery &Q, bool AllowRefinement, 260 SmallVectorImpl<Instruction *> *DropFlags = nullptr); 261 262 /// Replace all uses of 'I' with 'SimpleV' and simplify the uses recursively. 263 /// 264 /// This first performs a normal RAUW of I with SimpleV. It then recursively 265 /// attempts to simplify those users updated by the operation. The 'I' 266 /// instruction must not be equal to the simplified value 'SimpleV'. 267 /// If UnsimplifiedUsers is provided, instructions that could not be simplified 268 /// are added to it. 269 /// 270 /// The function returns true if any simplifications were performed. 271 bool replaceAndRecursivelySimplify( 272 Instruction *I, Value *SimpleV, const TargetLibraryInfo *TLI = nullptr, 273 const DominatorTree *DT = nullptr, AssumptionCache *AC = nullptr, 274 SmallSetVector<Instruction *, 8> *UnsimplifiedUsers = nullptr); 275 276 // These helper functions return a SimplifyQuery structure that contains as 277 // many of the optional analysis we use as are currently valid. This is the 278 // strongly preferred way of constructing SimplifyQuery in passes. 279 const SimplifyQuery getBestSimplifyQuery(Pass &, Function &); 280 template <class T, class... TArgs> 281 const SimplifyQuery getBestSimplifyQuery(AnalysisManager<T, TArgs...> &, 282 Function &); 283 const SimplifyQuery getBestSimplifyQuery(LoopStandardAnalysisResults &, 284 const DataLayout &); 285 } // end namespace llvm 286 287 #endif 288