1 //===-- llvm/Operator.h - Operator utility subclass -------------*- 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 defines various classes for working with Instructions and 10 // ConstantExprs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_IR_OPERATOR_H 15 #define LLVM_IR_OPERATOR_H 16 17 #include "llvm/ADT/MapVector.h" 18 #include "llvm/IR/Constants.h" 19 #include "llvm/IR/FMF.h" 20 #include "llvm/IR/Instruction.h" 21 #include "llvm/IR/Type.h" 22 #include "llvm/IR/Value.h" 23 #include "llvm/Support/Casting.h" 24 #include <cstddef> 25 #include <optional> 26 27 namespace llvm { 28 29 /// This is a utility class that provides an abstraction for the common 30 /// functionality between Instructions and ConstantExprs. 31 class Operator : public User { 32 public: 33 // The Operator class is intended to be used as a utility, and is never itself 34 // instantiated. 35 Operator() = delete; 36 ~Operator() = delete; 37 38 void *operator new(size_t s) = delete; 39 40 /// Return the opcode for this Instruction or ConstantExpr. getOpcode()41 unsigned getOpcode() const { 42 if (const Instruction *I = dyn_cast<Instruction>(this)) 43 return I->getOpcode(); 44 return cast<ConstantExpr>(this)->getOpcode(); 45 } 46 47 /// If V is an Instruction or ConstantExpr, return its opcode. 48 /// Otherwise return UserOp1. getOpcode(const Value * V)49 static unsigned getOpcode(const Value *V) { 50 if (const Instruction *I = dyn_cast<Instruction>(V)) 51 return I->getOpcode(); 52 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) 53 return CE->getOpcode(); 54 return Instruction::UserOp1; 55 } 56 classof(const Instruction *)57 static bool classof(const Instruction *) { return true; } classof(const ConstantExpr *)58 static bool classof(const ConstantExpr *) { return true; } classof(const Value * V)59 static bool classof(const Value *V) { 60 return isa<Instruction>(V) || isa<ConstantExpr>(V); 61 } 62 63 /// Return true if this operator has flags which may cause this operator 64 /// to evaluate to poison despite having non-poison inputs. 65 bool hasPoisonGeneratingFlags() const; 66 67 /// Return true if this operator has poison-generating flags or metadata. 68 /// The latter is only possible for instructions. 69 bool hasPoisonGeneratingFlagsOrMetadata() const; 70 }; 71 72 /// Utility class for integer operators which may exhibit overflow - Add, Sub, 73 /// Mul, and Shl. It does not include SDiv, despite that operator having the 74 /// potential for overflow. 75 class OverflowingBinaryOperator : public Operator { 76 public: 77 enum { 78 AnyWrap = 0, 79 NoUnsignedWrap = (1 << 0), 80 NoSignedWrap = (1 << 1) 81 }; 82 83 private: 84 friend class Instruction; 85 friend class ConstantExpr; 86 setHasNoUnsignedWrap(bool B)87 void setHasNoUnsignedWrap(bool B) { 88 SubclassOptionalData = 89 (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); 90 } setHasNoSignedWrap(bool B)91 void setHasNoSignedWrap(bool B) { 92 SubclassOptionalData = 93 (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); 94 } 95 96 public: 97 /// Test whether this operation is known to never 98 /// undergo unsigned overflow, aka the nuw property. hasNoUnsignedWrap()99 bool hasNoUnsignedWrap() const { 100 return SubclassOptionalData & NoUnsignedWrap; 101 } 102 103 /// Test whether this operation is known to never 104 /// undergo signed overflow, aka the nsw property. hasNoSignedWrap()105 bool hasNoSignedWrap() const { 106 return (SubclassOptionalData & NoSignedWrap) != 0; 107 } 108 classof(const Instruction * I)109 static bool classof(const Instruction *I) { 110 return I->getOpcode() == Instruction::Add || 111 I->getOpcode() == Instruction::Sub || 112 I->getOpcode() == Instruction::Mul || 113 I->getOpcode() == Instruction::Shl; 114 } classof(const ConstantExpr * CE)115 static bool classof(const ConstantExpr *CE) { 116 return CE->getOpcode() == Instruction::Add || 117 CE->getOpcode() == Instruction::Sub || 118 CE->getOpcode() == Instruction::Mul || 119 CE->getOpcode() == Instruction::Shl; 120 } classof(const Value * V)121 static bool classof(const Value *V) { 122 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 123 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 124 } 125 }; 126 127 /// A udiv or sdiv instruction, which can be marked as "exact", 128 /// indicating that no bits are destroyed. 129 class PossiblyExactOperator : public Operator { 130 public: 131 enum { 132 IsExact = (1 << 0) 133 }; 134 135 private: 136 friend class Instruction; 137 friend class ConstantExpr; 138 setIsExact(bool B)139 void setIsExact(bool B) { 140 SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); 141 } 142 143 public: 144 /// Test whether this division is known to be exact, with zero remainder. isExact()145 bool isExact() const { 146 return SubclassOptionalData & IsExact; 147 } 148 isPossiblyExactOpcode(unsigned OpC)149 static bool isPossiblyExactOpcode(unsigned OpC) { 150 return OpC == Instruction::SDiv || 151 OpC == Instruction::UDiv || 152 OpC == Instruction::AShr || 153 OpC == Instruction::LShr; 154 } 155 classof(const ConstantExpr * CE)156 static bool classof(const ConstantExpr *CE) { 157 return isPossiblyExactOpcode(CE->getOpcode()); 158 } classof(const Instruction * I)159 static bool classof(const Instruction *I) { 160 return isPossiblyExactOpcode(I->getOpcode()); 161 } classof(const Value * V)162 static bool classof(const Value *V) { 163 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 164 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 165 } 166 }; 167 168 /// Utility class for floating point operations which can have 169 /// information about relaxed accuracy requirements attached to them. 170 class FPMathOperator : public Operator { 171 private: 172 friend class Instruction; 173 174 /// 'Fast' means all bits are set. setFast(bool B)175 void setFast(bool B) { 176 setHasAllowReassoc(B); 177 setHasNoNaNs(B); 178 setHasNoInfs(B); 179 setHasNoSignedZeros(B); 180 setHasAllowReciprocal(B); 181 setHasAllowContract(B); 182 setHasApproxFunc(B); 183 } 184 setHasAllowReassoc(bool B)185 void setHasAllowReassoc(bool B) { 186 SubclassOptionalData = 187 (SubclassOptionalData & ~FastMathFlags::AllowReassoc) | 188 (B * FastMathFlags::AllowReassoc); 189 } 190 setHasNoNaNs(bool B)191 void setHasNoNaNs(bool B) { 192 SubclassOptionalData = 193 (SubclassOptionalData & ~FastMathFlags::NoNaNs) | 194 (B * FastMathFlags::NoNaNs); 195 } 196 setHasNoInfs(bool B)197 void setHasNoInfs(bool B) { 198 SubclassOptionalData = 199 (SubclassOptionalData & ~FastMathFlags::NoInfs) | 200 (B * FastMathFlags::NoInfs); 201 } 202 setHasNoSignedZeros(bool B)203 void setHasNoSignedZeros(bool B) { 204 SubclassOptionalData = 205 (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) | 206 (B * FastMathFlags::NoSignedZeros); 207 } 208 setHasAllowReciprocal(bool B)209 void setHasAllowReciprocal(bool B) { 210 SubclassOptionalData = 211 (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) | 212 (B * FastMathFlags::AllowReciprocal); 213 } 214 setHasAllowContract(bool B)215 void setHasAllowContract(bool B) { 216 SubclassOptionalData = 217 (SubclassOptionalData & ~FastMathFlags::AllowContract) | 218 (B * FastMathFlags::AllowContract); 219 } 220 setHasApproxFunc(bool B)221 void setHasApproxFunc(bool B) { 222 SubclassOptionalData = 223 (SubclassOptionalData & ~FastMathFlags::ApproxFunc) | 224 (B * FastMathFlags::ApproxFunc); 225 } 226 227 /// Convenience function for setting multiple fast-math flags. 228 /// FMF is a mask of the bits to set. setFastMathFlags(FastMathFlags FMF)229 void setFastMathFlags(FastMathFlags FMF) { 230 SubclassOptionalData |= FMF.Flags; 231 } 232 233 /// Convenience function for copying all fast-math flags. 234 /// All values in FMF are transferred to this operator. copyFastMathFlags(FastMathFlags FMF)235 void copyFastMathFlags(FastMathFlags FMF) { 236 SubclassOptionalData = FMF.Flags; 237 } 238 239 public: 240 /// Test if this operation allows all non-strict floating-point transforms. isFast()241 bool isFast() const { 242 return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 && 243 (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 && 244 (SubclassOptionalData & FastMathFlags::NoInfs) != 0 && 245 (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 && 246 (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 && 247 (SubclassOptionalData & FastMathFlags::AllowContract) != 0 && 248 (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0); 249 } 250 251 /// Test if this operation may be simplified with reassociative transforms. hasAllowReassoc()252 bool hasAllowReassoc() const { 253 return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0; 254 } 255 256 /// Test if this operation's arguments and results are assumed not-NaN. hasNoNaNs()257 bool hasNoNaNs() const { 258 return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0; 259 } 260 261 /// Test if this operation's arguments and results are assumed not-infinite. hasNoInfs()262 bool hasNoInfs() const { 263 return (SubclassOptionalData & FastMathFlags::NoInfs) != 0; 264 } 265 266 /// Test if this operation can ignore the sign of zero. hasNoSignedZeros()267 bool hasNoSignedZeros() const { 268 return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0; 269 } 270 271 /// Test if this operation can use reciprocal multiply instead of division. hasAllowReciprocal()272 bool hasAllowReciprocal() const { 273 return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0; 274 } 275 276 /// Test if this operation can be floating-point contracted (FMA). hasAllowContract()277 bool hasAllowContract() const { 278 return (SubclassOptionalData & FastMathFlags::AllowContract) != 0; 279 } 280 281 /// Test if this operation allows approximations of math library functions or 282 /// intrinsics. hasApproxFunc()283 bool hasApproxFunc() const { 284 return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0; 285 } 286 287 /// Convenience function for getting all the fast-math flags getFastMathFlags()288 FastMathFlags getFastMathFlags() const { 289 return FastMathFlags(SubclassOptionalData); 290 } 291 292 /// Get the maximum error permitted by this operation in ULPs. An accuracy of 293 /// 0.0 means that the operation should be performed with the default 294 /// precision. 295 float getFPAccuracy() const; 296 classof(const Value * V)297 static bool classof(const Value *V) { 298 unsigned Opcode; 299 if (auto *I = dyn_cast<Instruction>(V)) 300 Opcode = I->getOpcode(); 301 else if (auto *CE = dyn_cast<ConstantExpr>(V)) 302 Opcode = CE->getOpcode(); 303 else 304 return false; 305 306 switch (Opcode) { 307 case Instruction::FNeg: 308 case Instruction::FAdd: 309 case Instruction::FSub: 310 case Instruction::FMul: 311 case Instruction::FDiv: 312 case Instruction::FRem: 313 // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp 314 // should not be treated as a math op, but the other opcodes should. 315 // This would make things consistent with Select/PHI (FP value type 316 // determines whether they are math ops and, therefore, capable of 317 // having fast-math-flags). 318 case Instruction::FCmp: 319 return true; 320 case Instruction::PHI: 321 case Instruction::Select: 322 case Instruction::Call: { 323 Type *Ty = V->getType(); 324 while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty)) 325 Ty = ArrTy->getElementType(); 326 return Ty->isFPOrFPVectorTy(); 327 } 328 default: 329 return false; 330 } 331 } 332 }; 333 334 /// A helper template for defining operators for individual opcodes. 335 template<typename SuperClass, unsigned Opc> 336 class ConcreteOperator : public SuperClass { 337 public: classof(const Instruction * I)338 static bool classof(const Instruction *I) { 339 return I->getOpcode() == Opc; 340 } classof(const ConstantExpr * CE)341 static bool classof(const ConstantExpr *CE) { 342 return CE->getOpcode() == Opc; 343 } classof(const Value * V)344 static bool classof(const Value *V) { 345 return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || 346 (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); 347 } 348 }; 349 350 class AddOperator 351 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { 352 }; 353 class SubOperator 354 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { 355 }; 356 class MulOperator 357 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { 358 }; 359 class ShlOperator 360 : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { 361 }; 362 363 class AShrOperator 364 : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { 365 }; 366 class LShrOperator 367 : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { 368 }; 369 370 class GEPOperator 371 : public ConcreteOperator<Operator, Instruction::GetElementPtr> { 372 friend class GetElementPtrInst; 373 friend class ConstantExpr; 374 375 enum { 376 IsInBounds = (1 << 0), 377 // InRangeIndex: bits 1-6 378 }; 379 setIsInBounds(bool B)380 void setIsInBounds(bool B) { 381 SubclassOptionalData = 382 (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); 383 } 384 385 public: 386 /// Test whether this is an inbounds GEP, as defined by LangRef.html. isInBounds()387 bool isInBounds() const { 388 return SubclassOptionalData & IsInBounds; 389 } 390 391 /// Returns the offset of the index with an inrange attachment, or 392 /// std::nullopt if none. getInRangeIndex()393 std::optional<unsigned> getInRangeIndex() const { 394 if (SubclassOptionalData >> 1 == 0) 395 return std::nullopt; 396 return (SubclassOptionalData >> 1) - 1; 397 } 398 idx_begin()399 inline op_iterator idx_begin() { return op_begin()+1; } idx_begin()400 inline const_op_iterator idx_begin() const { return op_begin()+1; } idx_end()401 inline op_iterator idx_end() { return op_end(); } idx_end()402 inline const_op_iterator idx_end() const { return op_end(); } 403 indices()404 inline iterator_range<op_iterator> indices() { 405 return make_range(idx_begin(), idx_end()); 406 } 407 indices()408 inline iterator_range<const_op_iterator> indices() const { 409 return make_range(idx_begin(), idx_end()); 410 } 411 getPointerOperand()412 Value *getPointerOperand() { 413 return getOperand(0); 414 } getPointerOperand()415 const Value *getPointerOperand() const { 416 return getOperand(0); 417 } getPointerOperandIndex()418 static unsigned getPointerOperandIndex() { 419 return 0U; // get index for modifying correct operand 420 } 421 422 /// Method to return the pointer operand as a PointerType. getPointerOperandType()423 Type *getPointerOperandType() const { 424 return getPointerOperand()->getType(); 425 } 426 427 Type *getSourceElementType() const; 428 Type *getResultElementType() const; 429 430 /// Method to return the address space of the pointer operand. getPointerAddressSpace()431 unsigned getPointerAddressSpace() const { 432 return getPointerOperandType()->getPointerAddressSpace(); 433 } 434 getNumIndices()435 unsigned getNumIndices() const { // Note: always non-negative 436 return getNumOperands() - 1; 437 } 438 hasIndices()439 bool hasIndices() const { 440 return getNumOperands() > 1; 441 } 442 443 /// Return true if all of the indices of this GEP are zeros. 444 /// If so, the result pointer and the first operand have the same 445 /// value, just potentially different types. hasAllZeroIndices()446 bool hasAllZeroIndices() const { 447 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 448 if (ConstantInt *C = dyn_cast<ConstantInt>(I)) 449 if (C->isZero()) 450 continue; 451 return false; 452 } 453 return true; 454 } 455 456 /// Return true if all of the indices of this GEP are constant integers. 457 /// If so, the result pointer and the first operand have 458 /// a constant offset between them. hasAllConstantIndices()459 bool hasAllConstantIndices() const { 460 for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { 461 if (!isa<ConstantInt>(I)) 462 return false; 463 } 464 return true; 465 } 466 countNonConstantIndices()467 unsigned countNonConstantIndices() const { 468 return count_if(indices(), [](const Use& use) { 469 return !isa<ConstantInt>(*use); 470 }); 471 } 472 473 /// Compute the maximum alignment that this GEP is garranteed to preserve. 474 Align getMaxPreservedAlignment(const DataLayout &DL) const; 475 476 /// Accumulate the constant address offset of this GEP if possible. 477 /// 478 /// This routine accepts an APInt into which it will try to accumulate the 479 /// constant offset of this GEP. 480 /// 481 /// If \p ExternalAnalysis is provided it will be used to calculate a offset 482 /// when a operand of GEP is not constant. 483 /// For example, for a value \p ExternalAnalysis might try to calculate a 484 /// lower bound. If \p ExternalAnalysis is successful, it should return true. 485 /// 486 /// If the \p ExternalAnalysis returns false or the value returned by \p 487 /// ExternalAnalysis results in a overflow/underflow, this routine returns 488 /// false and the value of the offset APInt is undefined (it is *not* 489 /// preserved!). 490 /// 491 /// The APInt passed into this routine must be at exactly as wide as the 492 /// IntPtr type for the address space of the base GEP pointer. 493 bool accumulateConstantOffset( 494 const DataLayout &DL, APInt &Offset, 495 function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const; 496 497 static bool accumulateConstantOffset( 498 Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL, 499 APInt &Offset, 500 function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr); 501 502 /// Collect the offset of this GEP as a map of Values to their associated 503 /// APInt multipliers, as well as a total Constant Offset. 504 bool collectOffset(const DataLayout &DL, unsigned BitWidth, 505 MapVector<Value *, APInt> &VariableOffsets, 506 APInt &ConstantOffset) const; 507 }; 508 509 class PtrToIntOperator 510 : public ConcreteOperator<Operator, Instruction::PtrToInt> { 511 friend class PtrToInt; 512 friend class ConstantExpr; 513 514 public: getPointerOperand()515 Value *getPointerOperand() { 516 return getOperand(0); 517 } getPointerOperand()518 const Value *getPointerOperand() const { 519 return getOperand(0); 520 } 521 getPointerOperandIndex()522 static unsigned getPointerOperandIndex() { 523 return 0U; // get index for modifying correct operand 524 } 525 526 /// Method to return the pointer operand as a PointerType. getPointerOperandType()527 Type *getPointerOperandType() const { 528 return getPointerOperand()->getType(); 529 } 530 531 /// Method to return the address space of the pointer operand. getPointerAddressSpace()532 unsigned getPointerAddressSpace() const { 533 return cast<PointerType>(getPointerOperandType())->getAddressSpace(); 534 } 535 }; 536 537 class BitCastOperator 538 : public ConcreteOperator<Operator, Instruction::BitCast> { 539 friend class BitCastInst; 540 friend class ConstantExpr; 541 542 public: getSrcTy()543 Type *getSrcTy() const { 544 return getOperand(0)->getType(); 545 } 546 getDestTy()547 Type *getDestTy() const { 548 return getType(); 549 } 550 }; 551 552 class AddrSpaceCastOperator 553 : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> { 554 friend class AddrSpaceCastInst; 555 friend class ConstantExpr; 556 557 public: getPointerOperand()558 Value *getPointerOperand() { return getOperand(0); } 559 getPointerOperand()560 const Value *getPointerOperand() const { return getOperand(0); } 561 getSrcAddressSpace()562 unsigned getSrcAddressSpace() const { 563 return getPointerOperand()->getType()->getPointerAddressSpace(); 564 } 565 getDestAddressSpace()566 unsigned getDestAddressSpace() const { 567 return getType()->getPointerAddressSpace(); 568 } 569 }; 570 571 } // end namespace llvm 572 573 #endif // LLVM_IR_OPERATOR_H 574