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