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