xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/Operator.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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