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