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