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