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