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.
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.
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 
57   static bool classof(const Instruction *) { return true; }
58   static bool classof(const ConstantExpr *) { return true; }
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 
87   void setHasNoUnsignedWrap(bool B) {
88     SubclassOptionalData =
89       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
90   }
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.
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.
105   bool hasNoSignedWrap() const {
106     return (SubclassOptionalData & NoSignedWrap) != 0;
107   }
108 
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   }
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   }
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 
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.
145   bool isExact() const {
146     return SubclassOptionalData & IsExact;
147   }
148 
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 
156   static bool classof(const ConstantExpr *CE) {
157     return isPossiblyExactOpcode(CE->getOpcode());
158   }
159   static bool classof(const Instruction *I) {
160     return isPossiblyExactOpcode(I->getOpcode());
161   }
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.
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 
185   void setHasAllowReassoc(bool B) {
186     SubclassOptionalData =
187     (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
188     (B * FastMathFlags::AllowReassoc);
189   }
190 
191   void setHasNoNaNs(bool B) {
192     SubclassOptionalData =
193       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
194       (B * FastMathFlags::NoNaNs);
195   }
196 
197   void setHasNoInfs(bool B) {
198     SubclassOptionalData =
199       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
200       (B * FastMathFlags::NoInfs);
201   }
202 
203   void setHasNoSignedZeros(bool B) {
204     SubclassOptionalData =
205       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
206       (B * FastMathFlags::NoSignedZeros);
207   }
208 
209   void setHasAllowReciprocal(bool B) {
210     SubclassOptionalData =
211       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
212       (B * FastMathFlags::AllowReciprocal);
213   }
214 
215   void setHasAllowContract(bool B) {
216     SubclassOptionalData =
217         (SubclassOptionalData & ~FastMathFlags::AllowContract) |
218         (B * FastMathFlags::AllowContract);
219   }
220 
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.
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.
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.
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.
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.
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.
262   bool hasNoInfs() const {
263     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
264   }
265 
266   /// Test if this operation can ignore the sign of zero.
267   bool hasNoSignedZeros() const {
268     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
269   }
270 
271   /// Test if this operation can use reciprocal multiply instead of division.
272   bool hasAllowReciprocal() const {
273     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
274   }
275 
276   /// Test if this operation can be floating-point contracted (FMA).
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.
283   bool hasApproxFunc() const {
284     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
285   }
286 
287   /// Convenience function for getting all the fast-math flags
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 
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:
338   static bool classof(const Instruction *I) {
339     return I->getOpcode() == Opc;
340   }
341   static bool classof(const ConstantExpr *CE) {
342     return CE->getOpcode() == Opc;
343   }
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 SDivOperator
364   : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
365 };
366 class UDivOperator
367   : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
368 };
369 class AShrOperator
370   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
371 };
372 class LShrOperator
373   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
374 };
375 
376 class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
377 
378 class GEPOperator
379   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
380   friend class GetElementPtrInst;
381   friend class ConstantExpr;
382 
383   enum {
384     IsInBounds = (1 << 0),
385     // InRangeIndex: bits 1-6
386   };
387 
388   void setIsInBounds(bool B) {
389     SubclassOptionalData =
390       (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
391   }
392 
393 public:
394   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
395   bool isInBounds() const {
396     return SubclassOptionalData & IsInBounds;
397   }
398 
399   /// Returns the offset of the index with an inrange attachment, or
400   /// std::nullopt if none.
401   std::optional<unsigned> getInRangeIndex() const {
402     if (SubclassOptionalData >> 1 == 0)
403       return std::nullopt;
404     return (SubclassOptionalData >> 1) - 1;
405   }
406 
407   inline op_iterator       idx_begin()       { return op_begin()+1; }
408   inline const_op_iterator idx_begin() const { return op_begin()+1; }
409   inline op_iterator       idx_end()         { return op_end(); }
410   inline const_op_iterator idx_end()   const { return op_end(); }
411 
412   inline iterator_range<op_iterator> indices() {
413     return make_range(idx_begin(), idx_end());
414   }
415 
416   inline iterator_range<const_op_iterator> indices() const {
417     return make_range(idx_begin(), idx_end());
418   }
419 
420   Value *getPointerOperand() {
421     return getOperand(0);
422   }
423   const Value *getPointerOperand() const {
424     return getOperand(0);
425   }
426   static unsigned getPointerOperandIndex() {
427     return 0U;                      // get index for modifying correct operand
428   }
429 
430   /// Method to return the pointer operand as a PointerType.
431   Type *getPointerOperandType() const {
432     return getPointerOperand()->getType();
433   }
434 
435   Type *getSourceElementType() const;
436   Type *getResultElementType() const;
437 
438   /// Method to return the address space of the pointer operand.
439   unsigned getPointerAddressSpace() const {
440     return getPointerOperandType()->getPointerAddressSpace();
441   }
442 
443   unsigned getNumIndices() const {  // Note: always non-negative
444     return getNumOperands() - 1;
445   }
446 
447   bool hasIndices() const {
448     return getNumOperands() > 1;
449   }
450 
451   /// Return true if all of the indices of this GEP are zeros.
452   /// If so, the result pointer and the first operand have the same
453   /// value, just potentially different types.
454   bool hasAllZeroIndices() const {
455     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
456       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
457         if (C->isZero())
458           continue;
459       return false;
460     }
461     return true;
462   }
463 
464   /// Return true if all of the indices of this GEP are constant integers.
465   /// If so, the result pointer and the first operand have
466   /// a constant offset between them.
467   bool hasAllConstantIndices() const {
468     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
469       if (!isa<ConstantInt>(I))
470         return false;
471     }
472     return true;
473   }
474 
475   unsigned countNonConstantIndices() const {
476     return count_if(indices(), [](const Use& use) {
477         return !isa<ConstantInt>(*use);
478       });
479   }
480 
481   /// Compute the maximum alignment that this GEP is garranteed to preserve.
482   Align getMaxPreservedAlignment(const DataLayout &DL) const;
483 
484   /// Accumulate the constant address offset of this GEP if possible.
485   ///
486   /// This routine accepts an APInt into which it will try to accumulate the
487   /// constant offset of this GEP.
488   ///
489   /// If \p ExternalAnalysis is provided it will be used to calculate a offset
490   /// when a operand of GEP is not constant.
491   /// For example, for a value \p ExternalAnalysis might try to calculate a
492   /// lower bound. If \p ExternalAnalysis is successful, it should return true.
493   ///
494   /// If the \p ExternalAnalysis returns false or the value returned by \p
495   /// ExternalAnalysis results in a overflow/underflow, this routine returns
496   /// false and the value of the offset APInt is undefined (it is *not*
497   /// preserved!).
498   ///
499   /// The APInt passed into this routine must be at exactly as wide as the
500   /// IntPtr type for the address space of the base GEP pointer.
501   bool accumulateConstantOffset(
502       const DataLayout &DL, APInt &Offset,
503       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
504 
505   static bool accumulateConstantOffset(
506       Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
507       APInt &Offset,
508       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
509 
510   /// Collect the offset of this GEP as a map of Values to their associated
511   /// APInt multipliers, as well as a total Constant Offset.
512   bool collectOffset(const DataLayout &DL, unsigned BitWidth,
513                      MapVector<Value *, APInt> &VariableOffsets,
514                      APInt &ConstantOffset) const;
515 };
516 
517 class PtrToIntOperator
518     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
519   friend class PtrToInt;
520   friend class ConstantExpr;
521 
522 public:
523   Value *getPointerOperand() {
524     return getOperand(0);
525   }
526   const Value *getPointerOperand() const {
527     return getOperand(0);
528   }
529 
530   static unsigned getPointerOperandIndex() {
531     return 0U;                      // get index for modifying correct operand
532   }
533 
534   /// Method to return the pointer operand as a PointerType.
535   Type *getPointerOperandType() const {
536     return getPointerOperand()->getType();
537   }
538 
539   /// Method to return the address space of the pointer operand.
540   unsigned getPointerAddressSpace() const {
541     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
542   }
543 };
544 
545 class BitCastOperator
546     : public ConcreteOperator<Operator, Instruction::BitCast> {
547   friend class BitCastInst;
548   friend class ConstantExpr;
549 
550 public:
551   Type *getSrcTy() const {
552     return getOperand(0)->getType();
553   }
554 
555   Type *getDestTy() const {
556     return getType();
557   }
558 };
559 
560 class AddrSpaceCastOperator
561     : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
562   friend class AddrSpaceCastInst;
563   friend class ConstantExpr;
564 
565 public:
566   Value *getPointerOperand() { return getOperand(0); }
567 
568   const Value *getPointerOperand() const { return getOperand(0); }
569 
570   unsigned getSrcAddressSpace() const {
571     return getPointerOperand()->getType()->getPointerAddressSpace();
572   }
573 
574   unsigned getDestAddressSpace() const {
575     return getType()->getPointerAddressSpace();
576   }
577 };
578 
579 } // end namespace llvm
580 
581 #endif // LLVM_IR_OPERATOR_H
582