Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
ConstantFolding.cpp
Go to the documentation of this file.
1//===-- ConstantFolding.cpp - Fold instructions into constants ------------===//
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 routines for folding instructions into constants.
10//
11// Also, to supplement the basic IR ConstantExpr simplifications,
12// this file defines some additional folding routines that can make use of
13// DataLayout information. These functions cannot go in IR due to library
14// dependency issues.
15//
16//===----------------------------------------------------------------------===//
17
18#include "llvm/Analysis/ConstantFolding.h"
19#include "llvm/ADT/APFloat.h"
20#include "llvm/ADT/APInt.h"
21#include "llvm/ADT/APSInt.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/Analysis/TargetFolder.h"
28#include "llvm/Analysis/TargetLibraryInfo.h"
29#include "llvm/Analysis/ValueTracking.h"
30#include "llvm/Analysis/VectorUtils.h"
31#include "llvm/Config/config.h"
32#include "llvm/IR/Constant.h"
33#include "llvm/IR/ConstantFold.h"
34#include "llvm/IR/Constants.h"
35#include "llvm/IR/DataLayout.h"
36#include "llvm/IR/DerivedTypes.h"
37#include "llvm/IR/Function.h"
38#include "llvm/IR/GlobalValue.h"
39#include "llvm/IR/GlobalVariable.h"
40#include "llvm/IR/InstrTypes.h"
41#include "llvm/IR/Instruction.h"
42#include "llvm/IR/Instructions.h"
43#include "llvm/IR/IntrinsicInst.h"
44#include "llvm/IR/Intrinsics.h"
45#include "llvm/IR/IntrinsicsAArch64.h"
46#include "llvm/IR/IntrinsicsAMDGPU.h"
47#include "llvm/IR/IntrinsicsARM.h"
48#include "llvm/IR/IntrinsicsNVPTX.h"
49#include "llvm/IR/IntrinsicsWebAssembly.h"
50#include "llvm/IR/IntrinsicsX86.h"
51#include "llvm/IR/NVVMIntrinsicUtils.h"
52#include "llvm/IR/Operator.h"
53#include "llvm/IR/Type.h"
54#include "llvm/IR/Value.h"
55#include "llvm/Support/Casting.h"
56#include "llvm/Support/ErrorHandling.h"
57#include "llvm/Support/KnownBits.h"
58#include "llvm/Support/MathExtras.h"
59#include <cassert>
60#include <cerrno>
61#include <cfenv>
62#include <cmath>
63#include <cstdint>
64
65using namespacellvm;
66
67namespace{
68
69//===----------------------------------------------------------------------===//
70// Constant Folding internal helper functions
71//===----------------------------------------------------------------------===//
72
73staticConstant *foldConstVectorToAPInt(APInt &Result,Type *DestTy,
74Constant *C,Type *SrcEltTy,
75unsigned NumSrcElts,
76constDataLayout &DL) {
77// Now that we know that the input value is a vector of integers, just shift
78// and insert them into our result.
79unsigned BitShift =DL.getTypeSizeInBits(SrcEltTy);
80for (unsigned i = 0; i != NumSrcElts; ++i) {
81Constant *Element;
82if (DL.isLittleEndian())
83 Element =C->getAggregateElement(NumSrcElts - i - 1);
84else
85 Element =C->getAggregateElement(i);
86
87if (isa_and_nonnull<UndefValue>(Element)) {
88Result <<= BitShift;
89continue;
90 }
91
92auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
93if (!ElementCI)
94returnConstantExpr::getBitCast(C, DestTy);
95
96Result <<= BitShift;
97Result |= ElementCI->getValue().zext(Result.getBitWidth());
98 }
99
100returnnullptr;
101}
102
103/// Constant fold bitcast, symbolically evaluating it with DataLayout.
104/// This always returns a non-null constant, but it may be a
105/// ConstantExpr if unfoldable.
106Constant *FoldBitCast(Constant *C,Type *DestTy,constDataLayout &DL) {
107assert(CastInst::castIsValid(Instruction::BitCast,C, DestTy) &&
108"Invalid constantexpr bitcast!");
109
110// Catch the obvious splat cases.
111if (Constant *Res =ConstantFoldLoadFromUniformValue(C, DestTy,DL))
112return Res;
113
114if (auto *VTy = dyn_cast<VectorType>(C->getType())) {
115// Handle a vector->scalar integer/fp cast.
116if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {
117unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
118Type *SrcEltTy = VTy->getElementType();
119
120// If the vector is a vector of floating point, convert it to vector of int
121// to simplify things.
122if (SrcEltTy->isFloatingPointTy()) {
123unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
124auto *SrcIVTy =FixedVectorType::get(
125IntegerType::get(C->getContext(), FPWidth), NumSrcElts);
126// Ask IR to do the conversion now that #elts line up.
127C =ConstantExpr::getBitCast(C, SrcIVTy);
128 }
129
130APIntResult(DL.getTypeSizeInBits(DestTy), 0);
131if (Constant *CE = foldConstVectorToAPInt(Result, DestTy,C,
132 SrcEltTy, NumSrcElts,DL))
133returnCE;
134
135if (isa<IntegerType>(DestTy))
136return ConstantInt::get(DestTy, Result);
137
138APFloatFP(DestTy->getFltSemantics(), Result);
139return ConstantFP::get(DestTy->getContext(),FP);
140 }
141 }
142
143// The code below only handles casts to vectors currently.
144auto *DestVTy = dyn_cast<VectorType>(DestTy);
145if (!DestVTy)
146returnConstantExpr::getBitCast(C, DestTy);
147
148// If this is a scalar -> vector cast, convert the input into a <1 x scalar>
149// vector so the code below can handle it uniformly.
150if (!isa<VectorType>(C->getType()) &&
151 (isa<ConstantFP>(C) || isa<ConstantInt>(C))) {
152Constant *Ops =C;// don't take the address of C!
153returnFoldBitCast(ConstantVector::get(Ops), DestTy,DL);
154 }
155
156// Some of what follows may extend to cover scalable vectors but the current
157// implementation is fixed length specific.
158if (!isa<FixedVectorType>(C->getType()))
159returnConstantExpr::getBitCast(C, DestTy);
160
161// If this is a bitcast from constant vector -> vector, fold it.
162if (!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C) &&
163 !isa<ConstantInt>(C) && !isa<ConstantFP>(C))
164returnConstantExpr::getBitCast(C, DestTy);
165
166// If the element types match, IR can fold it.
167unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
168unsigned NumSrcElt = cast<FixedVectorType>(C->getType())->getNumElements();
169if (NumDstElt == NumSrcElt)
170returnConstantExpr::getBitCast(C, DestTy);
171
172Type *SrcEltTy = cast<VectorType>(C->getType())->getElementType();
173Type *DstEltTy = DestVTy->getElementType();
174
175// Otherwise, we're changing the number of elements in a vector, which
176// requires endianness information to do the right thing. For example,
177// bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)
178// folds to (little endian):
179// <4 x i32> <i32 0, i32 0, i32 1, i32 0>
180// and to (big endian):
181// <4 x i32> <i32 0, i32 0, i32 0, i32 1>
182
183// First thing is first. We only want to think about integer here, so if
184// we have something in FP form, recast it as integer.
185if (DstEltTy->isFloatingPointTy()) {
186// Fold to an vector of integers with same size as our FP type.
187unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits();
188auto *DestIVTy =FixedVectorType::get(
189IntegerType::get(C->getContext(), FPWidth), NumDstElt);
190// Recursively handle this integer conversion, if possible.
191C =FoldBitCast(C, DestIVTy,DL);
192
193// Finally, IR can handle this now that #elts line up.
194returnConstantExpr::getBitCast(C, DestTy);
195 }
196
197// Okay, we know the destination is integer, if the input is FP, convert
198// it to integer first.
199if (SrcEltTy->isFloatingPointTy()) {
200unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();
201auto *SrcIVTy =FixedVectorType::get(
202IntegerType::get(C->getContext(), FPWidth), NumSrcElt);
203// Ask IR to do the conversion now that #elts line up.
204C =ConstantExpr::getBitCast(C, SrcIVTy);
205assert((isa<ConstantVector>(C) ||// FIXME: Remove ConstantVector.
206 isa<ConstantDataVector>(C) || isa<ConstantInt>(C)) &&
207"Constant folding cannot fail for plain fp->int bitcast!");
208 }
209
210// Now we know that the input and output vectors are both integer vectors
211// of the same size, and that their #elements is not the same. Do the
212// conversion here, which depends on whether the input or output has
213// more elements.
214bool isLittleEndian =DL.isLittleEndian();
215
216SmallVector<Constant*, 32>Result;
217if (NumDstElt < NumSrcElt) {
218// Handle: bitcast (<4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>)
219Constant *Zero =Constant::getNullValue(DstEltTy);
220unsigned Ratio = NumSrcElt/NumDstElt;
221unsigned SrcBitSize = SrcEltTy->getPrimitiveSizeInBits();
222unsigned SrcElt = 0;
223for (unsigned i = 0; i != NumDstElt; ++i) {
224// Build each element of the result.
225Constant *Elt =Zero;
226unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1);
227for (unsigned j = 0;j != Ratio; ++j) {
228Constant *Src =C->getAggregateElement(SrcElt++);
229if (isa_and_nonnull<UndefValue>(Src))
230 Src =Constant::getNullValue(
231 cast<VectorType>(C->getType())->getElementType());
232else
233 Src = dyn_cast_or_null<ConstantInt>(Src);
234if (!Src)// Reject constantexpr elements.
235returnConstantExpr::getBitCast(C, DestTy);
236
237// Zero extend the element to the right size.
238 Src =ConstantFoldCastOperand(Instruction::ZExt, Src, Elt->getType(),
239DL);
240assert(Src &&"Constant folding cannot fail on plain integers");
241
242// Shift it to the right place, depending on endianness.
243 Src =ConstantFoldBinaryOpOperands(
244 Instruction::Shl, Src, ConstantInt::get(Src->getType(), ShiftAmt),
245DL);
246assert(Src &&"Constant folding cannot fail on plain integers");
247
248 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
249
250// Mix it in.
251 Elt =ConstantFoldBinaryOpOperands(Instruction::Or, Elt, Src,DL);
252assert(Elt &&"Constant folding cannot fail on plain integers");
253 }
254Result.push_back(Elt);
255 }
256returnConstantVector::get(Result);
257 }
258
259// Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)
260unsigned Ratio = NumDstElt/NumSrcElt;
261unsigned DstBitSize =DL.getTypeSizeInBits(DstEltTy);
262
263// Loop over each source value, expanding into multiple results.
264for (unsigned i = 0; i != NumSrcElt; ++i) {
265auto *Element =C->getAggregateElement(i);
266
267if (!Element)// Reject constantexpr elements.
268returnConstantExpr::getBitCast(C, DestTy);
269
270if (isa<UndefValue>(Element)) {
271// Correctly Propagate undef values.
272Result.append(Ratio,UndefValue::get(DstEltTy));
273continue;
274 }
275
276auto *Src = dyn_cast<ConstantInt>(Element);
277if (!Src)
278returnConstantExpr::getBitCast(C, DestTy);
279
280unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1);
281for (unsigned j = 0;j != Ratio; ++j) {
282// Shift the piece of the value into the right place, depending on
283// endianness.
284APInt Elt = Src->getValue().lshr(ShiftAmt);
285 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
286
287// Truncate and remember this piece.
288Result.push_back(ConstantInt::get(DstEltTy, Elt.trunc(DstBitSize)));
289 }
290 }
291
292returnConstantVector::get(Result);
293}
294
295}// end anonymous namespace
296
297/// If this constant is a constant offset from a global, return the global and
298/// the constant. Because of constantexprs, this function is recursive.
299boolllvm::IsConstantOffsetFromGlobal(Constant *C,GlobalValue *&GV,
300APInt &Offset,constDataLayout &DL,
301DSOLocalEquivalent **DSOEquiv) {
302if (DSOEquiv)
303 *DSOEquiv =nullptr;
304
305// Trivial case, constant is the global.
306if ((GV = dyn_cast<GlobalValue>(C))) {
307unsignedBitWidth =DL.getIndexTypeSizeInBits(GV->getType());
308Offset =APInt(BitWidth, 0);
309returntrue;
310 }
311
312if (auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(C)) {
313if (DSOEquiv)
314 *DSOEquiv = FoundDSOEquiv;
315 GV = FoundDSOEquiv->getGlobalValue();
316unsignedBitWidth =DL.getIndexTypeSizeInBits(GV->getType());
317Offset =APInt(BitWidth, 0);
318returntrue;
319 }
320
321// Otherwise, if this isn't a constant expr, bail out.
322auto *CE = dyn_cast<ConstantExpr>(C);
323if (!CE)returnfalse;
324
325// Look through ptr->int and ptr->ptr casts.
326if (CE->getOpcode() == Instruction::PtrToInt ||
327 CE->getOpcode() == Instruction::BitCast)
328returnIsConstantOffsetFromGlobal(CE->getOperand(0), GV,Offset,DL,
329 DSOEquiv);
330
331// i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)
332auto *GEP = dyn_cast<GEPOperator>(CE);
333if (!GEP)
334returnfalse;
335
336unsignedBitWidth =DL.getIndexTypeSizeInBits(GEP->getType());
337APInt TmpOffset(BitWidth, 0);
338
339// If the base isn't a global+constant, we aren't either.
340if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, TmpOffset,DL,
341 DSOEquiv))
342returnfalse;
343
344// Otherwise, add any offset that our operands provide.
345if (!GEP->accumulateConstantOffset(DL, TmpOffset))
346returnfalse;
347
348Offset = TmpOffset;
349returntrue;
350}
351
352Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C,Type *DestTy,
353constDataLayout &DL) {
354do {
355Type *SrcTy =C->getType();
356if (SrcTy == DestTy)
357returnC;
358
359TypeSize DestSize =DL.getTypeSizeInBits(DestTy);
360TypeSize SrcSize =DL.getTypeSizeInBits(SrcTy);
361if (!TypeSize::isKnownGE(SrcSize, DestSize))
362returnnullptr;
363
364// Catch the obvious splat cases (since all-zeros can coerce non-integral
365// pointers legally).
366if (Constant *Res =ConstantFoldLoadFromUniformValue(C, DestTy,DL))
367return Res;
368
369// If the type sizes are the same and a cast is legal, just directly
370// cast the constant.
371// But be careful not to coerce non-integral pointers illegally.
372if (SrcSize == DestSize &&
373DL.isNonIntegralPointerType(SrcTy->getScalarType()) ==
374DL.isNonIntegralPointerType(DestTy->getScalarType())) {
375Instruction::CastOps Cast = Instruction::BitCast;
376// If we are going from a pointer to int or vice versa, we spell the cast
377// differently.
378if (SrcTy->isIntegerTy() && DestTy->isPointerTy())
379 Cast = Instruction::IntToPtr;
380elseif (SrcTy->isPointerTy() && DestTy->isIntegerTy())
381 Cast = Instruction::PtrToInt;
382
383if (CastInst::castIsValid(Cast,C, DestTy))
384returnConstantFoldCastOperand(Cast,C, DestTy,DL);
385 }
386
387// If this isn't an aggregate type, there is nothing we can do to drill down
388// and find a bitcastable constant.
389if (!SrcTy->isAggregateType() && !SrcTy->isVectorTy())
390returnnullptr;
391
392// We're simulating a load through a pointer that was bitcast to point to
393// a different type, so we can try to walk down through the initial
394// elements of an aggregate to see if some part of the aggregate is
395// castable to implement the "load" semantic model.
396if (SrcTy->isStructTy()) {
397// Struct types might have leading zero-length elements like [0 x i32],
398// which are certainly not what we are looking for, so skip them.
399unsigned Elem = 0;
400Constant *ElemC;
401do {
402 ElemC =C->getAggregateElement(Elem++);
403 }while (ElemC &&DL.getTypeSizeInBits(ElemC->getType()).isZero());
404C = ElemC;
405 }else {
406// For non-byte-sized vector elements, the first element is not
407// necessarily located at the vector base address.
408if (auto *VT = dyn_cast<VectorType>(SrcTy))
409if (!DL.typeSizeEqualsStoreSize(VT->getElementType()))
410returnnullptr;
411
412C =C->getAggregateElement(0u);
413 }
414 }while (C);
415
416returnnullptr;
417}
418
419namespace{
420
421/// Recursive helper to read bits out of global. C is the constant being copied
422/// out of. ByteOffset is an offset into C. CurPtr is the pointer to copy
423/// results into and BytesLeft is the number of bytes left in
424/// the CurPtr buffer. DL is the DataLayout.
425bool ReadDataFromGlobal(Constant *C,uint64_t ByteOffset,unsignedchar *CurPtr,
426unsigned BytesLeft,constDataLayout &DL) {
427assert(ByteOffset <=DL.getTypeAllocSize(C->getType()) &&
428"Out of range access");
429
430// If this element is zero or undefined, we can just return since *CurPtr is
431// zero initialized.
432if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
433returntrue;
434
435if (auto *CI = dyn_cast<ConstantInt>(C)) {
436if ((CI->getBitWidth() & 7) != 0)
437returnfalse;
438constAPInt &Val = CI->getValue();
439unsigned IntBytes =unsigned(CI->getBitWidth()/8);
440
441for (unsigned i = 0; i != BytesLeft && ByteOffset != IntBytes; ++i) {
442unsigned n = ByteOffset;
443if (!DL.isLittleEndian())
444 n = IntBytes - n - 1;
445 CurPtr[i] = Val.extractBits(8, n * 8).getZExtValue();
446 ++ByteOffset;
447 }
448returntrue;
449 }
450
451if (auto *CFP = dyn_cast<ConstantFP>(C)) {
452if (CFP->getType()->isDoubleTy()) {
453C =FoldBitCast(C,Type::getInt64Ty(C->getContext()),DL);
454return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft,DL);
455 }
456if (CFP->getType()->isFloatTy()){
457C =FoldBitCast(C,Type::getInt32Ty(C->getContext()),DL);
458return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft,DL);
459 }
460if (CFP->getType()->isHalfTy()){
461C =FoldBitCast(C,Type::getInt16Ty(C->getContext()),DL);
462return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft,DL);
463 }
464returnfalse;
465 }
466
467if (auto *CS = dyn_cast<ConstantStruct>(C)) {
468constStructLayout *SL =DL.getStructLayout(CS->getType());
469unsignedIndex = SL->getElementContainingOffset(ByteOffset);
470uint64_t CurEltOffset = SL->getElementOffset(Index);
471 ByteOffset -= CurEltOffset;
472
473while (true) {
474// If the element access is to the element itself and not to tail padding,
475// read the bytes from the element.
476uint64_t EltSize =DL.getTypeAllocSize(CS->getOperand(Index)->getType());
477
478if (ByteOffset < EltSize &&
479 !ReadDataFromGlobal(CS->getOperand(Index), ByteOffset, CurPtr,
480 BytesLeft,DL))
481returnfalse;
482
483 ++Index;
484
485// Check to see if we read from the last struct element, if so we're done.
486if (Index == CS->getType()->getNumElements())
487returntrue;
488
489// If we read all of the bytes we needed from this element we're done.
490uint64_t NextEltOffset = SL->getElementOffset(Index);
491
492if (BytesLeft <= NextEltOffset - CurEltOffset - ByteOffset)
493returntrue;
494
495// Move to the next element of the struct.
496 CurPtr += NextEltOffset - CurEltOffset - ByteOffset;
497 BytesLeft -= NextEltOffset - CurEltOffset - ByteOffset;
498 ByteOffset = 0;
499 CurEltOffset = NextEltOffset;
500 }
501// not reached.
502 }
503
504if (isa<ConstantArray>(C) || isa<ConstantVector>(C) ||
505 isa<ConstantDataSequential>(C)) {
506uint64_t NumElts, EltSize;
507Type *EltTy;
508if (auto *AT = dyn_cast<ArrayType>(C->getType())) {
509 NumElts = AT->getNumElements();
510 EltTy = AT->getElementType();
511 EltSize =DL.getTypeAllocSize(EltTy);
512 }else {
513 NumElts = cast<FixedVectorType>(C->getType())->getNumElements();
514 EltTy = cast<FixedVectorType>(C->getType())->getElementType();
515// TODO: For non-byte-sized vectors, current implementation assumes there is
516// padding to the next byte boundary between elements.
517if (!DL.typeSizeEqualsStoreSize(EltTy))
518returnfalse;
519
520 EltSize =DL.getTypeStoreSize(EltTy);
521 }
522uint64_tIndex = ByteOffset / EltSize;
523uint64_tOffset = ByteOffset -Index * EltSize;
524
525for (;Index != NumElts; ++Index) {
526if (!ReadDataFromGlobal(C->getAggregateElement(Index),Offset, CurPtr,
527 BytesLeft,DL))
528returnfalse;
529
530uint64_t BytesWritten = EltSize -Offset;
531assert(BytesWritten <= EltSize &&"Not indexing into this element?");
532if (BytesWritten >= BytesLeft)
533returntrue;
534
535Offset = 0;
536 BytesLeft -= BytesWritten;
537 CurPtr += BytesWritten;
538 }
539returntrue;
540 }
541
542if (auto *CE = dyn_cast<ConstantExpr>(C)) {
543if (CE->getOpcode() == Instruction::IntToPtr &&
544CE->getOperand(0)->getType() ==DL.getIntPtrType(CE->getType())) {
545return ReadDataFromGlobal(CE->getOperand(0), ByteOffset, CurPtr,
546 BytesLeft,DL);
547 }
548 }
549
550// Otherwise, unknown initializer type.
551returnfalse;
552}
553
554Constant *FoldReinterpretLoadFromConst(Constant *C,Type *LoadTy,
555 int64_tOffset,constDataLayout &DL) {
556// Bail out early. Not expect to load from scalable global variable.
557if (isa<ScalableVectorType>(LoadTy))
558returnnullptr;
559
560auto *IntType = dyn_cast<IntegerType>(LoadTy);
561
562// If this isn't an integer load we can't fold it directly.
563if (!IntType) {
564// If this is a non-integer load, we can try folding it as an int load and
565// then bitcast the result. This can be useful for union cases. Note
566// that address spaces don't matter here since we're not going to result in
567// an actual new load.
568if (!LoadTy->isFloatingPointTy() && !LoadTy->isPointerTy() &&
569 !LoadTy->isVectorTy())
570returnnullptr;
571
572Type *MapTy =Type::getIntNTy(C->getContext(),
573DL.getTypeSizeInBits(LoadTy).getFixedValue());
574if (Constant *Res = FoldReinterpretLoadFromConst(C, MapTy,Offset,DL)) {
575if (Res->isNullValue() && !LoadTy->isX86_AMXTy())
576// Materializing a zero can be done trivially without a bitcast
577returnConstant::getNullValue(LoadTy);
578Type *CastTy = LoadTy->isPtrOrPtrVectorTy() ?DL.getIntPtrType(LoadTy) : LoadTy;
579 Res =FoldBitCast(Res, CastTy,DL);
580if (LoadTy->isPtrOrPtrVectorTy()) {
581// For vector of pointer, we needed to first convert to a vector of integer, then do vector inttoptr
582if (Res->isNullValue() && !LoadTy->isX86_AMXTy())
583returnConstant::getNullValue(LoadTy);
584if (DL.isNonIntegralPointerType(LoadTy->getScalarType()))
585// Be careful not to replace a load of an addrspace value with an inttoptr here
586returnnullptr;
587 Res =ConstantExpr::getIntToPtr(Res, LoadTy);
588 }
589return Res;
590 }
591returnnullptr;
592 }
593
594unsigned BytesLoaded = (IntType->getBitWidth() + 7) / 8;
595if (BytesLoaded > 32 || BytesLoaded == 0)
596returnnullptr;
597
598// If we're not accessing anything in this constant, the result is undefined.
599if (Offset <= -1 *static_cast<int64_t>(BytesLoaded))
600returnPoisonValue::get(IntType);
601
602// TODO: We should be able to support scalable types.
603TypeSize InitializerSize =DL.getTypeAllocSize(C->getType());
604if (InitializerSize.isScalable())
605returnnullptr;
606
607// If we're not accessing anything in this constant, the result is undefined.
608if (Offset >= (int64_t)InitializerSize.getFixedValue())
609returnPoisonValue::get(IntType);
610
611unsignedchar RawBytes[32] = {0};
612unsignedchar *CurPtr = RawBytes;
613unsigned BytesLeft = BytesLoaded;
614
615// If we're loading off the beginning of the global, some bytes may be valid.
616if (Offset < 0) {
617 CurPtr += -Offset;
618 BytesLeft +=Offset;
619Offset = 0;
620 }
621
622if (!ReadDataFromGlobal(C,Offset, CurPtr, BytesLeft,DL))
623returnnullptr;
624
625APInt ResultVal =APInt(IntType->getBitWidth(), 0);
626if (DL.isLittleEndian()) {
627 ResultVal = RawBytes[BytesLoaded - 1];
628for (unsigned i = 1; i != BytesLoaded; ++i) {
629 ResultVal <<= 8;
630 ResultVal |= RawBytes[BytesLoaded - 1 - i];
631 }
632 }else {
633 ResultVal = RawBytes[0];
634for (unsigned i = 1; i != BytesLoaded; ++i) {
635 ResultVal <<= 8;
636 ResultVal |= RawBytes[i];
637 }
638 }
639
640return ConstantInt::get(IntType->getContext(), ResultVal);
641}
642
643}// anonymous namespace
644
645// If GV is a constant with an initializer read its representation starting
646// at Offset and return it as a constant array of unsigned char. Otherwise
647// return null.
648Constant *llvm::ReadByteArrayFromGlobal(constGlobalVariable *GV,
649uint64_tOffset) {
650if (!GV->isConstant() || !GV->hasDefinitiveInitializer())
651returnnullptr;
652
653constDataLayout &DL = GV->getDataLayout();
654Constant *Init =const_cast<Constant *>(GV->getInitializer());
655TypeSize InitSize =DL.getTypeAllocSize(Init->getType());
656if (InitSize <Offset)
657returnnullptr;
658
659uint64_t NBytes = InitSize -Offset;
660if (NBytes > UINT16_MAX)
661// Bail for large initializers in excess of 64K to avoid allocating
662// too much memory.
663// Offset is assumed to be less than or equal than InitSize (this
664// is enforced in ReadDataFromGlobal).
665returnnullptr;
666
667SmallVector<unsigned char, 256> RawBytes(static_cast<size_t>(NBytes));
668unsignedchar *CurPtr = RawBytes.data();
669
670if (!ReadDataFromGlobal(Init,Offset, CurPtr, NBytes,DL))
671returnnullptr;
672
673returnConstantDataArray::get(GV->getContext(), RawBytes);
674}
675
676/// If this Offset points exactly to the start of an aggregate element, return
677/// that element, otherwise return nullptr.
678Constant *getConstantAtOffset(Constant *Base,APIntOffset,
679constDataLayout &DL) {
680if (Offset.isZero())
681returnBase;
682
683if (!isa<ConstantAggregate>(Base) && !isa<ConstantDataSequential>(Base))
684returnnullptr;
685
686Type *ElemTy =Base->getType();
687SmallVector<APInt> Indices =DL.getGEPIndicesForOffset(ElemTy,Offset);
688if (!Offset.isZero() || !Indices[0].isZero())
689returnnullptr;
690
691Constant *C =Base;
692for (constAPInt &Index :drop_begin(Indices)) {
693if (Index.isNegative() || Index.getActiveBits() >= 32)
694returnnullptr;
695
696C =C->getAggregateElement(Index.getZExtValue());
697if (!C)
698returnnullptr;
699 }
700
701returnC;
702}
703
704Constant *llvm::ConstantFoldLoadFromConst(Constant *C,Type *Ty,
705constAPInt &Offset,
706constDataLayout &DL) {
707if (Constant *AtOffset =getConstantAtOffset(C,Offset,DL))
708if (Constant *Result =ConstantFoldLoadThroughBitcast(AtOffset, Ty,DL))
709return Result;
710
711// Explicitly check for out-of-bounds access, so we return poison even if the
712// constant is a uniform value.
713TypeSizeSize =DL.getTypeAllocSize(C->getType());
714if (!Size.isScalable() &&Offset.sge(Size.getFixedValue()))
715returnPoisonValue::get(Ty);
716
717// Try an offset-independent fold of a uniform value.
718if (Constant *Result =ConstantFoldLoadFromUniformValue(C, Ty,DL))
719return Result;
720
721// Try hard to fold loads from bitcasted strange and non-type-safe things.
722if (Offset.getSignificantBits() <= 64)
723if (Constant *Result =
724 FoldReinterpretLoadFromConst(C, Ty,Offset.getSExtValue(),DL))
725return Result;
726
727returnnullptr;
728}
729
730Constant *llvm::ConstantFoldLoadFromConst(Constant *C,Type *Ty,
731constDataLayout &DL) {
732returnConstantFoldLoadFromConst(C, Ty,APInt(64, 0),DL);
733}
734
735Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,Type *Ty,
736APIntOffset,
737constDataLayout &DL) {
738// We can only fold loads from constant globals with a definitive initializer.
739// Check this upfront, to skip expensive offset calculations.
740auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(C));
741if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
742returnnullptr;
743
744C = cast<Constant>(C->stripAndAccumulateConstantOffsets(
745DL,Offset,/* AllowNonInbounds */true));
746
747if (C == GV)
748if (Constant *Result =ConstantFoldLoadFromConst(GV->getInitializer(), Ty,
749Offset,DL))
750return Result;
751
752// If this load comes from anywhere in a uniform constant global, the value
753// is always the same, regardless of the loaded offset.
754returnConstantFoldLoadFromUniformValue(GV->getInitializer(), Ty,DL);
755}
756
757Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C,Type *Ty,
758constDataLayout &DL) {
759APIntOffset(DL.getIndexTypeSizeInBits(C->getType()), 0);
760returnConstantFoldLoadFromConstPtr(C, Ty, std::move(Offset),DL);
761}
762
763Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C,Type *Ty,
764constDataLayout &DL) {
765if (isa<PoisonValue>(C))
766returnPoisonValue::get(Ty);
767if (isa<UndefValue>(C))
768returnUndefValue::get(Ty);
769// If padding is needed when storing C to memory, then it isn't considered as
770// uniform.
771if (!DL.typeSizeEqualsStoreSize(C->getType()))
772returnnullptr;
773if (C->isNullValue() && !Ty->isX86_AMXTy())
774returnConstant::getNullValue(Ty);
775if (C->isAllOnesValue() &&
776 (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()))
777returnConstant::getAllOnesValue(Ty);
778returnnullptr;
779}
780
781namespace{
782
783/// One of Op0/Op1 is a constant expression.
784/// Attempt to symbolically evaluate the result of a binary operator merging
785/// these together. If target data info is available, it is provided as DL,
786/// otherwise DL is null.
787Constant *SymbolicallyEvaluateBinop(unsigned Opc,Constant *Op0,Constant *Op1,
788constDataLayout &DL) {
789// SROA
790
791// Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.
792// Fold (lshr (or X, Y), 32) -> (lshr [X/Y], 32) if one doesn't contribute
793// bits.
794
795if (Opc == Instruction::And) {
796KnownBits Known0 =computeKnownBits(Op0,DL);
797KnownBits Known1 =computeKnownBits(Op1,DL);
798if ((Known1.One | Known0.Zero).isAllOnes()) {
799// All the bits of Op0 that the 'and' could be masking are already zero.
800return Op0;
801 }
802if ((Known0.One | Known1.Zero).isAllOnes()) {
803// All the bits of Op1 that the 'and' could be masking are already zero.
804return Op1;
805 }
806
807 Known0 &= Known1;
808if (Known0.isConstant())
809return ConstantInt::get(Op0->getType(), Known0.getConstant());
810 }
811
812// If the constant expr is something like &A[123] - &A[4].f, fold this into a
813// constant. This happens frequently when iterating over a global array.
814if (Opc == Instruction::Sub) {
815GlobalValue *GV1, *GV2;
816APInt Offs1, Offs2;
817
818if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1,DL))
819if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2,DL) && GV1 == GV2) {
820unsigned OpSize =DL.getTypeSizeInBits(Op0->getType());
821
822// (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
823// PtrToInt may change the bitwidth so we have convert to the right size
824// first.
825return ConstantInt::get(Op0->getType(), Offs1.zextOrTrunc(OpSize) -
826 Offs2.zextOrTrunc(OpSize));
827 }
828 }
829
830returnnullptr;
831}
832
833/// If array indices are not pointer-sized integers, explicitly cast them so
834/// that they aren't implicitly casted by the getelementptr.
835Constant *CastGEPIndices(Type *SrcElemTy,ArrayRef<Constant *> Ops,
836Type *ResultTy,GEPNoWrapFlags NW,
837 std::optional<ConstantRange>InRange,
838constDataLayout &DL,constTargetLibraryInfo *TLI) {
839Type *IntIdxTy =DL.getIndexType(ResultTy);
840Type *IntIdxScalarTy = IntIdxTy->getScalarType();
841
842boolAny =false;
843SmallVector<Constant*, 32> NewIdxs;
844for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
845if ((i == 1 ||
846 !isa<StructType>(GetElementPtrInst::getIndexedType(
847 SrcElemTy, Ops.slice(1, i - 1)))) &&
848 Ops[i]->getType()->getScalarType() != IntIdxScalarTy) {
849Any =true;
850Type *NewType =
851 Ops[i]->getType()->isVectorTy() ? IntIdxTy : IntIdxScalarTy;
852Constant *NewIdx =ConstantFoldCastOperand(
853CastInst::getCastOpcode(Ops[i],true, NewType,true), Ops[i], NewType,
854DL);
855if (!NewIdx)
856returnnullptr;
857 NewIdxs.push_back(NewIdx);
858 }else
859 NewIdxs.push_back(Ops[i]);
860 }
861
862if (!Any)
863returnnullptr;
864
865Constant *C =
866ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs, NW,InRange);
867returnConstantFoldConstant(C,DL, TLI);
868}
869
870/// If we can symbolically evaluate the GEP constant expression, do so.
871Constant *SymbolicallyEvaluateGEP(constGEPOperator *GEP,
872ArrayRef<Constant *> Ops,
873constDataLayout &DL,
874constTargetLibraryInfo *TLI) {
875Type *SrcElemTy =GEP->getSourceElementType();
876Type *ResTy =GEP->getType();
877if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))
878returnnullptr;
879
880if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy,GEP->getNoWrapFlags(),
881GEP->getInRange(),DL, TLI))
882returnC;
883
884Constant *Ptr = Ops[0];
885if (!Ptr->getType()->isPointerTy())
886returnnullptr;
887
888Type *IntIdxTy =DL.getIndexType(Ptr->getType());
889
890for (unsigned i = 1, e = Ops.size(); i != e; ++i)
891if (!isa<ConstantInt>(Ops[i]) || !Ops[i]->getType()->isIntegerTy())
892returnnullptr;
893
894unsignedBitWidth =DL.getTypeSizeInBits(IntIdxTy);
895APIntOffset =APInt(
896BitWidth,
897DL.getIndexedOffsetInType(
898 SrcElemTy,ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),
899/*isSigned=*/true,/*implicitTrunc=*/true);
900
901 std::optional<ConstantRange>InRange =GEP->getInRange();
902if (InRange)
903InRange =InRange->sextOrTrunc(BitWidth);
904
905// If this is a GEP of a GEP, fold it all into a single GEP.
906GEPNoWrapFlags NW =GEP->getNoWrapFlags();
907bool Overflow =false;
908while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {
909 NW &=GEP->getNoWrapFlags();
910
911SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands()));
912
913// Do not try the incorporate the sub-GEP if some index is not a number.
914bool AllConstantInt =true;
915for (Value *NestedOp : NestedOps)
916if (!isa<ConstantInt>(NestedOp)) {
917 AllConstantInt =false;
918break;
919 }
920if (!AllConstantInt)
921break;
922
923// TODO: Try to intersect two inrange attributes?
924if (!InRange) {
925InRange =GEP->getInRange();
926if (InRange)
927// Adjust inrange by offset until now.
928InRange =InRange->sextOrTrunc(BitWidth).subtract(Offset);
929 }
930
931Ptr = cast<Constant>(GEP->getOperand(0));
932 SrcElemTy =GEP->getSourceElementType();
933Offset =Offset.sadd_ov(
934APInt(BitWidth,DL.getIndexedOffsetInType(SrcElemTy, NestedOps),
935/*isSigned=*/true,/*implicitTrunc=*/true),
936 Overflow);
937 }
938
939// Preserving nusw (without inbounds) also requires that the offset
940// additions did not overflow.
941if (NW.hasNoUnsignedSignedWrap() && !NW.isInBounds() && Overflow)
942 NW = NW.withoutNoUnsignedSignedWrap();
943
944// If the base value for this address is a literal integer value, fold the
945// getelementptr to the resulting integer value casted to the pointer type.
946APIntBasePtr(BitWidth, 0);
947if (auto *CE = dyn_cast<ConstantExpr>(Ptr)) {
948if (CE->getOpcode() == Instruction::IntToPtr) {
949if (auto *Base = dyn_cast<ConstantInt>(CE->getOperand(0)))
950BasePtr =Base->getValue().zextOrTrunc(BitWidth);
951 }
952 }
953
954auto *PTy = cast<PointerType>(Ptr->getType());
955if ((Ptr->isNullValue() || BasePtr != 0) &&
956 !DL.isNonIntegralPointerType(PTy)) {
957Constant *C = ConstantInt::get(Ptr->getContext(),Offset + BasePtr);
958returnConstantExpr::getIntToPtr(C, ResTy);
959 }
960
961// Try to infer inbounds for GEPs of globals.
962if (!NW.isInBounds() &&Offset.isNonNegative()) {
963bool CanBeNull, CanBeFreed;
964uint64_t DerefBytes =
965Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);
966if (DerefBytes != 0 && !CanBeNull &&Offset.sle(DerefBytes))
967 NW |=GEPNoWrapFlags::inBounds();
968 }
969
970// nusw + nneg -> nuw
971if (NW.hasNoUnsignedSignedWrap() &&Offset.isNonNegative())
972 NW |=GEPNoWrapFlags::noUnsignedWrap();
973
974// Otherwise canonicalize this to a single ptradd.
975LLVMContext &Ctx =Ptr->getContext();
976returnConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx),Ptr,
977 ConstantInt::get(Ctx,Offset), NW,
978InRange);
979}
980
981/// Attempt to constant fold an instruction with the
982/// specified opcode and operands. If successful, the constant result is
983/// returned, if not, null is returned. Note that this function can fail when
984/// attempting to fold instructions like loads and stores, which have no
985/// constant expression form.
986Constant *ConstantFoldInstOperandsImpl(constValue *InstOrCE,unsigned Opcode,
987ArrayRef<Constant *> Ops,
988constDataLayout &DL,
989constTargetLibraryInfo *TLI,
990bool AllowNonDeterministic) {
991Type *DestTy = InstOrCE->getType();
992
993if (Instruction::isUnaryOp(Opcode))
994returnConstantFoldUnaryOpOperand(Opcode, Ops[0],DL);
995
996if (Instruction::isBinaryOp(Opcode)) {
997switch (Opcode) {
998default:
999break;
1000case Instruction::FAdd:
1001case Instruction::FSub:
1002case Instruction::FMul:
1003case Instruction::FDiv:
1004case Instruction::FRem:
1005// Handle floating point instructions separately to account for denormals
1006// TODO: If a constant expression is being folded rather than an
1007// instruction, denormals will not be flushed/treated as zero
1008if (constauto *I = dyn_cast<Instruction>(InstOrCE)) {
1009returnConstantFoldFPInstOperands(Opcode, Ops[0], Ops[1],DL,I,
1010 AllowNonDeterministic);
1011 }
1012 }
1013returnConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1],DL);
1014 }
1015
1016if (Instruction::isCast(Opcode))
1017returnConstantFoldCastOperand(Opcode, Ops[0], DestTy,DL);
1018
1019if (auto *GEP = dyn_cast<GEPOperator>(InstOrCE)) {
1020Type *SrcElemTy =GEP->getSourceElementType();
1021if (!ConstantExpr::isSupportedGetElementPtr(SrcElemTy))
1022returnnullptr;
1023
1024if (Constant *C = SymbolicallyEvaluateGEP(GEP, Ops,DL, TLI))
1025returnC;
1026
1027returnConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], Ops.slice(1),
1028GEP->getNoWrapFlags(),
1029GEP->getInRange());
1030 }
1031
1032if (auto *CE = dyn_cast<ConstantExpr>(InstOrCE))
1033returnCE->getWithOperands(Ops);
1034
1035switch (Opcode) {
1036default:returnnullptr;
1037case Instruction::ICmp:
1038case Instruction::FCmp: {
1039auto *C = cast<CmpInst>(InstOrCE);
1040returnConstantFoldCompareInstOperands(C->getPredicate(), Ops[0], Ops[1],
1041DL, TLI,C);
1042 }
1043case Instruction::Freeze:
1044returnisGuaranteedNotToBeUndefOrPoison(Ops[0]) ? Ops[0] :nullptr;
1045case Instruction::Call:
1046if (auto *F = dyn_cast<Function>(Ops.back())) {
1047constauto *Call = cast<CallBase>(InstOrCE);
1048if (canConstantFoldCallTo(Call,F))
1049returnConstantFoldCall(Call,F, Ops.slice(0, Ops.size() - 1), TLI,
1050 AllowNonDeterministic);
1051 }
1052returnnullptr;
1053case Instruction::Select:
1054returnConstantFoldSelectInstruction(Ops[0], Ops[1], Ops[2]);
1055case Instruction::ExtractElement:
1056returnConstantExpr::getExtractElement(Ops[0], Ops[1]);
1057case Instruction::ExtractValue:
1058returnConstantFoldExtractValueInstruction(
1059 Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());
1060case Instruction::InsertElement:
1061returnConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
1062case Instruction::InsertValue:
1063returnConstantFoldInsertValueInstruction(
1064 Ops[0], Ops[1], cast<InsertValueInst>(InstOrCE)->getIndices());
1065case Instruction::ShuffleVector:
1066returnConstantExpr::getShuffleVector(
1067 Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());
1068case Instruction::Load: {
1069constauto *LI = dyn_cast<LoadInst>(InstOrCE);
1070if (LI->isVolatile())
1071returnnullptr;
1072returnConstantFoldLoadFromConstPtr(Ops[0], LI->getType(),DL);
1073 }
1074 }
1075}
1076
1077}// end anonymous namespace
1078
1079//===----------------------------------------------------------------------===//
1080// Constant Folding public APIs
1081//===----------------------------------------------------------------------===//
1082
1083namespace{
1084
1085Constant *
1086ConstantFoldConstantImpl(constConstant *C,constDataLayout &DL,
1087constTargetLibraryInfo *TLI,
1088SmallDenseMap<Constant *, Constant *> &FoldedOps) {
1089if (!isa<ConstantVector>(C) && !isa<ConstantExpr>(C))
1090returnconst_cast<Constant *>(C);
1091
1092SmallVector<Constant *, 8> Ops;
1093for (constUse &OldU :C->operands()) {
1094Constant *OldC = cast<Constant>(&OldU);
1095Constant *NewC = OldC;
1096// Recursively fold the ConstantExpr's operands. If we have already folded
1097// a ConstantExpr, we don't have to process it again.
1098if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
1099auto It = FoldedOps.find(OldC);
1100if (It == FoldedOps.end()) {
1101 NewC = ConstantFoldConstantImpl(OldC,DL, TLI, FoldedOps);
1102 FoldedOps.insert({OldC, NewC});
1103 }else {
1104 NewC = It->second;
1105 }
1106 }
1107 Ops.push_back(NewC);
1108 }
1109
1110if (auto *CE = dyn_cast<ConstantExpr>(C)) {
1111if (Constant *Res = ConstantFoldInstOperandsImpl(
1112 CE,CE->getOpcode(), Ops,DL, TLI,/*AllowNonDeterministic=*/true))
1113return Res;
1114returnconst_cast<Constant *>(C);
1115 }
1116
1117assert(isa<ConstantVector>(C));
1118returnConstantVector::get(Ops);
1119}
1120
1121}// end anonymous namespace
1122
1123Constant *llvm::ConstantFoldInstruction(Instruction *I,constDataLayout &DL,
1124constTargetLibraryInfo *TLI) {
1125// Handle PHI nodes quickly here...
1126if (auto *PN = dyn_cast<PHINode>(I)) {
1127Constant *CommonValue =nullptr;
1128
1129SmallDenseMap<Constant *, Constant *> FoldedOps;
1130for (Value *Incoming : PN->incoming_values()) {
1131// If the incoming value is undef then skip it. Note that while we could
1132// skip the value if it is equal to the phi node itself we choose not to
1133// because that would break the rule that constant folding only applies if
1134// all operands are constants.
1135if (isa<UndefValue>(Incoming))
1136continue;
1137// If the incoming value is not a constant, then give up.
1138auto *C = dyn_cast<Constant>(Incoming);
1139if (!C)
1140returnnullptr;
1141// Fold the PHI's operands.
1142C = ConstantFoldConstantImpl(C,DL, TLI, FoldedOps);
1143// If the incoming value is a different constant to
1144// the one we saw previously, then give up.
1145if (CommonValue &&C != CommonValue)
1146returnnullptr;
1147 CommonValue =C;
1148 }
1149
1150// If we reach here, all incoming values are the same constant or undef.
1151return CommonValue ? CommonValue :UndefValue::get(PN->getType());
1152 }
1153
1154// Scan the operand list, checking to see if they are all constants, if so,
1155// hand off to ConstantFoldInstOperandsImpl.
1156if (!all_of(I->operands(), [](Use &U) { return isa<Constant>(U); }))
1157returnnullptr;
1158
1159SmallDenseMap<Constant *, Constant *> FoldedOps;
1160SmallVector<Constant *, 8> Ops;
1161for (constUse &OpU :I->operands()) {
1162auto *Op = cast<Constant>(&OpU);
1163// Fold the Instruction's operands.
1164Op = ConstantFoldConstantImpl(Op,DL, TLI, FoldedOps);
1165 Ops.push_back(Op);
1166 }
1167
1168returnConstantFoldInstOperands(I, Ops,DL, TLI);
1169}
1170
1171Constant *llvm::ConstantFoldConstant(constConstant *C,constDataLayout &DL,
1172constTargetLibraryInfo *TLI) {
1173SmallDenseMap<Constant *, Constant *> FoldedOps;
1174return ConstantFoldConstantImpl(C,DL, TLI, FoldedOps);
1175}
1176
1177Constant *llvm::ConstantFoldInstOperands(Instruction *I,
1178ArrayRef<Constant *> Ops,
1179constDataLayout &DL,
1180constTargetLibraryInfo *TLI,
1181bool AllowNonDeterministic) {
1182return ConstantFoldInstOperandsImpl(I,I->getOpcode(), Ops,DL, TLI,
1183 AllowNonDeterministic);
1184}
1185
1186Constant *llvm::ConstantFoldCompareInstOperands(
1187unsigned IntPredicate,Constant *Ops0,Constant *Ops1,constDataLayout &DL,
1188constTargetLibraryInfo *TLI,constInstruction *I) {
1189CmpInst::Predicate Predicate = (CmpInst::Predicate)IntPredicate;
1190// fold: icmp (inttoptr x), null -> icmp x, 0
1191// fold: icmp null, (inttoptr x) -> icmp 0, x
1192// fold: icmp (ptrtoint x), 0 -> icmp x, null
1193// fold: icmp 0, (ptrtoint x) -> icmp null, x
1194// fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
1195// fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
1196//
1197// FIXME: The following comment is out of data and the DataLayout is here now.
1198// ConstantExpr::getCompare cannot do this, because it doesn't have DL
1199// around to know if bit truncation is happening.
1200if (auto *CE0 = dyn_cast<ConstantExpr>(Ops0)) {
1201if (Ops1->isNullValue()) {
1202if (CE0->getOpcode() == Instruction::IntToPtr) {
1203Type *IntPtrTy =DL.getIntPtrType(CE0->getType());
1204// Convert the integer value to the right size to ensure we get the
1205// proper extension or truncation.
1206if (Constant *C =ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,
1207/*IsSigned*/false,DL)) {
1208Constant *Null =Constant::getNullValue(C->getType());
1209returnConstantFoldCompareInstOperands(Predicate,C,Null,DL, TLI);
1210 }
1211 }
1212
1213// Only do this transformation if the int is intptrty in size, otherwise
1214// there is a truncation or extension that we aren't modeling.
1215if (CE0->getOpcode() == Instruction::PtrToInt) {
1216Type *IntPtrTy =DL.getIntPtrType(CE0->getOperand(0)->getType());
1217if (CE0->getType() == IntPtrTy) {
1218Constant *C = CE0->getOperand(0);
1219Constant *Null =Constant::getNullValue(C->getType());
1220returnConstantFoldCompareInstOperands(Predicate,C,Null,DL, TLI);
1221 }
1222 }
1223 }
1224
1225if (auto *CE1 = dyn_cast<ConstantExpr>(Ops1)) {
1226if (CE0->getOpcode() == CE1->getOpcode()) {
1227if (CE0->getOpcode() == Instruction::IntToPtr) {
1228Type *IntPtrTy =DL.getIntPtrType(CE0->getType());
1229
1230// Convert the integer value to the right size to ensure we get the
1231// proper extension or truncation.
1232Constant *C0 =ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,
1233/*IsSigned*/false,DL);
1234Constant *C1 =ConstantFoldIntegerCast(CE1->getOperand(0), IntPtrTy,
1235/*IsSigned*/false,DL);
1236if (C0 && C1)
1237returnConstantFoldCompareInstOperands(Predicate, C0, C1,DL, TLI);
1238 }
1239
1240// Only do this transformation if the int is intptrty in size, otherwise
1241// there is a truncation or extension that we aren't modeling.
1242if (CE0->getOpcode() == Instruction::PtrToInt) {
1243Type *IntPtrTy =DL.getIntPtrType(CE0->getOperand(0)->getType());
1244if (CE0->getType() == IntPtrTy &&
1245 CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()) {
1246returnConstantFoldCompareInstOperands(
1247 Predicate, CE0->getOperand(0), CE1->getOperand(0),DL, TLI);
1248 }
1249 }
1250 }
1251 }
1252
1253// Convert pointer comparison (base+offset1) pred (base+offset2) into
1254// offset1 pred offset2, for the case where the offset is inbounds. This
1255// only works for equality and unsigned comparison, as inbounds permits
1256// crossing the sign boundary. However, the offset comparison itself is
1257// signed.
1258if (Ops0->getType()->isPointerTy() && !ICmpInst::isSigned(Predicate)) {
1259unsigned IndexWidth =DL.getIndexTypeSizeInBits(Ops0->getType());
1260APInt Offset0(IndexWidth, 0);
1261Value *Stripped0 =
1262 Ops0->stripAndAccumulateInBoundsConstantOffsets(DL, Offset0);
1263APInt Offset1(IndexWidth, 0);
1264Value *Stripped1 =
1265 Ops1->stripAndAccumulateInBoundsConstantOffsets(DL, Offset1);
1266if (Stripped0 == Stripped1)
1267returnConstantInt::getBool(
1268 Ops0->getContext(),
1269ICmpInst::compare(Offset0, Offset1,
1270ICmpInst::getSignedPredicate(Predicate)));
1271 }
1272 }elseif (isa<ConstantExpr>(Ops1)) {
1273// If RHS is a constant expression, but the left side isn't, swap the
1274// operands and try again.
1275 Predicate = ICmpInst::getSwappedPredicate(Predicate);
1276returnConstantFoldCompareInstOperands(Predicate, Ops1, Ops0,DL, TLI);
1277 }
1278
1279if (CmpInst::isFPPredicate(Predicate)) {
1280// Flush any denormal constant float input according to denormal handling
1281// mode.
1282 Ops0 =FlushFPConstant(Ops0,I,/*IsOutput=*/false);
1283if (!Ops0)
1284returnnullptr;
1285 Ops1 =FlushFPConstant(Ops1,I,/*IsOutput=*/false);
1286if (!Ops1)
1287returnnullptr;
1288 }
1289
1290returnConstantFoldCompareInstruction(Predicate, Ops0, Ops1);
1291}
1292
1293Constant *llvm::ConstantFoldUnaryOpOperand(unsigned Opcode,Constant *Op,
1294constDataLayout &DL) {
1295assert(Instruction::isUnaryOp(Opcode));
1296
1297returnConstantFoldUnaryInstruction(Opcode,Op);
1298}
1299
1300Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode,Constant *LHS,
1301Constant *RHS,
1302constDataLayout &DL) {
1303assert(Instruction::isBinaryOp(Opcode));
1304if (isa<ConstantExpr>(LHS) || isa<ConstantExpr>(RHS))
1305if (Constant *C = SymbolicallyEvaluateBinop(Opcode,LHS,RHS,DL))
1306returnC;
1307
1308if (ConstantExpr::isDesirableBinOp(Opcode))
1309returnConstantExpr::get(Opcode,LHS,RHS);
1310returnConstantFoldBinaryInstruction(Opcode,LHS,RHS);
1311}
1312
1313staticConstantFP *flushDenormalConstant(Type *Ty,constAPFloat &APF,
1314DenormalMode::DenormalModeKind Mode) {
1315switch (Mode) {
1316caseDenormalMode::Dynamic:
1317returnnullptr;
1318caseDenormalMode::IEEE:
1319return ConstantFP::get(Ty->getContext(), APF);
1320caseDenormalMode::PreserveSign:
1321return ConstantFP::get(
1322 Ty->getContext(),
1323APFloat::getZero(APF.getSemantics(), APF.isNegative()));
1324caseDenormalMode::PositiveZero:
1325return ConstantFP::get(Ty->getContext(),
1326APFloat::getZero(APF.getSemantics(),false));
1327default:
1328break;
1329 }
1330
1331llvm_unreachable("unknown denormal mode");
1332}
1333
1334/// Return the denormal mode that can be assumed when executing a floating point
1335/// operation at \p CtxI.
1336staticDenormalModegetInstrDenormalMode(constInstruction *CtxI,Type *Ty) {
1337if (!CtxI || !CtxI->getParent() || !CtxI->getFunction())
1338returnDenormalMode::getDynamic();
1339return CtxI->getFunction()->getDenormalMode(Ty->getFltSemantics());
1340}
1341
1342staticConstantFP *flushDenormalConstantFP(ConstantFP *CFP,
1343constInstruction *Inst,
1344bool IsOutput) {
1345constAPFloat &APF = CFP->getValueAPF();
1346if (!APF.isDenormal())
1347return CFP;
1348
1349DenormalMode Mode =getInstrDenormalMode(Inst, CFP->getType());
1350returnflushDenormalConstant(CFP->getType(), APF,
1351 IsOutput ? Mode.Output : Mode.Input);
1352}
1353
1354Constant *llvm::FlushFPConstant(Constant *Operand,constInstruction *Inst,
1355bool IsOutput) {
1356if (ConstantFP *CFP = dyn_cast<ConstantFP>(Operand))
1357returnflushDenormalConstantFP(CFP, Inst, IsOutput);
1358
1359if (isa<ConstantAggregateZero, UndefValue, ConstantExpr>(Operand))
1360return Operand;
1361
1362Type *Ty = Operand->getType();
1363VectorType *VecTy = dyn_cast<VectorType>(Ty);
1364if (VecTy) {
1365if (auto *Splat = dyn_cast_or_null<ConstantFP>(Operand->getSplatValue())) {
1366ConstantFP *Folded =flushDenormalConstantFP(Splat, Inst, IsOutput);
1367if (!Folded)
1368returnnullptr;
1369returnConstantVector::getSplat(VecTy->getElementCount(), Folded);
1370 }
1371
1372 Ty = VecTy->getElementType();
1373 }
1374
1375if (constauto *CV = dyn_cast<ConstantVector>(Operand)) {
1376SmallVector<Constant *, 16> NewElts;
1377for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
1378Constant *Element = CV->getAggregateElement(i);
1379if (isa<UndefValue>(Element)) {
1380 NewElts.push_back(Element);
1381continue;
1382 }
1383
1384ConstantFP *CFP = dyn_cast<ConstantFP>(Element);
1385if (!CFP)
1386returnnullptr;
1387
1388ConstantFP *Folded =flushDenormalConstantFP(CFP, Inst, IsOutput);
1389if (!Folded)
1390returnnullptr;
1391 NewElts.push_back(Folded);
1392 }
1393
1394returnConstantVector::get(NewElts);
1395 }
1396
1397if (constauto *CDV = dyn_cast<ConstantDataVector>(Operand)) {
1398SmallVector<Constant *, 16> NewElts;
1399for (unsignedI = 0, E = CDV->getNumElements();I < E; ++I) {
1400constAPFloat &Elt = CDV->getElementAsAPFloat(I);
1401if (!Elt.isDenormal()) {
1402 NewElts.push_back(ConstantFP::get(Ty, Elt));
1403 }else {
1404DenormalMode Mode =getInstrDenormalMode(Inst, Ty);
1405ConstantFP *Folded =
1406flushDenormalConstant(Ty, Elt, IsOutput ? Mode.Output : Mode.Input);
1407if (!Folded)
1408returnnullptr;
1409 NewElts.push_back(Folded);
1410 }
1411 }
1412
1413returnConstantVector::get(NewElts);
1414 }
1415
1416returnnullptr;
1417}
1418
1419Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode,Constant *LHS,
1420Constant *RHS,constDataLayout &DL,
1421constInstruction *I,
1422bool AllowNonDeterministic) {
1423if (Instruction::isBinaryOp(Opcode)) {
1424// Flush denormal inputs if needed.
1425Constant *Op0 =FlushFPConstant(LHS,I,/* IsOutput */false);
1426if (!Op0)
1427returnnullptr;
1428Constant *Op1 =FlushFPConstant(RHS,I,/* IsOutput */false);
1429if (!Op1)
1430returnnullptr;
1431
1432// If nsz or an algebraic FMF flag is set, the result of the FP operation
1433// may change due to future optimization. Don't constant fold them if
1434// non-deterministic results are not allowed.
1435if (!AllowNonDeterministic)
1436if (auto *FP = dyn_cast_or_null<FPMathOperator>(I))
1437if (FP->hasNoSignedZeros() ||FP->hasAllowReassoc() ||
1438FP->hasAllowContract() ||FP->hasAllowReciprocal())
1439returnnullptr;
1440
1441// Calculate constant result.
1442Constant *C =ConstantFoldBinaryOpOperands(Opcode, Op0, Op1,DL);
1443if (!C)
1444returnnullptr;
1445
1446// Flush denormal output if needed.
1447C =FlushFPConstant(C,I,/* IsOutput */true);
1448if (!C)
1449returnnullptr;
1450
1451// The precise NaN value is non-deterministic.
1452if (!AllowNonDeterministic &&C->isNaN())
1453returnnullptr;
1454
1455returnC;
1456 }
1457// If instruction lacks a parent/function and the denormal mode cannot be
1458// determined, use the default (IEEE).
1459returnConstantFoldBinaryOpOperands(Opcode,LHS,RHS,DL);
1460}
1461
1462Constant *llvm::ConstantFoldCastOperand(unsigned Opcode,Constant *C,
1463Type *DestTy,constDataLayout &DL) {
1464assert(Instruction::isCast(Opcode));
1465switch (Opcode) {
1466default:
1467llvm_unreachable("Missing case");
1468case Instruction::PtrToInt:
1469if (auto *CE = dyn_cast<ConstantExpr>(C)) {
1470Constant *FoldedValue =nullptr;
1471// If the input is a inttoptr, eliminate the pair. This requires knowing
1472// the width of a pointer, so it can't be done in ConstantExpr::getCast.
1473if (CE->getOpcode() == Instruction::IntToPtr) {
1474// zext/trunc the inttoptr to pointer size.
1475 FoldedValue =ConstantFoldIntegerCast(CE->getOperand(0),
1476DL.getIntPtrType(CE->getType()),
1477/*IsSigned=*/false,DL);
1478 }elseif (auto *GEP = dyn_cast<GEPOperator>(CE)) {
1479// If we have GEP, we can perform the following folds:
1480// (ptrtoint (gep null, x)) -> x
1481// (ptrtoint (gep (gep null, x), y) -> x + y, etc.
1482unsignedBitWidth =DL.getIndexTypeSizeInBits(GEP->getType());
1483APInt BaseOffset(BitWidth, 0);
1484auto *Base = cast<Constant>(GEP->stripAndAccumulateConstantOffsets(
1485DL, BaseOffset,/*AllowNonInbounds=*/true));
1486if (Base->isNullValue()) {
1487 FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset);
1488 }else {
1489// ptrtoint (gep i8, Ptr, (sub 0, V)) -> sub (ptrtoint Ptr), V
1490if (GEP->getNumIndices() == 1 &&
1491GEP->getSourceElementType()->isIntegerTy(8)) {
1492auto *Ptr = cast<Constant>(GEP->getPointerOperand());
1493auto *Sub = dyn_cast<ConstantExpr>(GEP->getOperand(1));
1494Type *IntIdxTy =DL.getIndexType(Ptr->getType());
1495if (Sub && Sub->getType() == IntIdxTy &&
1496 Sub->getOpcode() == Instruction::Sub &&
1497 Sub->getOperand(0)->isNullValue())
1498 FoldedValue =ConstantExpr::getSub(
1499ConstantExpr::getPtrToInt(Ptr, IntIdxTy), Sub->getOperand(1));
1500 }
1501 }
1502 }
1503if (FoldedValue) {
1504// Do a zext or trunc to get to the ptrtoint dest size.
1505returnConstantFoldIntegerCast(FoldedValue, DestTy,/*IsSigned=*/false,
1506DL);
1507 }
1508 }
1509break;
1510case Instruction::IntToPtr:
1511// If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if
1512// the int size is >= the ptr size and the address spaces are the same.
1513// This requires knowing the width of a pointer, so it can't be done in
1514// ConstantExpr::getCast.
1515if (auto *CE = dyn_cast<ConstantExpr>(C)) {
1516if (CE->getOpcode() == Instruction::PtrToInt) {
1517Constant *SrcPtr = CE->getOperand(0);
1518unsigned SrcPtrSize =DL.getPointerTypeSizeInBits(SrcPtr->getType());
1519unsigned MidIntSize = CE->getType()->getScalarSizeInBits();
1520
1521if (MidIntSize >= SrcPtrSize) {
1522unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();
1523if (SrcAS == DestTy->getPointerAddressSpace())
1524returnFoldBitCast(CE->getOperand(0), DestTy,DL);
1525 }
1526 }
1527 }
1528break;
1529case Instruction::Trunc:
1530case Instruction::ZExt:
1531case Instruction::SExt:
1532case Instruction::FPTrunc:
1533case Instruction::FPExt:
1534case Instruction::UIToFP:
1535case Instruction::SIToFP:
1536case Instruction::FPToUI:
1537case Instruction::FPToSI:
1538case Instruction::AddrSpaceCast:
1539break;
1540case Instruction::BitCast:
1541returnFoldBitCast(C, DestTy,DL);
1542 }
1543
1544if (ConstantExpr::isDesirableCastOp(Opcode))
1545returnConstantExpr::getCast(Opcode,C, DestTy);
1546returnConstantFoldCastInstruction(Opcode,C, DestTy);
1547}
1548
1549Constant *llvm::ConstantFoldIntegerCast(Constant *C,Type *DestTy,
1550bool IsSigned,constDataLayout &DL) {
1551Type *SrcTy =C->getType();
1552if (SrcTy == DestTy)
1553returnC;
1554if (SrcTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
1555returnConstantFoldCastOperand(Instruction::Trunc,C, DestTy,DL);
1556if (IsSigned)
1557returnConstantFoldCastOperand(Instruction::SExt,C, DestTy,DL);
1558returnConstantFoldCastOperand(Instruction::ZExt,C, DestTy,DL);
1559}
1560
1561//===----------------------------------------------------------------------===//
1562// Constant Folding for Calls
1563//
1564
1565boolllvm::canConstantFoldCallTo(constCallBase *Call,constFunction *F) {
1566if (Call->isNoBuiltin())
1567returnfalse;
1568if (Call->getFunctionType() !=F->getFunctionType())
1569returnfalse;
1570switch (F->getIntrinsicID()) {
1571// Operations that do not operate floating-point numbers and do not depend on
1572// FP environment can be folded even in strictfp functions.
1573case Intrinsic::bswap:
1574case Intrinsic::ctpop:
1575case Intrinsic::ctlz:
1576case Intrinsic::cttz:
1577case Intrinsic::fshl:
1578case Intrinsic::fshr:
1579case Intrinsic::launder_invariant_group:
1580case Intrinsic::strip_invariant_group:
1581case Intrinsic::masked_load:
1582case Intrinsic::get_active_lane_mask:
1583case Intrinsic::abs:
1584case Intrinsic::smax:
1585case Intrinsic::smin:
1586case Intrinsic::umax:
1587case Intrinsic::umin:
1588case Intrinsic::scmp:
1589case Intrinsic::ucmp:
1590case Intrinsic::sadd_with_overflow:
1591case Intrinsic::uadd_with_overflow:
1592case Intrinsic::ssub_with_overflow:
1593case Intrinsic::usub_with_overflow:
1594case Intrinsic::smul_with_overflow:
1595case Intrinsic::umul_with_overflow:
1596case Intrinsic::sadd_sat:
1597case Intrinsic::uadd_sat:
1598case Intrinsic::ssub_sat:
1599case Intrinsic::usub_sat:
1600case Intrinsic::smul_fix:
1601case Intrinsic::smul_fix_sat:
1602case Intrinsic::bitreverse:
1603case Intrinsic::is_constant:
1604case Intrinsic::vector_reduce_add:
1605case Intrinsic::vector_reduce_mul:
1606case Intrinsic::vector_reduce_and:
1607case Intrinsic::vector_reduce_or:
1608case Intrinsic::vector_reduce_xor:
1609case Intrinsic::vector_reduce_smin:
1610case Intrinsic::vector_reduce_smax:
1611case Intrinsic::vector_reduce_umin:
1612case Intrinsic::vector_reduce_umax:
1613// Target intrinsics
1614case Intrinsic::amdgcn_perm:
1615case Intrinsic::amdgcn_wave_reduce_umin:
1616case Intrinsic::amdgcn_wave_reduce_umax:
1617case Intrinsic::amdgcn_s_wqm:
1618case Intrinsic::amdgcn_s_quadmask:
1619case Intrinsic::amdgcn_s_bitreplicate:
1620case Intrinsic::arm_mve_vctp8:
1621case Intrinsic::arm_mve_vctp16:
1622case Intrinsic::arm_mve_vctp32:
1623case Intrinsic::arm_mve_vctp64:
1624case Intrinsic::aarch64_sve_convert_from_svbool:
1625// WebAssembly float semantics are always known
1626case Intrinsic::wasm_trunc_signed:
1627case Intrinsic::wasm_trunc_unsigned:
1628returntrue;
1629
1630// Floating point operations cannot be folded in strictfp functions in
1631// general case. They can be folded if FP environment is known to compiler.
1632case Intrinsic::minnum:
1633case Intrinsic::maxnum:
1634case Intrinsic::minimum:
1635case Intrinsic::maximum:
1636case Intrinsic::log:
1637case Intrinsic::log2:
1638case Intrinsic::log10:
1639case Intrinsic::exp:
1640case Intrinsic::exp2:
1641case Intrinsic::exp10:
1642case Intrinsic::sqrt:
1643case Intrinsic::sin:
1644case Intrinsic::cos:
1645case Intrinsic::sincos:
1646case Intrinsic::pow:
1647case Intrinsic::powi:
1648case Intrinsic::ldexp:
1649case Intrinsic::fma:
1650case Intrinsic::fmuladd:
1651case Intrinsic::frexp:
1652case Intrinsic::fptoui_sat:
1653case Intrinsic::fptosi_sat:
1654case Intrinsic::convert_from_fp16:
1655case Intrinsic::convert_to_fp16:
1656case Intrinsic::amdgcn_cos:
1657case Intrinsic::amdgcn_cubeid:
1658case Intrinsic::amdgcn_cubema:
1659case Intrinsic::amdgcn_cubesc:
1660case Intrinsic::amdgcn_cubetc:
1661case Intrinsic::amdgcn_fmul_legacy:
1662case Intrinsic::amdgcn_fma_legacy:
1663case Intrinsic::amdgcn_fract:
1664case Intrinsic::amdgcn_sin:
1665// The intrinsics below depend on rounding mode in MXCSR.
1666case Intrinsic::x86_sse_cvtss2si:
1667case Intrinsic::x86_sse_cvtss2si64:
1668case Intrinsic::x86_sse_cvttss2si:
1669case Intrinsic::x86_sse_cvttss2si64:
1670case Intrinsic::x86_sse2_cvtsd2si:
1671case Intrinsic::x86_sse2_cvtsd2si64:
1672case Intrinsic::x86_sse2_cvttsd2si:
1673case Intrinsic::x86_sse2_cvttsd2si64:
1674case Intrinsic::x86_avx512_vcvtss2si32:
1675case Intrinsic::x86_avx512_vcvtss2si64:
1676case Intrinsic::x86_avx512_cvttss2si:
1677case Intrinsic::x86_avx512_cvttss2si64:
1678case Intrinsic::x86_avx512_vcvtsd2si32:
1679case Intrinsic::x86_avx512_vcvtsd2si64:
1680case Intrinsic::x86_avx512_cvttsd2si:
1681case Intrinsic::x86_avx512_cvttsd2si64:
1682case Intrinsic::x86_avx512_vcvtss2usi32:
1683case Intrinsic::x86_avx512_vcvtss2usi64:
1684case Intrinsic::x86_avx512_cvttss2usi:
1685case Intrinsic::x86_avx512_cvttss2usi64:
1686case Intrinsic::x86_avx512_vcvtsd2usi32:
1687case Intrinsic::x86_avx512_vcvtsd2usi64:
1688case Intrinsic::x86_avx512_cvttsd2usi:
1689case Intrinsic::x86_avx512_cvttsd2usi64:
1690return !Call->isStrictFP();
1691
1692// NVVM FMax intrinsics
1693case Intrinsic::nvvm_fmax_d:
1694case Intrinsic::nvvm_fmax_f:
1695case Intrinsic::nvvm_fmax_ftz_f:
1696case Intrinsic::nvvm_fmax_ftz_nan_f:
1697case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
1698case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
1699case Intrinsic::nvvm_fmax_nan_f:
1700case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
1701case Intrinsic::nvvm_fmax_xorsign_abs_f:
1702
1703// NVVM FMin intrinsics
1704case Intrinsic::nvvm_fmin_d:
1705case Intrinsic::nvvm_fmin_f:
1706case Intrinsic::nvvm_fmin_ftz_f:
1707case Intrinsic::nvvm_fmin_ftz_nan_f:
1708case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
1709case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
1710case Intrinsic::nvvm_fmin_nan_f:
1711case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
1712case Intrinsic::nvvm_fmin_xorsign_abs_f:
1713
1714// NVVM float/double to int32/uint32 conversion intrinsics
1715case Intrinsic::nvvm_f2i_rm:
1716case Intrinsic::nvvm_f2i_rn:
1717case Intrinsic::nvvm_f2i_rp:
1718case Intrinsic::nvvm_f2i_rz:
1719case Intrinsic::nvvm_f2i_rm_ftz:
1720case Intrinsic::nvvm_f2i_rn_ftz:
1721case Intrinsic::nvvm_f2i_rp_ftz:
1722case Intrinsic::nvvm_f2i_rz_ftz:
1723case Intrinsic::nvvm_f2ui_rm:
1724case Intrinsic::nvvm_f2ui_rn:
1725case Intrinsic::nvvm_f2ui_rp:
1726case Intrinsic::nvvm_f2ui_rz:
1727case Intrinsic::nvvm_f2ui_rm_ftz:
1728case Intrinsic::nvvm_f2ui_rn_ftz:
1729case Intrinsic::nvvm_f2ui_rp_ftz:
1730case Intrinsic::nvvm_f2ui_rz_ftz:
1731case Intrinsic::nvvm_d2i_rm:
1732case Intrinsic::nvvm_d2i_rn:
1733case Intrinsic::nvvm_d2i_rp:
1734case Intrinsic::nvvm_d2i_rz:
1735case Intrinsic::nvvm_d2ui_rm:
1736case Intrinsic::nvvm_d2ui_rn:
1737case Intrinsic::nvvm_d2ui_rp:
1738case Intrinsic::nvvm_d2ui_rz:
1739
1740// NVVM float/double to int64/uint64 conversion intrinsics
1741case Intrinsic::nvvm_f2ll_rm:
1742case Intrinsic::nvvm_f2ll_rn:
1743case Intrinsic::nvvm_f2ll_rp:
1744case Intrinsic::nvvm_f2ll_rz:
1745case Intrinsic::nvvm_f2ll_rm_ftz:
1746case Intrinsic::nvvm_f2ll_rn_ftz:
1747case Intrinsic::nvvm_f2ll_rp_ftz:
1748case Intrinsic::nvvm_f2ll_rz_ftz:
1749case Intrinsic::nvvm_f2ull_rm:
1750case Intrinsic::nvvm_f2ull_rn:
1751case Intrinsic::nvvm_f2ull_rp:
1752case Intrinsic::nvvm_f2ull_rz:
1753case Intrinsic::nvvm_f2ull_rm_ftz:
1754case Intrinsic::nvvm_f2ull_rn_ftz:
1755case Intrinsic::nvvm_f2ull_rp_ftz:
1756case Intrinsic::nvvm_f2ull_rz_ftz:
1757case Intrinsic::nvvm_d2ll_rm:
1758case Intrinsic::nvvm_d2ll_rn:
1759case Intrinsic::nvvm_d2ll_rp:
1760case Intrinsic::nvvm_d2ll_rz:
1761case Intrinsic::nvvm_d2ull_rm:
1762case Intrinsic::nvvm_d2ull_rn:
1763case Intrinsic::nvvm_d2ull_rp:
1764case Intrinsic::nvvm_d2ull_rz:
1765
1766// Sign operations are actually bitwise operations, they do not raise
1767// exceptions even for SNANs.
1768case Intrinsic::fabs:
1769case Intrinsic::copysign:
1770case Intrinsic::is_fpclass:
1771// Non-constrained variants of rounding operations means default FP
1772// environment, they can be folded in any case.
1773case Intrinsic::ceil:
1774case Intrinsic::floor:
1775case Intrinsic::round:
1776case Intrinsic::roundeven:
1777case Intrinsic::trunc:
1778case Intrinsic::nearbyint:
1779case Intrinsic::rint:
1780case Intrinsic::canonicalize:
1781// Constrained intrinsics can be folded if FP environment is known
1782// to compiler.
1783case Intrinsic::experimental_constrained_fma:
1784case Intrinsic::experimental_constrained_fmuladd:
1785case Intrinsic::experimental_constrained_fadd:
1786case Intrinsic::experimental_constrained_fsub:
1787case Intrinsic::experimental_constrained_fmul:
1788case Intrinsic::experimental_constrained_fdiv:
1789case Intrinsic::experimental_constrained_frem:
1790case Intrinsic::experimental_constrained_ceil:
1791case Intrinsic::experimental_constrained_floor:
1792case Intrinsic::experimental_constrained_round:
1793case Intrinsic::experimental_constrained_roundeven:
1794case Intrinsic::experimental_constrained_trunc:
1795case Intrinsic::experimental_constrained_nearbyint:
1796case Intrinsic::experimental_constrained_rint:
1797case Intrinsic::experimental_constrained_fcmp:
1798case Intrinsic::experimental_constrained_fcmps:
1799returntrue;
1800default:
1801returnfalse;
1802caseIntrinsic::not_intrinsic:break;
1803 }
1804
1805if (!F->hasName() || Call->isStrictFP())
1806returnfalse;
1807
1808// In these cases, the check of the length is required. We don't want to
1809// return true for a name like "cos\0blah" which strcmp would return equal to
1810// "cos", but has length 8.
1811StringRefName =F->getName();
1812switch (Name[0]) {
1813default:
1814returnfalse;
1815case'a':
1816returnName =="acos" ||Name =="acosf" ||
1817Name =="asin" ||Name =="asinf" ||
1818Name =="atan" ||Name =="atanf" ||
1819Name =="atan2" ||Name =="atan2f";
1820case'c':
1821returnName =="ceil" ||Name =="ceilf" ||
1822Name =="cos" ||Name =="cosf" ||
1823Name =="cosh" ||Name =="coshf";
1824case'e':
1825returnName =="exp" ||Name =="expf" ||Name =="exp2" ||
1826Name =="exp2f" ||Name =="erf" ||Name =="erff";
1827case'f':
1828returnName =="fabs" ||Name =="fabsf" ||
1829Name =="floor" ||Name =="floorf" ||
1830Name =="fmod" ||Name =="fmodf";
1831case'i':
1832returnName =="ilogb" ||Name =="ilogbf";
1833case'l':
1834returnName =="log" ||Name =="logf" ||Name =="logl" ||
1835Name =="log2" ||Name =="log2f" ||Name =="log10" ||
1836Name =="log10f" ||Name =="logb" ||Name =="logbf" ||
1837Name =="log1p" ||Name =="log1pf";
1838case'n':
1839returnName =="nearbyint" ||Name =="nearbyintf";
1840case'p':
1841returnName =="pow" ||Name =="powf";
1842case'r':
1843returnName =="remainder" ||Name =="remainderf" ||
1844Name =="rint" ||Name =="rintf" ||
1845Name =="round" ||Name =="roundf";
1846case's':
1847returnName =="sin" ||Name =="sinf" ||
1848Name =="sinh" ||Name =="sinhf" ||
1849Name =="sqrt" ||Name =="sqrtf";
1850case't':
1851returnName =="tan" ||Name =="tanf" ||
1852Name =="tanh" ||Name =="tanhf" ||
1853Name =="trunc" ||Name =="truncf";
1854case'_':
1855// Check for various function names that get used for the math functions
1856// when the header files are preprocessed with the macro
1857// __FINITE_MATH_ONLY__ enabled.
1858// The '12' here is the length of the shortest name that can match.
1859// We need to check the size before looking at Name[1] and Name[2]
1860// so we may as well check a limit that will eliminate mismatches.
1861if (Name.size() < 12 ||Name[1] !='_')
1862returnfalse;
1863switch (Name[2]) {
1864default:
1865returnfalse;
1866case'a':
1867returnName =="__acos_finite" ||Name =="__acosf_finite" ||
1868Name =="__asin_finite" ||Name =="__asinf_finite" ||
1869Name =="__atan2_finite" ||Name =="__atan2f_finite";
1870case'c':
1871returnName =="__cosh_finite" ||Name =="__coshf_finite";
1872case'e':
1873returnName =="__exp_finite" ||Name =="__expf_finite" ||
1874Name =="__exp2_finite" ||Name =="__exp2f_finite";
1875case'l':
1876returnName =="__log_finite" ||Name =="__logf_finite" ||
1877Name =="__log10_finite" ||Name =="__log10f_finite";
1878case'p':
1879returnName =="__pow_finite" ||Name =="__powf_finite";
1880case's':
1881returnName =="__sinh_finite" ||Name =="__sinhf_finite";
1882 }
1883 }
1884}
1885
1886namespace{
1887
1888Constant *GetConstantFoldFPValue(double V,Type *Ty) {
1889if (Ty->isHalfTy() || Ty->isFloatTy()) {
1890APFloat APF(V);
1891bool unused;
1892 APF.convert(Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &unused);
1893return ConstantFP::get(Ty->getContext(), APF);
1894 }
1895if (Ty->isDoubleTy())
1896return ConstantFP::get(Ty->getContext(),APFloat(V));
1897llvm_unreachable("Can only constant fold half/float/double");
1898}
1899
1900#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
1901Constant *GetConstantFoldFPValue128(float128 V,Type *Ty) {
1902if (Ty->isFP128Ty())
1903return ConstantFP::get(Ty, V);
1904llvm_unreachable("Can only constant fold fp128");
1905}
1906#endif
1907
1908/// Clear the floating-point exception state.
1909inlinevoid llvm_fenv_clearexcept() {
1910#if HAVE_DECL_FE_ALL_EXCEPT
1911 feclearexcept(FE_ALL_EXCEPT);
1912#endif
1913 errno = 0;
1914}
1915
1916/// Test if a floating-point exception was raised.
1917inlinebool llvm_fenv_testexcept() {
1918int errno_val = errno;
1919if (errno_val == ERANGE || errno_val == EDOM)
1920returntrue;
1921#if HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
1922if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
1923returntrue;
1924#endif
1925returnfalse;
1926}
1927
1928staticconstAPFloat FTZPreserveSign(constAPFloat &V) {
1929if (V.isDenormal())
1930returnAPFloat::getZero(V.getSemantics(),V.isNegative());
1931returnV;
1932}
1933
1934Constant *ConstantFoldFP(double (*NativeFP)(double),constAPFloat &V,
1935Type *Ty) {
1936 llvm_fenv_clearexcept();
1937doubleResult = NativeFP(V.convertToDouble());
1938if (llvm_fenv_testexcept()) {
1939 llvm_fenv_clearexcept();
1940returnnullptr;
1941 }
1942
1943return GetConstantFoldFPValue(Result, Ty);
1944}
1945
1946#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
1947Constant *ConstantFoldFP128(float128 (*NativeFP)(float128),constAPFloat &V,
1948Type *Ty) {
1949 llvm_fenv_clearexcept();
1950 float128Result = NativeFP(V.convertToQuad());
1951if (llvm_fenv_testexcept()) {
1952 llvm_fenv_clearexcept();
1953returnnullptr;
1954 }
1955
1956return GetConstantFoldFPValue128(Result, Ty);
1957}
1958#endif
1959
1960Constant *ConstantFoldBinaryFP(double (*NativeFP)(double,double),
1961constAPFloat &V,constAPFloat &W,Type *Ty) {
1962 llvm_fenv_clearexcept();
1963doubleResult = NativeFP(V.convertToDouble(),W.convertToDouble());
1964if (llvm_fenv_testexcept()) {
1965 llvm_fenv_clearexcept();
1966returnnullptr;
1967 }
1968
1969return GetConstantFoldFPValue(Result, Ty);
1970}
1971
1972Constant *constantFoldVectorReduce(Intrinsic::ID IID,Constant *Op) {
1973FixedVectorType *VT = dyn_cast<FixedVectorType>(Op->getType());
1974if (!VT)
1975returnnullptr;
1976
1977// This isn't strictly necessary, but handle the special/common case of zero:
1978// all integer reductions of a zero input produce zero.
1979if (isa<ConstantAggregateZero>(Op))
1980return ConstantInt::get(VT->getElementType(), 0);
1981
1982// This is the same as the underlying binops - poison propagates.
1983if (isa<PoisonValue>(Op) ||Op->containsPoisonElement())
1984returnPoisonValue::get(VT->getElementType());
1985
1986// TODO: Handle undef.
1987if (!isa<ConstantVector>(Op) && !isa<ConstantDataVector>(Op))
1988returnnullptr;
1989
1990auto *EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(0U));
1991if (!EltC)
1992returnnullptr;
1993
1994APInt Acc = EltC->getValue();
1995for (unsignedI = 1, E = VT->getNumElements();I != E;I++) {
1996if (!(EltC = dyn_cast<ConstantInt>(Op->getAggregateElement(I))))
1997returnnullptr;
1998constAPInt &X = EltC->getValue();
1999switch (IID) {
2000case Intrinsic::vector_reduce_add:
2001 Acc = Acc +X;
2002break;
2003case Intrinsic::vector_reduce_mul:
2004 Acc = Acc *X;
2005break;
2006case Intrinsic::vector_reduce_and:
2007 Acc = Acc &X;
2008break;
2009case Intrinsic::vector_reduce_or:
2010 Acc = Acc |X;
2011break;
2012case Intrinsic::vector_reduce_xor:
2013 Acc = Acc ^X;
2014break;
2015case Intrinsic::vector_reduce_smin:
2016 Acc =APIntOps::smin(Acc,X);
2017break;
2018case Intrinsic::vector_reduce_smax:
2019 Acc =APIntOps::smax(Acc,X);
2020break;
2021case Intrinsic::vector_reduce_umin:
2022 Acc =APIntOps::umin(Acc,X);
2023break;
2024case Intrinsic::vector_reduce_umax:
2025 Acc =APIntOps::umax(Acc,X);
2026break;
2027 }
2028 }
2029
2030return ConstantInt::get(Op->getContext(), Acc);
2031}
2032
2033/// Attempt to fold an SSE floating point to integer conversion of a constant
2034/// floating point. If roundTowardZero is false, the default IEEE rounding is
2035/// used (toward nearest, ties to even). This matches the behavior of the
2036/// non-truncating SSE instructions in the default rounding mode. The desired
2037/// integer type Ty is used to select how many bits are available for the
2038/// result. Returns null if the conversion cannot be performed, otherwise
2039/// returns the Constant value resulting from the conversion.
2040Constant *ConstantFoldSSEConvertToInt(constAPFloat &Val,bool roundTowardZero,
2041Type *Ty,bool IsSigned) {
2042// All of these conversion intrinsics form an integer of at most 64bits.
2043unsigned ResultWidth = Ty->getIntegerBitWidth();
2044assert(ResultWidth <= 64 &&
2045"Can only constant fold conversions to 64 and 32 bit ints");
2046
2047uint64_t UIntVal;
2048bool isExact =false;
2049APFloat::roundingModemode = roundTowardZero? APFloat::rmTowardZero
2050 : APFloat::rmNearestTiesToEven;
2051APFloat::opStatusstatus =
2052 Val.convertToInteger(MutableArrayRef(UIntVal), ResultWidth,
2053 IsSigned,mode, &isExact);
2054if (status != APFloat::opOK &&
2055 (!roundTowardZero || status != APFloat::opInexact))
2056returnnullptr;
2057return ConstantInt::get(Ty, UIntVal, IsSigned);
2058}
2059
2060double getValueAsDouble(ConstantFP *Op) {
2061Type *Ty =Op->getType();
2062
2063if (Ty->isBFloatTy() || Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())
2064returnOp->getValueAPF().convertToDouble();
2065
2066bool unused;
2067APFloat APF =Op->getValueAPF();
2068 APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &unused);
2069return APF.convertToDouble();
2070}
2071
2072staticbool getConstIntOrUndef(Value *Op,constAPInt *&C) {
2073if (auto *CI = dyn_cast<ConstantInt>(Op)) {
2074C = &CI->getValue();
2075returntrue;
2076 }
2077if (isa<UndefValue>(Op)) {
2078C =nullptr;
2079returntrue;
2080 }
2081returnfalse;
2082}
2083
2084/// Checks if the given intrinsic call, which evaluates to constant, is allowed
2085/// to be folded.
2086///
2087/// \param CI Constrained intrinsic call.
2088/// \param St Exception flags raised during constant evaluation.
2089staticbool mayFoldConstrained(ConstrainedFPIntrinsic *CI,
2090APFloat::opStatus St) {
2091 std::optional<RoundingMode> ORM = CI->getRoundingMode();
2092 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
2093
2094// If the operation does not change exception status flags, it is safe
2095// to fold.
2096if (St == APFloat::opStatus::opOK)
2097returntrue;
2098
2099// If evaluation raised FP exception, the result can depend on rounding
2100// mode. If the latter is unknown, folding is not possible.
2101if (ORM && *ORM == RoundingMode::Dynamic)
2102returnfalse;
2103
2104// If FP exceptions are ignored, fold the call, even if such exception is
2105// raised.
2106if (EB && *EB != fp::ExceptionBehavior::ebStrict)
2107returntrue;
2108
2109// Leave the calculation for runtime so that exception flags be correctly set
2110// in hardware.
2111returnfalse;
2112}
2113
2114/// Returns the rounding mode that should be used for constant evaluation.
2115staticRoundingMode
2116getEvaluationRoundingMode(constConstrainedFPIntrinsic *CI) {
2117 std::optional<RoundingMode> ORM = CI->getRoundingMode();
2118if (!ORM || *ORM == RoundingMode::Dynamic)
2119// Even if the rounding mode is unknown, try evaluating the operation.
2120// If it does not raise inexact exception, rounding was not applied,
2121// so the result is exact and does not depend on rounding mode. Whether
2122// other FP exceptions are raised, it does not depend on rounding mode.
2123return RoundingMode::NearestTiesToEven;
2124return *ORM;
2125}
2126
2127/// Try to constant fold llvm.canonicalize for the given caller and value.
2128staticConstant *constantFoldCanonicalize(constType *Ty,constCallBase *CI,
2129constAPFloat &Src) {
2130// Zero, positive and negative, is always OK to fold.
2131if (Src.isZero()) {
2132// Get a fresh 0, since ppc_fp128 does have non-canonical zeros.
2133return ConstantFP::get(
2134 CI->getContext(),
2135APFloat::getZero(Src.getSemantics(), Src.isNegative()));
2136 }
2137
2138if (!Ty->isIEEELikeFPTy())
2139returnnullptr;
2140
2141// Zero is always canonical and the sign must be preserved.
2142//
2143// Denorms and nans may have special encodings, but it should be OK to fold a
2144// totally average number.
2145if (Src.isNormal() || Src.isInfinity())
2146return ConstantFP::get(CI->getContext(), Src);
2147
2148if (Src.isDenormal() && CI->getParent() && CI->getFunction()) {
2149DenormalMode DenormMode =
2150 CI->getFunction()->getDenormalMode(Src.getSemantics());
2151
2152if (DenormMode ==DenormalMode::getIEEE())
2153return ConstantFP::get(CI->getContext(), Src);
2154
2155if (DenormMode.Input ==DenormalMode::Dynamic)
2156returnnullptr;
2157
2158// If we know if either input or output is flushed, we can fold.
2159if ((DenormMode.Input ==DenormalMode::Dynamic &&
2160 DenormMode.Output ==DenormalMode::IEEE) ||
2161 (DenormMode.Input ==DenormalMode::IEEE &&
2162 DenormMode.Output ==DenormalMode::Dynamic))
2163returnnullptr;
2164
2165bool IsPositive =
2166 (!Src.isNegative() || DenormMode.Input ==DenormalMode::PositiveZero ||
2167 (DenormMode.Output ==DenormalMode::PositiveZero &&
2168 DenormMode.Input ==DenormalMode::IEEE));
2169
2170return ConstantFP::get(CI->getContext(),
2171APFloat::getZero(Src.getSemantics(), !IsPositive));
2172 }
2173
2174returnnullptr;
2175}
2176
2177staticConstant *ConstantFoldScalarCall1(StringRefName,
2178Intrinsic::ID IntrinsicID,
2179Type *Ty,
2180ArrayRef<Constant *>Operands,
2181constTargetLibraryInfo *TLI,
2182constCallBase *Call) {
2183assert(Operands.size() == 1 &&"Wrong number of operands.");
2184
2185if (IntrinsicID == Intrinsic::is_constant) {
2186// We know we have a "Constant" argument. But we want to only
2187// return true for manifest constants, not those that depend on
2188// constants with unknowable values, e.g. GlobalValue or BlockAddress.
2189if (Operands[0]->isManifestConstant())
2190returnConstantInt::getTrue(Ty->getContext());
2191returnnullptr;
2192 }
2193
2194if (isa<PoisonValue>(Operands[0])) {
2195// TODO: All of these operations should probably propagate poison.
2196if (IntrinsicID == Intrinsic::canonicalize)
2197returnPoisonValue::get(Ty);
2198 }
2199
2200if (isa<UndefValue>(Operands[0])) {
2201// cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
2202// ctpop() is between 0 and bitwidth, pick 0 for undef.
2203// fptoui.sat and fptosi.sat can always fold to zero (for a zero input).
2204if (IntrinsicID == Intrinsic::cos ||
2205 IntrinsicID == Intrinsic::ctpop ||
2206 IntrinsicID == Intrinsic::fptoui_sat ||
2207 IntrinsicID == Intrinsic::fptosi_sat ||
2208 IntrinsicID == Intrinsic::canonicalize)
2209returnConstant::getNullValue(Ty);
2210if (IntrinsicID == Intrinsic::bswap ||
2211 IntrinsicID == Intrinsic::bitreverse ||
2212 IntrinsicID == Intrinsic::launder_invariant_group ||
2213 IntrinsicID == Intrinsic::strip_invariant_group)
2214returnOperands[0];
2215 }
2216
2217if (isa<ConstantPointerNull>(Operands[0])) {
2218// launder(null) == null == strip(null) iff in addrspace 0
2219if (IntrinsicID == Intrinsic::launder_invariant_group ||
2220 IntrinsicID == Intrinsic::strip_invariant_group) {
2221// If instruction is not yet put in a basic block (e.g. when cloning
2222// a function during inlining), Call's caller may not be available.
2223// So check Call's BB first before querying Call->getCaller.
2224constFunction *Caller =
2225Call->getParent() ?Call->getCaller() :nullptr;
2226if (Caller &&
2227 !NullPointerIsDefined(
2228 Caller,Operands[0]->getType()->getPointerAddressSpace())) {
2229returnOperands[0];
2230 }
2231returnnullptr;
2232 }
2233 }
2234
2235if (auto *Op = dyn_cast<ConstantFP>(Operands[0])) {
2236if (IntrinsicID == Intrinsic::convert_to_fp16) {
2237APFloat Val(Op->getValueAPF());
2238
2239bool lost =false;
2240 Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &lost);
2241
2242return ConstantInt::get(Ty->getContext(), Val.bitcastToAPInt());
2243 }
2244
2245APFloatU =Op->getValueAPF();
2246
2247if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
2248 IntrinsicID == Intrinsic::wasm_trunc_unsigned) {
2249boolSigned = IntrinsicID == Intrinsic::wasm_trunc_signed;
2250
2251if (U.isNaN())
2252returnnullptr;
2253
2254unsigned Width = Ty->getIntegerBitWidth();
2255APSIntInt(Width, !Signed);
2256bool IsExact =false;
2257APFloat::opStatusStatus =
2258U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
2259
2260if (Status == APFloat::opOK ||Status == APFloat::opInexact)
2261return ConstantInt::get(Ty,Int);
2262
2263returnnullptr;
2264 }
2265
2266if (IntrinsicID == Intrinsic::fptoui_sat ||
2267 IntrinsicID == Intrinsic::fptosi_sat) {
2268// convertToInteger() already has the desired saturation semantics.
2269APSIntInt(Ty->getIntegerBitWidth(),
2270 IntrinsicID == Intrinsic::fptoui_sat);
2271bool IsExact;
2272U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
2273return ConstantInt::get(Ty,Int);
2274 }
2275
2276if (IntrinsicID == Intrinsic::canonicalize)
2277return constantFoldCanonicalize(Ty, Call, U);
2278
2279#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
2280if (Ty->isFP128Ty()) {
2281if (IntrinsicID == Intrinsic::log) {
2282 float128Result = logf128(Op->getValueAPF().convertToQuad());
2283return GetConstantFoldFPValue128(Result, Ty);
2284 }
2285
2286LibFunc Fp128Func =NotLibFunc;
2287if (TLI && TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) &&
2288 Fp128Func == LibFunc_logl)
2289return ConstantFoldFP128(logf128,Op->getValueAPF(), Ty);
2290 }
2291#endif
2292
2293if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() &&
2294 !Ty->isIntegerTy())
2295returnnullptr;
2296
2297// Use internal versions of these intrinsics.
2298
2299if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
2300U.roundToIntegral(APFloat::rmNearestTiesToEven);
2301return ConstantFP::get(Ty->getContext(), U);
2302 }
2303
2304if (IntrinsicID == Intrinsic::round) {
2305U.roundToIntegral(APFloat::rmNearestTiesToAway);
2306return ConstantFP::get(Ty->getContext(), U);
2307 }
2308
2309if (IntrinsicID == Intrinsic::roundeven) {
2310U.roundToIntegral(APFloat::rmNearestTiesToEven);
2311return ConstantFP::get(Ty->getContext(), U);
2312 }
2313
2314if (IntrinsicID == Intrinsic::ceil) {
2315U.roundToIntegral(APFloat::rmTowardPositive);
2316return ConstantFP::get(Ty->getContext(), U);
2317 }
2318
2319if (IntrinsicID == Intrinsic::floor) {
2320U.roundToIntegral(APFloat::rmTowardNegative);
2321return ConstantFP::get(Ty->getContext(), U);
2322 }
2323
2324if (IntrinsicID == Intrinsic::trunc) {
2325U.roundToIntegral(APFloat::rmTowardZero);
2326return ConstantFP::get(Ty->getContext(), U);
2327 }
2328
2329if (IntrinsicID == Intrinsic::fabs) {
2330U.clearSign();
2331return ConstantFP::get(Ty->getContext(), U);
2332 }
2333
2334if (IntrinsicID == Intrinsic::amdgcn_fract) {
2335// The v_fract instruction behaves like the OpenCL spec, which defines
2336// fract(x) as fmin(x - floor(x), 0x1.fffffep-1f): "The min() operator is
2337// there to prevent fract(-small) from returning 1.0. It returns the
2338// largest positive floating-point number less than 1.0."
2339APFloat FloorU(U);
2340 FloorU.roundToIntegral(APFloat::rmTowardNegative);
2341APFloat FractU(U - FloorU);
2342APFloat AlmostOne(U.getSemantics(), 1);
2343 AlmostOne.next(/*nextDown*/true);
2344return ConstantFP::get(Ty->getContext(),minimum(FractU, AlmostOne));
2345 }
2346
2347// Rounding operations (floor, trunc, ceil, round and nearbyint) do not
2348// raise FP exceptions, unless the argument is signaling NaN.
2349
2350 std::optional<APFloat::roundingMode>RM;
2351switch (IntrinsicID) {
2352default:
2353break;
2354case Intrinsic::experimental_constrained_nearbyint:
2355case Intrinsic::experimental_constrained_rint: {
2356auto CI = cast<ConstrainedFPIntrinsic>(Call);
2357RM = CI->getRoundingMode();
2358if (!RM || *RM == RoundingMode::Dynamic)
2359returnnullptr;
2360break;
2361 }
2362case Intrinsic::experimental_constrained_round:
2363RM = APFloat::rmNearestTiesToAway;
2364break;
2365case Intrinsic::experimental_constrained_ceil:
2366RM = APFloat::rmTowardPositive;
2367break;
2368case Intrinsic::experimental_constrained_floor:
2369RM = APFloat::rmTowardNegative;
2370break;
2371case Intrinsic::experimental_constrained_trunc:
2372RM = APFloat::rmTowardZero;
2373break;
2374 }
2375if (RM) {
2376auto CI = cast<ConstrainedFPIntrinsic>(Call);
2377if (U.isFinite()) {
2378APFloat::opStatus St =U.roundToIntegral(*RM);
2379if (IntrinsicID == Intrinsic::experimental_constrained_rint &&
2380 St == APFloat::opInexact) {
2381 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
2382if (EB && *EB ==fp::ebStrict)
2383returnnullptr;
2384 }
2385 }elseif (U.isSignaling()) {
2386 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
2387if (EB && *EB !=fp::ebIgnore)
2388returnnullptr;
2389U =APFloat::getQNaN(U.getSemantics());
2390 }
2391return ConstantFP::get(Ty->getContext(), U);
2392 }
2393
2394// NVVM float/double to signed/unsigned int32/int64 conversions:
2395switch (IntrinsicID) {
2396// f2i
2397case Intrinsic::nvvm_f2i_rm:
2398case Intrinsic::nvvm_f2i_rn:
2399case Intrinsic::nvvm_f2i_rp:
2400case Intrinsic::nvvm_f2i_rz:
2401case Intrinsic::nvvm_f2i_rm_ftz:
2402case Intrinsic::nvvm_f2i_rn_ftz:
2403case Intrinsic::nvvm_f2i_rp_ftz:
2404case Intrinsic::nvvm_f2i_rz_ftz:
2405// f2ui
2406case Intrinsic::nvvm_f2ui_rm:
2407case Intrinsic::nvvm_f2ui_rn:
2408case Intrinsic::nvvm_f2ui_rp:
2409case Intrinsic::nvvm_f2ui_rz:
2410case Intrinsic::nvvm_f2ui_rm_ftz:
2411case Intrinsic::nvvm_f2ui_rn_ftz:
2412case Intrinsic::nvvm_f2ui_rp_ftz:
2413case Intrinsic::nvvm_f2ui_rz_ftz:
2414// d2i
2415case Intrinsic::nvvm_d2i_rm:
2416case Intrinsic::nvvm_d2i_rn:
2417case Intrinsic::nvvm_d2i_rp:
2418case Intrinsic::nvvm_d2i_rz:
2419// d2ui
2420case Intrinsic::nvvm_d2ui_rm:
2421case Intrinsic::nvvm_d2ui_rn:
2422case Intrinsic::nvvm_d2ui_rp:
2423case Intrinsic::nvvm_d2ui_rz:
2424// f2ll
2425case Intrinsic::nvvm_f2ll_rm:
2426case Intrinsic::nvvm_f2ll_rn:
2427case Intrinsic::nvvm_f2ll_rp:
2428case Intrinsic::nvvm_f2ll_rz:
2429case Intrinsic::nvvm_f2ll_rm_ftz:
2430case Intrinsic::nvvm_f2ll_rn_ftz:
2431case Intrinsic::nvvm_f2ll_rp_ftz:
2432case Intrinsic::nvvm_f2ll_rz_ftz:
2433// f2ull
2434case Intrinsic::nvvm_f2ull_rm:
2435case Intrinsic::nvvm_f2ull_rn:
2436case Intrinsic::nvvm_f2ull_rp:
2437case Intrinsic::nvvm_f2ull_rz:
2438case Intrinsic::nvvm_f2ull_rm_ftz:
2439case Intrinsic::nvvm_f2ull_rn_ftz:
2440case Intrinsic::nvvm_f2ull_rp_ftz:
2441case Intrinsic::nvvm_f2ull_rz_ftz:
2442// d2ll
2443case Intrinsic::nvvm_d2ll_rm:
2444case Intrinsic::nvvm_d2ll_rn:
2445case Intrinsic::nvvm_d2ll_rp:
2446case Intrinsic::nvvm_d2ll_rz:
2447// d2ull
2448case Intrinsic::nvvm_d2ull_rm:
2449case Intrinsic::nvvm_d2ull_rn:
2450case Intrinsic::nvvm_d2ull_rp:
2451case Intrinsic::nvvm_d2ull_rz: {
2452// In float-to-integer conversion, NaN inputs are converted to 0.
2453if (U.isNaN())
2454return ConstantInt::get(Ty, 0);
2455
2456APFloat::roundingMode RMode =
2457nvvm::GetFPToIntegerRoundingMode(IntrinsicID);
2458bool IsFTZ =nvvm::FPToIntegerIntrinsicShouldFTZ(IntrinsicID);
2459bool IsSigned =nvvm::FPToIntegerIntrinsicResultIsSigned(IntrinsicID);
2460
2461APSInt ResInt(Ty->getIntegerBitWidth(), !IsSigned);
2462auto FloatToRound = IsFTZ ? FTZPreserveSign(U) :U;
2463
2464bool IsExact =false;
2465APFloat::opStatusStatus =
2466 FloatToRound.convertToInteger(ResInt, RMode, &IsExact);
2467
2468if (Status != APFloat::opInvalidOp)
2469return ConstantInt::get(Ty, ResInt);
2470returnnullptr;
2471 }
2472 }
2473
2474 /// We only fold functions with finite arguments. Folding NaN and inf is
2475 /// likely to be aborted with an exception anyway, and some host libms
2476 /// have known errors raising exceptions.
2477if (!U.isFinite())
2478returnnullptr;
2479
2480 /// Currently APFloat versions of these functions do not exist, so we use
2481 /// the host native double versions. Float versions are not called
2482 /// directly but for all these it is true (float)(f((double)arg)) ==
2483 /// f(arg). Long double not supported yet.
2484constAPFloat &APF =Op->getValueAPF();
2485
2486switch (IntrinsicID) {
2487default:break;
2488case Intrinsic::log:
2489return ConstantFoldFP(log, APF, Ty);
2490case Intrinsic::log2:
2491// TODO: What about hosts that lack a C99 library?
2492return ConstantFoldFP(log2, APF, Ty);
2493case Intrinsic::log10:
2494// TODO: What about hosts that lack a C99 library?
2495return ConstantFoldFP(log10, APF, Ty);
2496case Intrinsic::exp:
2497return ConstantFoldFP(exp, APF, Ty);
2498case Intrinsic::exp2:
2499// Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.
2500return ConstantFoldBinaryFP(pow,APFloat(2.0), APF, Ty);
2501case Intrinsic::exp10:
2502// Fold exp10(x) as pow(10, x), in case the host lacks a C99 library.
2503return ConstantFoldBinaryFP(pow,APFloat(10.0), APF, Ty);
2504case Intrinsic::sin:
2505return ConstantFoldFP(sin, APF, Ty);
2506case Intrinsic::cos:
2507return ConstantFoldFP(cos, APF, Ty);
2508case Intrinsic::sqrt:
2509return ConstantFoldFP(sqrt, APF, Ty);
2510case Intrinsic::amdgcn_cos:
2511case Intrinsic::amdgcn_sin: {
2512doubleV = getValueAsDouble(Op);
2513if (V < -256.0 || V > 256.0)
2514// The gfx8 and gfx9 architectures handle arguments outside the range
2515// [-256, 256] differently. This should be a rare case so bail out
2516// rather than trying to handle the difference.
2517returnnullptr;
2518bool IsCos = IntrinsicID == Intrinsic::amdgcn_cos;
2519doubleV4 =V * 4.0;
2520if (V4 == floor(V4)) {
2521// Force exact results for quarter-integer inputs.
2522constdouble SinVals[4] = { 0.0, 1.0, 0.0, -1.0 };
2523V = SinVals[((int)V4 + (IsCos ? 1 : 0)) & 3];
2524 }else {
2525if (IsCos)
2526V = cos(V * 2.0 *numbers::pi);
2527else
2528V = sin(V * 2.0 *numbers::pi);
2529 }
2530return GetConstantFoldFPValue(V, Ty);
2531 }
2532 }
2533
2534if (!TLI)
2535returnnullptr;
2536
2537LibFuncFunc =NotLibFunc;
2538if (!TLI->getLibFunc(Name, Func))
2539returnnullptr;
2540
2541switch (Func) {
2542default:
2543break;
2544case LibFunc_acos:
2545case LibFunc_acosf:
2546case LibFunc_acos_finite:
2547case LibFunc_acosf_finite:
2548if (TLI->has(Func))
2549return ConstantFoldFP(acos, APF, Ty);
2550break;
2551case LibFunc_asin:
2552case LibFunc_asinf:
2553case LibFunc_asin_finite:
2554case LibFunc_asinf_finite:
2555if (TLI->has(Func))
2556return ConstantFoldFP(asin, APF, Ty);
2557break;
2558case LibFunc_atan:
2559case LibFunc_atanf:
2560if (TLI->has(Func))
2561return ConstantFoldFP(atan, APF, Ty);
2562break;
2563case LibFunc_ceil:
2564case LibFunc_ceilf:
2565if (TLI->has(Func)) {
2566U.roundToIntegral(APFloat::rmTowardPositive);
2567return ConstantFP::get(Ty->getContext(), U);
2568 }
2569break;
2570case LibFunc_cos:
2571case LibFunc_cosf:
2572if (TLI->has(Func))
2573return ConstantFoldFP(cos, APF, Ty);
2574break;
2575case LibFunc_cosh:
2576case LibFunc_coshf:
2577case LibFunc_cosh_finite:
2578case LibFunc_coshf_finite:
2579if (TLI->has(Func))
2580return ConstantFoldFP(cosh, APF, Ty);
2581break;
2582case LibFunc_exp:
2583case LibFunc_expf:
2584case LibFunc_exp_finite:
2585case LibFunc_expf_finite:
2586if (TLI->has(Func))
2587return ConstantFoldFP(exp, APF, Ty);
2588break;
2589case LibFunc_exp2:
2590case LibFunc_exp2f:
2591case LibFunc_exp2_finite:
2592case LibFunc_exp2f_finite:
2593if (TLI->has(Func))
2594// Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.
2595return ConstantFoldBinaryFP(pow,APFloat(2.0), APF, Ty);
2596break;
2597case LibFunc_fabs:
2598case LibFunc_fabsf:
2599if (TLI->has(Func)) {
2600U.clearSign();
2601return ConstantFP::get(Ty->getContext(), U);
2602 }
2603break;
2604case LibFunc_floor:
2605case LibFunc_floorf:
2606if (TLI->has(Func)) {
2607U.roundToIntegral(APFloat::rmTowardNegative);
2608return ConstantFP::get(Ty->getContext(), U);
2609 }
2610break;
2611case LibFunc_log:
2612case LibFunc_logf:
2613case LibFunc_log_finite:
2614case LibFunc_logf_finite:
2615if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
2616return ConstantFoldFP(log, APF, Ty);
2617break;
2618case LibFunc_log2:
2619case LibFunc_log2f:
2620case LibFunc_log2_finite:
2621case LibFunc_log2f_finite:
2622if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
2623// TODO: What about hosts that lack a C99 library?
2624return ConstantFoldFP(log2, APF, Ty);
2625break;
2626case LibFunc_log10:
2627case LibFunc_log10f:
2628case LibFunc_log10_finite:
2629case LibFunc_log10f_finite:
2630if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))
2631// TODO: What about hosts that lack a C99 library?
2632return ConstantFoldFP(log10, APF, Ty);
2633break;
2634case LibFunc_ilogb:
2635case LibFunc_ilogbf:
2636if (!APF.isZero() && TLI->has(Func))
2637return ConstantInt::get(Ty,ilogb(APF),true);
2638break;
2639case LibFunc_logb:
2640case LibFunc_logbf:
2641if (!APF.isZero() && TLI->has(Func))
2642return ConstantFoldFP(logb, APF, Ty);
2643break;
2644case LibFunc_log1p:
2645case LibFunc_log1pf:
2646// Implement optional behavior from C's Annex F for +/-0.0.
2647if (U.isZero())
2648return ConstantFP::get(Ty->getContext(), U);
2649if (APF >APFloat::getOne(APF.getSemantics(),true) && TLI->has(Func))
2650return ConstantFoldFP(log1p, APF, Ty);
2651break;
2652case LibFunc_logl:
2653returnnullptr;
2654case LibFunc_erf:
2655case LibFunc_erff:
2656if (TLI->has(Func))
2657return ConstantFoldFP(erf, APF, Ty);
2658break;
2659case LibFunc_nearbyint:
2660case LibFunc_nearbyintf:
2661case LibFunc_rint:
2662case LibFunc_rintf:
2663if (TLI->has(Func)) {
2664U.roundToIntegral(APFloat::rmNearestTiesToEven);
2665return ConstantFP::get(Ty->getContext(), U);
2666 }
2667break;
2668case LibFunc_round:
2669case LibFunc_roundf:
2670if (TLI->has(Func)) {
2671U.roundToIntegral(APFloat::rmNearestTiesToAway);
2672return ConstantFP::get(Ty->getContext(), U);
2673 }
2674break;
2675case LibFunc_sin:
2676case LibFunc_sinf:
2677if (TLI->has(Func))
2678return ConstantFoldFP(sin, APF, Ty);
2679break;
2680case LibFunc_sinh:
2681case LibFunc_sinhf:
2682case LibFunc_sinh_finite:
2683case LibFunc_sinhf_finite:
2684if (TLI->has(Func))
2685return ConstantFoldFP(sinh, APF, Ty);
2686break;
2687case LibFunc_sqrt:
2688case LibFunc_sqrtf:
2689if (!APF.isNegative() && TLI->has(Func))
2690return ConstantFoldFP(sqrt, APF, Ty);
2691break;
2692case LibFunc_tan:
2693case LibFunc_tanf:
2694if (TLI->has(Func))
2695return ConstantFoldFP(tan, APF, Ty);
2696break;
2697case LibFunc_tanh:
2698case LibFunc_tanhf:
2699if (TLI->has(Func))
2700return ConstantFoldFP(tanh, APF, Ty);
2701break;
2702case LibFunc_trunc:
2703case LibFunc_truncf:
2704if (TLI->has(Func)) {
2705U.roundToIntegral(APFloat::rmTowardZero);
2706return ConstantFP::get(Ty->getContext(), U);
2707 }
2708break;
2709 }
2710returnnullptr;
2711 }
2712
2713if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
2714switch (IntrinsicID) {
2715case Intrinsic::bswap:
2716return ConstantInt::get(Ty->getContext(),Op->getValue().byteSwap());
2717case Intrinsic::ctpop:
2718return ConstantInt::get(Ty,Op->getValue().popcount());
2719case Intrinsic::bitreverse:
2720return ConstantInt::get(Ty->getContext(),Op->getValue().reverseBits());
2721case Intrinsic::convert_from_fp16: {
2722APFloat Val(APFloat::IEEEhalf(),Op->getValue());
2723
2724bool lost =false;
2725APFloat::opStatusstatus = Val.convert(
2726 Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &lost);
2727
2728// Conversion is always precise.
2729 (void)status;
2730assert(status != APFloat::opInexact && !lost &&
2731"Precision lost during fp16 constfolding");
2732
2733return ConstantFP::get(Ty->getContext(), Val);
2734 }
2735
2736case Intrinsic::amdgcn_s_wqm: {
2737uint64_t Val =Op->getZExtValue();
2738 Val |= (Val & 0x5555555555555555ULL) << 1 |
2739 ((Val >> 1) & 0x5555555555555555ULL);
2740 Val |= (Val & 0x3333333333333333ULL) << 2 |
2741 ((Val >> 2) & 0x3333333333333333ULL);
2742return ConstantInt::get(Ty, Val);
2743 }
2744
2745case Intrinsic::amdgcn_s_quadmask: {
2746uint64_t Val =Op->getZExtValue();
2747uint64_t QuadMask = 0;
2748for (unsignedI = 0;I <Op->getBitWidth() / 4; ++I, Val >>= 4) {
2749if (!(Val & 0xF))
2750continue;
2751
2752 QuadMask |= (1ULL <<I);
2753 }
2754return ConstantInt::get(Ty, QuadMask);
2755 }
2756
2757case Intrinsic::amdgcn_s_bitreplicate: {
2758uint64_t Val =Op->getZExtValue();
2759 Val = (Val & 0x000000000000FFFFULL) | (Val & 0x00000000FFFF0000ULL) << 16;
2760 Val = (Val & 0x000000FF000000FFULL) | (Val & 0x0000FF000000FF00ULL) << 8;
2761 Val = (Val & 0x000F000F000F000FULL) | (Val & 0x00F000F000F000F0ULL) << 4;
2762 Val = (Val & 0x0303030303030303ULL) | (Val & 0x0C0C0C0C0C0C0C0CULL) << 2;
2763 Val = (Val & 0x1111111111111111ULL) | (Val & 0x2222222222222222ULL) << 1;
2764 Val = Val | Val << 1;
2765return ConstantInt::get(Ty, Val);
2766 }
2767
2768default:
2769returnnullptr;
2770 }
2771 }
2772
2773switch (IntrinsicID) {
2774default:break;
2775case Intrinsic::vector_reduce_add:
2776case Intrinsic::vector_reduce_mul:
2777case Intrinsic::vector_reduce_and:
2778case Intrinsic::vector_reduce_or:
2779case Intrinsic::vector_reduce_xor:
2780case Intrinsic::vector_reduce_smin:
2781case Intrinsic::vector_reduce_smax:
2782case Intrinsic::vector_reduce_umin:
2783case Intrinsic::vector_reduce_umax:
2784if (Constant *C = constantFoldVectorReduce(IntrinsicID,Operands[0]))
2785returnC;
2786break;
2787 }
2788
2789// Support ConstantVector in case we have an Undef in the top.
2790if (isa<ConstantVector>(Operands[0]) ||
2791 isa<ConstantDataVector>(Operands[0])) {
2792auto *Op = cast<Constant>(Operands[0]);
2793switch (IntrinsicID) {
2794default:break;
2795case Intrinsic::x86_sse_cvtss2si:
2796case Intrinsic::x86_sse_cvtss2si64:
2797case Intrinsic::x86_sse2_cvtsd2si:
2798case Intrinsic::x86_sse2_cvtsd2si64:
2799if (ConstantFP *FPOp =
2800 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
2801return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2802/*roundTowardZero=*/false, Ty,
2803/*IsSigned*/true);
2804break;
2805case Intrinsic::x86_sse_cvttss2si:
2806case Intrinsic::x86_sse_cvttss2si64:
2807case Intrinsic::x86_sse2_cvttsd2si:
2808case Intrinsic::x86_sse2_cvttsd2si64:
2809if (ConstantFP *FPOp =
2810 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
2811return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2812/*roundTowardZero=*/true, Ty,
2813/*IsSigned*/true);
2814break;
2815 }
2816 }
2817
2818returnnullptr;
2819}
2820
2821staticConstant *evaluateCompare(constAPFloat &Op1,constAPFloat &Op2,
2822constConstrainedFPIntrinsic *Call) {
2823APFloat::opStatus St = APFloat::opOK;
2824auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
2825FCmpInst::PredicateCond = FCmp->getPredicate();
2826if (FCmp->isSignaling()) {
2827if (Op1.isNaN() || Op2.isNaN())
2828 St = APFloat::opInvalidOp;
2829 }else {
2830if (Op1.isSignaling() || Op2.isSignaling())
2831 St = APFloat::opInvalidOp;
2832 }
2833boolResult =FCmpInst::compare(Op1, Op2,Cond);
2834if (mayFoldConstrained(const_cast<ConstrainedFPCmpIntrinsic *>(FCmp), St))
2835return ConstantInt::get(Call->getType()->getScalarType(), Result);
2836returnnullptr;
2837}
2838
2839staticConstant *ConstantFoldLibCall2(StringRefName,Type *Ty,
2840ArrayRef<Constant *>Operands,
2841constTargetLibraryInfo *TLI) {
2842if (!TLI)
2843returnnullptr;
2844
2845LibFuncFunc =NotLibFunc;
2846if (!TLI->getLibFunc(Name, Func))
2847returnnullptr;
2848
2849constauto *Op1 = dyn_cast<ConstantFP>(Operands[0]);
2850if (!Op1)
2851returnnullptr;
2852
2853constauto *Op2 = dyn_cast<ConstantFP>(Operands[1]);
2854if (!Op2)
2855returnnullptr;
2856
2857constAPFloat &Op1V = Op1->getValueAPF();
2858constAPFloat &Op2V = Op2->getValueAPF();
2859
2860switch (Func) {
2861default:
2862break;
2863case LibFunc_pow:
2864case LibFunc_powf:
2865case LibFunc_pow_finite:
2866case LibFunc_powf_finite:
2867if (TLI->has(Func))
2868return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
2869break;
2870case LibFunc_fmod:
2871case LibFunc_fmodf:
2872if (TLI->has(Func)) {
2873APFloatV = Op1->getValueAPF();
2874if (APFloat::opStatus::opOK ==V.mod(Op2->getValueAPF()))
2875return ConstantFP::get(Ty->getContext(), V);
2876 }
2877break;
2878case LibFunc_remainder:
2879case LibFunc_remainderf:
2880if (TLI->has(Func)) {
2881APFloatV = Op1->getValueAPF();
2882if (APFloat::opStatus::opOK ==V.remainder(Op2->getValueAPF()))
2883return ConstantFP::get(Ty->getContext(), V);
2884 }
2885break;
2886case LibFunc_atan2:
2887case LibFunc_atan2f:
2888// atan2(+/-0.0, +/-0.0) is known to raise an exception on some libm
2889// (Solaris), so we do not assume a known result for that.
2890if (Op1V.isZero() && Op2V.isZero())
2891returnnullptr;
2892 [[fallthrough]];
2893case LibFunc_atan2_finite:
2894case LibFunc_atan2f_finite:
2895if (TLI->has(Func))
2896return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
2897break;
2898 }
2899
2900returnnullptr;
2901}
2902
2903staticConstant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID,Type *Ty,
2904ArrayRef<Constant *>Operands,
2905constCallBase *Call) {
2906assert(Operands.size() == 2 &&"Wrong number of operands.");
2907
2908if (Ty->isFloatingPointTy()) {
2909// TODO: We should have undef handling for all of the FP intrinsics that
2910// are attempted to be folded in this function.
2911bool IsOp0Undef = isa<UndefValue>(Operands[0]);
2912bool IsOp1Undef = isa<UndefValue>(Operands[1]);
2913switch (IntrinsicID) {
2914case Intrinsic::maxnum:
2915case Intrinsic::minnum:
2916case Intrinsic::maximum:
2917case Intrinsic::minimum:
2918case Intrinsic::nvvm_fmax_d:
2919case Intrinsic::nvvm_fmin_d:
2920// If one argument is undef, return the other argument.
2921if (IsOp0Undef)
2922returnOperands[1];
2923if (IsOp1Undef)
2924returnOperands[0];
2925break;
2926
2927case Intrinsic::nvvm_fmax_f:
2928case Intrinsic::nvvm_fmax_ftz_f:
2929case Intrinsic::nvvm_fmax_ftz_nan_f:
2930case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
2931case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
2932case Intrinsic::nvvm_fmax_nan_f:
2933case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
2934case Intrinsic::nvvm_fmax_xorsign_abs_f:
2935
2936case Intrinsic::nvvm_fmin_f:
2937case Intrinsic::nvvm_fmin_ftz_f:
2938case Intrinsic::nvvm_fmin_ftz_nan_f:
2939case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
2940case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
2941case Intrinsic::nvvm_fmin_nan_f:
2942case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
2943case Intrinsic::nvvm_fmin_xorsign_abs_f:
2944// If one arg is undef, the other arg can be returned only if it is
2945// constant, as we may need to flush it to sign-preserving zero or
2946// canonicalize the NaN.
2947if (!IsOp0Undef && !IsOp1Undef)
2948break;
2949if (auto *Op = dyn_cast<ConstantFP>(Operands[IsOp0Undef ? 1 : 0])) {
2950if (Op->isNaN()) {
2951APInt NVCanonicalNaN(32, 0x7fffffff);
2952return ConstantFP::get(
2953 Ty,APFloat(Ty->getFltSemantics(), NVCanonicalNaN));
2954 }
2955if (nvvm::FMinFMaxShouldFTZ(IntrinsicID))
2956return ConstantFP::get(Ty, FTZPreserveSign(Op->getValueAPF()));
2957else
2958returnOp;
2959 }
2960break;
2961 }
2962 }
2963
2964if (constauto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
2965constAPFloat &Op1V = Op1->getValueAPF();
2966
2967if (constauto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
2968if (Op2->getType() != Op1->getType())
2969returnnullptr;
2970constAPFloat &Op2V = Op2->getValueAPF();
2971
2972if (constauto *ConstrIntr =
2973 dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {
2974RoundingModeRM = getEvaluationRoundingMode(ConstrIntr);
2975APFloat Res = Op1V;
2976APFloat::opStatus St;
2977switch (IntrinsicID) {
2978default:
2979returnnullptr;
2980case Intrinsic::experimental_constrained_fadd:
2981 St = Res.add(Op2V, RM);
2982break;
2983case Intrinsic::experimental_constrained_fsub:
2984 St = Res.subtract(Op2V, RM);
2985break;
2986case Intrinsic::experimental_constrained_fmul:
2987 St = Res.multiply(Op2V, RM);
2988break;
2989case Intrinsic::experimental_constrained_fdiv:
2990 St = Res.divide(Op2V, RM);
2991break;
2992case Intrinsic::experimental_constrained_frem:
2993 St = Res.mod(Op2V);
2994break;
2995case Intrinsic::experimental_constrained_fcmp:
2996case Intrinsic::experimental_constrained_fcmps:
2997return evaluateCompare(Op1V, Op2V, ConstrIntr);
2998 }
2999if (mayFoldConstrained(const_cast<ConstrainedFPIntrinsic *>(ConstrIntr),
3000 St))
3001return ConstantFP::get(Ty->getContext(), Res);
3002returnnullptr;
3003 }
3004
3005switch (IntrinsicID) {
3006default:
3007break;
3008case Intrinsic::copysign:
3009return ConstantFP::get(Ty->getContext(),APFloat::copySign(Op1V, Op2V));
3010case Intrinsic::minnum:
3011return ConstantFP::get(Ty->getContext(),minnum(Op1V, Op2V));
3012case Intrinsic::maxnum:
3013return ConstantFP::get(Ty->getContext(),maxnum(Op1V, Op2V));
3014case Intrinsic::minimum:
3015return ConstantFP::get(Ty->getContext(),minimum(Op1V, Op2V));
3016case Intrinsic::maximum:
3017return ConstantFP::get(Ty->getContext(),maximum(Op1V, Op2V));
3018
3019case Intrinsic::nvvm_fmax_d:
3020case Intrinsic::nvvm_fmax_f:
3021case Intrinsic::nvvm_fmax_ftz_f:
3022case Intrinsic::nvvm_fmax_ftz_nan_f:
3023case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
3024case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
3025case Intrinsic::nvvm_fmax_nan_f:
3026case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
3027case Intrinsic::nvvm_fmax_xorsign_abs_f:
3028
3029case Intrinsic::nvvm_fmin_d:
3030case Intrinsic::nvvm_fmin_f:
3031case Intrinsic::nvvm_fmin_ftz_f:
3032case Intrinsic::nvvm_fmin_ftz_nan_f:
3033case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:
3034case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:
3035case Intrinsic::nvvm_fmin_nan_f:
3036case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:
3037case Intrinsic::nvvm_fmin_xorsign_abs_f: {
3038
3039bool ShouldCanonicalizeNaNs = !(IntrinsicID == Intrinsic::nvvm_fmax_d ||
3040 IntrinsicID == Intrinsic::nvvm_fmin_d);
3041bool IsFTZ =nvvm::FMinFMaxShouldFTZ(IntrinsicID);
3042bool IsNaNPropagating =nvvm::FMinFMaxPropagatesNaNs(IntrinsicID);
3043bool IsXorSignAbs =nvvm::FMinFMaxIsXorSignAbs(IntrinsicID);
3044
3045APFloatA = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;
3046APFloatB = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;
3047
3048bool XorSign =false;
3049if (IsXorSignAbs) {
3050 XorSign =A.isNegative() ^B.isNegative();
3051A =abs(A);
3052B =abs(B);
3053 }
3054
3055bool IsFMax =false;
3056switch (IntrinsicID) {
3057case Intrinsic::nvvm_fmax_d:
3058case Intrinsic::nvvm_fmax_f:
3059case Intrinsic::nvvm_fmax_ftz_f:
3060case Intrinsic::nvvm_fmax_ftz_nan_f:
3061case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:
3062case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:
3063case Intrinsic::nvvm_fmax_nan_f:
3064case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:
3065case Intrinsic::nvvm_fmax_xorsign_abs_f:
3066 IsFMax =true;
3067break;
3068 }
3069APFloat Res = IsFMax ?maximum(A,B) :minimum(A,B);
3070
3071if (ShouldCanonicalizeNaNs) {
3072APFloat NVCanonicalNaN(Res.getSemantics(),APInt(32, 0x7fffffff));
3073if (A.isNaN() &&B.isNaN())
3074return ConstantFP::get(Ty, NVCanonicalNaN);
3075elseif (IsNaNPropagating && (A.isNaN() ||B.isNaN()))
3076return ConstantFP::get(Ty, NVCanonicalNaN);
3077 }
3078
3079if (A.isNaN() &&B.isNaN())
3080returnOperands[1];
3081elseif (A.isNaN())
3082 Res =B;
3083elseif (B.isNaN())
3084 Res =A;
3085
3086if (IsXorSignAbs && XorSign != Res.isNegative())
3087 Res.changeSign();
3088
3089return ConstantFP::get(Ty->getContext(), Res);
3090 }
3091 }
3092
3093if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
3094returnnullptr;
3095
3096switch (IntrinsicID) {
3097default:
3098break;
3099case Intrinsic::pow:
3100return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
3101case Intrinsic::amdgcn_fmul_legacy:
3102// The legacy behaviour is that multiplying +/- 0.0 by anything, even
3103// NaN or infinity, gives +0.0.
3104if (Op1V.isZero() || Op2V.isZero())
3105returnConstantFP::getZero(Ty);
3106return ConstantFP::get(Ty->getContext(), Op1V * Op2V);
3107 }
3108
3109 }elseif (auto *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
3110switch (IntrinsicID) {
3111case Intrinsic::ldexp: {
3112return ConstantFP::get(
3113 Ty->getContext(),
3114scalbn(Op1V, Op2C->getSExtValue(), APFloat::rmNearestTiesToEven));
3115 }
3116case Intrinsic::is_fpclass: {
3117FPClassTestMask =static_cast<FPClassTest>(Op2C->getZExtValue());
3118boolResult =
3119 ((Mask &fcSNan) && Op1V.isNaN() && Op1V.isSignaling()) ||
3120 ((Mask &fcQNan) && Op1V.isNaN() && !Op1V.isSignaling()) ||
3121 ((Mask &fcNegInf) && Op1V.isNegInfinity()) ||
3122 ((Mask &fcNegNormal) && Op1V.isNormal() && Op1V.isNegative()) ||
3123 ((Mask &fcNegSubnormal) && Op1V.isDenormal() && Op1V.isNegative()) ||
3124 ((Mask &fcNegZero) && Op1V.isZero() && Op1V.isNegative()) ||
3125 ((Mask &fcPosZero) && Op1V.isZero() && !Op1V.isNegative()) ||
3126 ((Mask &fcPosSubnormal) && Op1V.isDenormal() && !Op1V.isNegative()) ||
3127 ((Mask &fcPosNormal) && Op1V.isNormal() && !Op1V.isNegative()) ||
3128 ((Mask &fcPosInf) && Op1V.isPosInfinity());
3129return ConstantInt::get(Ty, Result);
3130 }
3131case Intrinsic::powi: {
3132intExp =static_cast<int>(Op2C->getSExtValue());
3133switch (Ty->getTypeID()) {
3134caseType::HalfTyID:
3135caseType::FloatTyID: {
3136APFloat Res(static_cast<float>(std::pow(Op1V.convertToFloat(), Exp)));
3137if (Ty->isHalfTy()) {
3138boolUnused;
3139 Res.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
3140 &Unused);
3141 }
3142return ConstantFP::get(Ty->getContext(), Res);
3143 }
3144caseType::DoubleTyID:
3145return ConstantFP::get(Ty, std::pow(Op1V.convertToDouble(), Exp));
3146default:
3147returnnullptr;
3148 }
3149 }
3150default:
3151break;
3152 }
3153 }
3154returnnullptr;
3155 }
3156
3157if (Operands[0]->getType()->isIntegerTy() &&
3158Operands[1]->getType()->isIntegerTy()) {
3159constAPInt *C0, *C1;
3160if (!getConstIntOrUndef(Operands[0], C0) ||
3161 !getConstIntOrUndef(Operands[1], C1))
3162returnnullptr;
3163
3164switch (IntrinsicID) {
3165default:break;
3166case Intrinsic::smax:
3167case Intrinsic::smin:
3168case Intrinsic::umax:
3169case Intrinsic::umin:
3170// This is the same as for binary ops - poison propagates.
3171// TODO: Poison handling should be consolidated.
3172if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3173returnPoisonValue::get(Ty);
3174
3175if (!C0 && !C1)
3176returnUndefValue::get(Ty);
3177if (!C0 || !C1)
3178returnMinMaxIntrinsic::getSaturationPoint(IntrinsicID, Ty);
3179return ConstantInt::get(
3180 Ty,ICmpInst::compare(*C0, *C1,
3181MinMaxIntrinsic::getPredicate(IntrinsicID))
3182 ? *C0
3183 : *C1);
3184
3185case Intrinsic::scmp:
3186case Intrinsic::ucmp:
3187if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3188returnPoisonValue::get(Ty);
3189
3190if (!C0 || !C1)
3191return ConstantInt::get(Ty, 0);
3192
3193int Res;
3194if (IntrinsicID == Intrinsic::scmp)
3195 Res = C0->sgt(*C1) ? 1 : C0->slt(*C1) ? -1 : 0;
3196else
3197 Res = C0->ugt(*C1) ? 1 : C0->ult(*C1) ? -1 : 0;
3198return ConstantInt::get(Ty, Res,/*IsSigned=*/true);
3199
3200case Intrinsic::usub_with_overflow:
3201case Intrinsic::ssub_with_overflow:
3202// X - undef -> { 0, false }
3203// undef - X -> { 0, false }
3204if (!C0 || !C1)
3205returnConstant::getNullValue(Ty);
3206 [[fallthrough]];
3207case Intrinsic::uadd_with_overflow:
3208case Intrinsic::sadd_with_overflow:
3209// X + undef -> { -1, false }
3210// undef + x -> { -1, false }
3211if (!C0 || !C1) {
3212returnConstantStruct::get(
3213 cast<StructType>(Ty),
3214 {Constant::getAllOnesValue(Ty->getStructElementType(0)),
3215Constant::getNullValue(Ty->getStructElementType(1))});
3216 }
3217 [[fallthrough]];
3218case Intrinsic::smul_with_overflow:
3219case Intrinsic::umul_with_overflow: {
3220// undef * X -> { 0, false }
3221// X * undef -> { 0, false }
3222if (!C0 || !C1)
3223returnConstant::getNullValue(Ty);
3224
3225APInt Res;
3226bool Overflow;
3227switch (IntrinsicID) {
3228default:llvm_unreachable("Invalid case");
3229case Intrinsic::sadd_with_overflow:
3230 Res = C0->sadd_ov(*C1, Overflow);
3231break;
3232case Intrinsic::uadd_with_overflow:
3233 Res = C0->uadd_ov(*C1, Overflow);
3234break;
3235case Intrinsic::ssub_with_overflow:
3236 Res = C0->ssub_ov(*C1, Overflow);
3237break;
3238case Intrinsic::usub_with_overflow:
3239 Res = C0->usub_ov(*C1, Overflow);
3240break;
3241case Intrinsic::smul_with_overflow:
3242 Res = C0->smul_ov(*C1, Overflow);
3243break;
3244case Intrinsic::umul_with_overflow:
3245 Res = C0->umul_ov(*C1, Overflow);
3246break;
3247 }
3248Constant *Ops[] = {
3249 ConstantInt::get(Ty->getContext(), Res),
3250 ConstantInt::get(Type::getInt1Ty(Ty->getContext()), Overflow)
3251 };
3252returnConstantStruct::get(cast<StructType>(Ty), Ops);
3253 }
3254case Intrinsic::uadd_sat:
3255case Intrinsic::sadd_sat:
3256// This is the same as for binary ops - poison propagates.
3257// TODO: Poison handling should be consolidated.
3258if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3259returnPoisonValue::get(Ty);
3260
3261if (!C0 && !C1)
3262returnUndefValue::get(Ty);
3263if (!C0 || !C1)
3264returnConstant::getAllOnesValue(Ty);
3265if (IntrinsicID == Intrinsic::uadd_sat)
3266return ConstantInt::get(Ty, C0->uadd_sat(*C1));
3267else
3268return ConstantInt::get(Ty, C0->sadd_sat(*C1));
3269case Intrinsic::usub_sat:
3270case Intrinsic::ssub_sat:
3271// This is the same as for binary ops - poison propagates.
3272// TODO: Poison handling should be consolidated.
3273if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3274returnPoisonValue::get(Ty);
3275
3276if (!C0 && !C1)
3277returnUndefValue::get(Ty);
3278if (!C0 || !C1)
3279returnConstant::getNullValue(Ty);
3280if (IntrinsicID == Intrinsic::usub_sat)
3281return ConstantInt::get(Ty, C0->usub_sat(*C1));
3282else
3283return ConstantInt::get(Ty, C0->ssub_sat(*C1));
3284case Intrinsic::cttz:
3285case Intrinsic::ctlz:
3286assert(C1 &&"Must be constant int");
3287
3288// cttz(0, 1) and ctlz(0, 1) are poison.
3289if (C1->isOne() && (!C0 || C0->isZero()))
3290returnPoisonValue::get(Ty);
3291if (!C0)
3292returnConstant::getNullValue(Ty);
3293if (IntrinsicID == Intrinsic::cttz)
3294return ConstantInt::get(Ty, C0->countr_zero());
3295else
3296return ConstantInt::get(Ty, C0->countl_zero());
3297
3298case Intrinsic::abs:
3299assert(C1 &&"Must be constant int");
3300assert((C1->isOne() || C1->isZero()) &&"Must be 0 or 1");
3301
3302// Undef or minimum val operand with poison min --> poison
3303if (C1->isOne() && (!C0 || C0->isMinSignedValue()))
3304returnPoisonValue::get(Ty);
3305
3306// Undef operand with no poison min --> 0 (sign bit must be clear)
3307if (!C0)
3308returnConstant::getNullValue(Ty);
3309
3310return ConstantInt::get(Ty, C0->abs());
3311case Intrinsic::amdgcn_wave_reduce_umin:
3312case Intrinsic::amdgcn_wave_reduce_umax:
3313return dyn_cast<Constant>(Operands[0]);
3314 }
3315
3316returnnullptr;
3317 }
3318
3319// Support ConstantVector in case we have an Undef in the top.
3320if ((isa<ConstantVector>(Operands[0]) ||
3321 isa<ConstantDataVector>(Operands[0])) &&
3322// Check for default rounding mode.
3323// FIXME: Support other rounding modes?
3324 isa<ConstantInt>(Operands[1]) &&
3325 cast<ConstantInt>(Operands[1])->getValue() == 4) {
3326auto *Op = cast<Constant>(Operands[0]);
3327switch (IntrinsicID) {
3328default:break;
3329case Intrinsic::x86_avx512_vcvtss2si32:
3330case Intrinsic::x86_avx512_vcvtss2si64:
3331case Intrinsic::x86_avx512_vcvtsd2si32:
3332case Intrinsic::x86_avx512_vcvtsd2si64:
3333if (ConstantFP *FPOp =
3334 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
3335return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3336/*roundTowardZero=*/false, Ty,
3337/*IsSigned*/true);
3338break;
3339case Intrinsic::x86_avx512_vcvtss2usi32:
3340case Intrinsic::x86_avx512_vcvtss2usi64:
3341case Intrinsic::x86_avx512_vcvtsd2usi32:
3342case Intrinsic::x86_avx512_vcvtsd2usi64:
3343if (ConstantFP *FPOp =
3344 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
3345return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3346/*roundTowardZero=*/false, Ty,
3347/*IsSigned*/false);
3348break;
3349case Intrinsic::x86_avx512_cvttss2si:
3350case Intrinsic::x86_avx512_cvttss2si64:
3351case Intrinsic::x86_avx512_cvttsd2si:
3352case Intrinsic::x86_avx512_cvttsd2si64:
3353if (ConstantFP *FPOp =
3354 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
3355return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3356/*roundTowardZero=*/true, Ty,
3357/*IsSigned*/true);
3358break;
3359case Intrinsic::x86_avx512_cvttss2usi:
3360case Intrinsic::x86_avx512_cvttss2usi64:
3361case Intrinsic::x86_avx512_cvttsd2usi:
3362case Intrinsic::x86_avx512_cvttsd2usi64:
3363if (ConstantFP *FPOp =
3364 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))
3365return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3366/*roundTowardZero=*/true, Ty,
3367/*IsSigned*/false);
3368break;
3369 }
3370 }
3371returnnullptr;
3372}
3373
3374staticAPFloat ConstantFoldAMDGCNCubeIntrinsic(Intrinsic::ID IntrinsicID,
3375constAPFloat &S0,
3376constAPFloat &S1,
3377constAPFloat &S2) {
3378unsignedID;
3379constfltSemantics &Sem = S0.getSemantics();
3380APFloat MA(Sem),SC(Sem), TC(Sem);
3381if (abs(S2) >=abs(S0) &&abs(S2) >=abs(S1)) {
3382if (S2.isNegative() && S2.isNonZero() && !S2.isNaN()) {
3383// S2 < 0
3384ID = 5;
3385SC = -S0;
3386 }else {
3387ID = 4;
3388SC = S0;
3389 }
3390 MA = S2;
3391 TC = -S1;
3392 }elseif (abs(S1) >=abs(S0)) {
3393if (S1.isNegative() &&S1.isNonZero() && !S1.isNaN()) {
3394// S1 < 0
3395ID = 3;
3396 TC = -S2;
3397 }else {
3398ID = 2;
3399 TC = S2;
3400 }
3401 MA =S1;
3402SC = S0;
3403 }else {
3404if (S0.isNegative() && S0.isNonZero() && !S0.isNaN()) {
3405// S0 < 0
3406ID = 1;
3407SC = S2;
3408 }else {
3409ID = 0;
3410SC = -S2;
3411 }
3412 MA = S0;
3413 TC = -S1;
3414 }
3415switch (IntrinsicID) {
3416default:
3417llvm_unreachable("unhandled amdgcn cube intrinsic");
3418case Intrinsic::amdgcn_cubeid:
3419returnAPFloat(Sem,ID);
3420case Intrinsic::amdgcn_cubema:
3421return MA + MA;
3422case Intrinsic::amdgcn_cubesc:
3423returnSC;
3424case Intrinsic::amdgcn_cubetc:
3425return TC;
3426 }
3427}
3428
3429staticConstant *ConstantFoldAMDGCNPermIntrinsic(ArrayRef<Constant *>Operands,
3430Type *Ty) {
3431constAPInt *C0, *C1, *C2;
3432if (!getConstIntOrUndef(Operands[0], C0) ||
3433 !getConstIntOrUndef(Operands[1], C1) ||
3434 !getConstIntOrUndef(Operands[2], C2))
3435returnnullptr;
3436
3437if (!C2)
3438returnUndefValue::get(Ty);
3439
3440APInt Val(32, 0);
3441unsigned NumUndefBytes = 0;
3442for (unsignedI = 0;I < 32;I += 8) {
3443unsigned Sel = C2->extractBitsAsZExtValue(8,I);
3444unsignedB = 0;
3445
3446if (Sel >= 13)
3447B = 0xff;
3448elseif (Sel == 12)
3449B = 0x00;
3450else {
3451constAPInt *Src = ((Sel & 10) == 10 || (Sel & 12) == 4) ? C0 : C1;
3452if (!Src)
3453 ++NumUndefBytes;
3454elseif (Sel < 8)
3455B = Src->extractBitsAsZExtValue(8, (Sel & 3) * 8);
3456else
3457B = Src->extractBitsAsZExtValue(1, (Sel & 1) ? 31 : 15) * 0xff;
3458 }
3459
3460 Val.insertBits(B,I, 8);
3461 }
3462
3463if (NumUndefBytes == 4)
3464returnUndefValue::get(Ty);
3465
3466return ConstantInt::get(Ty, Val);
3467}
3468
3469staticConstant *ConstantFoldScalarCall3(StringRefName,
3470Intrinsic::ID IntrinsicID,
3471Type *Ty,
3472ArrayRef<Constant *>Operands,
3473constTargetLibraryInfo *TLI,
3474constCallBase *Call) {
3475assert(Operands.size() == 3 &&"Wrong number of operands.");
3476
3477if (constauto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
3478if (constauto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
3479if (constauto *Op3 = dyn_cast<ConstantFP>(Operands[2])) {
3480constAPFloat &C1 = Op1->getValueAPF();
3481constAPFloat &C2 = Op2->getValueAPF();
3482constAPFloat &C3 = Op3->getValueAPF();
3483
3484if (constauto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {
3485RoundingModeRM = getEvaluationRoundingMode(ConstrIntr);
3486APFloat Res = C1;
3487APFloat::opStatus St;
3488switch (IntrinsicID) {
3489default:
3490returnnullptr;
3491case Intrinsic::experimental_constrained_fma:
3492case Intrinsic::experimental_constrained_fmuladd:
3493 St = Res.fusedMultiplyAdd(C2, C3, RM);
3494break;
3495 }
3496if (mayFoldConstrained(
3497const_cast<ConstrainedFPIntrinsic *>(ConstrIntr), St))
3498return ConstantFP::get(Ty->getContext(), Res);
3499returnnullptr;
3500 }
3501
3502switch (IntrinsicID) {
3503default:break;
3504case Intrinsic::amdgcn_fma_legacy: {
3505// The legacy behaviour is that multiplying +/- 0.0 by anything, even
3506// NaN or infinity, gives +0.0.
3507if (C1.isZero() || C2.isZero()) {
3508// It's tempting to just return C3 here, but that would give the
3509// wrong result if C3 was -0.0.
3510return ConstantFP::get(Ty->getContext(),APFloat(0.0f) + C3);
3511 }
3512 [[fallthrough]];
3513 }
3514case Intrinsic::fma:
3515case Intrinsic::fmuladd: {
3516APFloatV = C1;
3517V.fusedMultiplyAdd(C2, C3, APFloat::rmNearestTiesToEven);
3518return ConstantFP::get(Ty->getContext(), V);
3519 }
3520case Intrinsic::amdgcn_cubeid:
3521case Intrinsic::amdgcn_cubema:
3522case Intrinsic::amdgcn_cubesc:
3523case Intrinsic::amdgcn_cubetc: {
3524APFloatV = ConstantFoldAMDGCNCubeIntrinsic(IntrinsicID, C1, C2, C3);
3525return ConstantFP::get(Ty->getContext(), V);
3526 }
3527 }
3528 }
3529 }
3530 }
3531
3532if (IntrinsicID == Intrinsic::smul_fix ||
3533 IntrinsicID == Intrinsic::smul_fix_sat) {
3534// poison * C -> poison
3535// C * poison -> poison
3536if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3537returnPoisonValue::get(Ty);
3538
3539constAPInt *C0, *C1;
3540if (!getConstIntOrUndef(Operands[0], C0) ||
3541 !getConstIntOrUndef(Operands[1], C1))
3542returnnullptr;
3543
3544// undef * C -> 0
3545// C * undef -> 0
3546if (!C0 || !C1)
3547returnConstant::getNullValue(Ty);
3548
3549// This code performs rounding towards negative infinity in case the result
3550// cannot be represented exactly for the given scale. Targets that do care
3551// about rounding should use a target hook for specifying how rounding
3552// should be done, and provide their own folding to be consistent with
3553// rounding. This is the same approach as used by
3554// DAGTypeLegalizer::ExpandIntRes_MULFIX.
3555unsigned Scale = cast<ConstantInt>(Operands[2])->getZExtValue();
3556unsigned Width = C0->getBitWidth();
3557assert(Scale < Width &&"Illegal scale.");
3558unsigned ExtendedWidth = Width * 2;
3559APInt Product =
3560 (C0->sext(ExtendedWidth) * C1->sext(ExtendedWidth)).ashr(Scale);
3561if (IntrinsicID == Intrinsic::smul_fix_sat) {
3562APIntMax =APInt::getSignedMaxValue(Width).sext(ExtendedWidth);
3563APInt Min =APInt::getSignedMinValue(Width).sext(ExtendedWidth);
3564 Product =APIntOps::smin(Product, Max);
3565 Product =APIntOps::smax(Product, Min);
3566 }
3567return ConstantInt::get(Ty->getContext(), Product.sextOrTrunc(Width));
3568 }
3569
3570if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {
3571constAPInt *C0, *C1, *C2;
3572if (!getConstIntOrUndef(Operands[0], C0) ||
3573 !getConstIntOrUndef(Operands[1], C1) ||
3574 !getConstIntOrUndef(Operands[2], C2))
3575returnnullptr;
3576
3577bool IsRight = IntrinsicID == Intrinsic::fshr;
3578if (!C2)
3579returnOperands[IsRight ? 1 : 0];
3580if (!C0 && !C1)
3581returnUndefValue::get(Ty);
3582
3583// The shift amount is interpreted as modulo the bitwidth. If the shift
3584// amount is effectively 0, avoid UB due to oversized inverse shift below.
3585unsignedBitWidth = C2->getBitWidth();
3586unsigned ShAmt = C2->urem(BitWidth);
3587if (!ShAmt)
3588returnOperands[IsRight ? 1 : 0];
3589
3590// (C0 << ShlAmt) | (C1 >> LshrAmt)
3591unsigned LshrAmt = IsRight ? ShAmt :BitWidth - ShAmt;
3592unsigned ShlAmt = !IsRight ? ShAmt :BitWidth - ShAmt;
3593if (!C0)
3594return ConstantInt::get(Ty, C1->lshr(LshrAmt));
3595if (!C1)
3596return ConstantInt::get(Ty, C0->shl(ShlAmt));
3597return ConstantInt::get(Ty, C0->shl(ShlAmt) | C1->lshr(LshrAmt));
3598 }
3599
3600if (IntrinsicID == Intrinsic::amdgcn_perm)
3601return ConstantFoldAMDGCNPermIntrinsic(Operands, Ty);
3602
3603returnnullptr;
3604}
3605
3606staticConstant *ConstantFoldScalarCall(StringRefName,
3607Intrinsic::ID IntrinsicID,
3608Type *Ty,
3609ArrayRef<Constant *>Operands,
3610constTargetLibraryInfo *TLI,
3611constCallBase *Call) {
3612if (Operands.size() == 1)
3613return ConstantFoldScalarCall1(Name, IntrinsicID, Ty,Operands, TLI, Call);
3614
3615if (Operands.size() == 2) {
3616if (Constant *FoldedLibCall =
3617 ConstantFoldLibCall2(Name, Ty,Operands, TLI)) {
3618return FoldedLibCall;
3619 }
3620return ConstantFoldIntrinsicCall2(IntrinsicID, Ty,Operands, Call);
3621 }
3622
3623if (Operands.size() == 3)
3624return ConstantFoldScalarCall3(Name, IntrinsicID, Ty,Operands, TLI, Call);
3625
3626returnnullptr;
3627}
3628
3629staticConstant *ConstantFoldFixedVectorCall(
3630StringRefName,Intrinsic::ID IntrinsicID,FixedVectorType *FVTy,
3631ArrayRef<Constant *>Operands,constDataLayout &DL,
3632constTargetLibraryInfo *TLI,constCallBase *Call) {
3633SmallVector<Constant *, 4>Result(FVTy->getNumElements());
3634SmallVector<Constant *, 4> Lane(Operands.size());
3635Type *Ty = FVTy->getElementType();
3636
3637switch (IntrinsicID) {
3638case Intrinsic::masked_load: {
3639auto *SrcPtr =Operands[0];
3640auto *Mask =Operands[2];
3641auto *Passthru =Operands[3];
3642
3643Constant *VecData =ConstantFoldLoadFromConstPtr(SrcPtr, FVTy,DL);
3644
3645SmallVector<Constant *, 32> NewElements;
3646for (unsignedI = 0, E = FVTy->getNumElements();I != E; ++I) {
3647auto *MaskElt =Mask->getAggregateElement(I);
3648if (!MaskElt)
3649break;
3650auto *PassthruElt = Passthru->getAggregateElement(I);
3651auto *VecElt = VecData ? VecData->getAggregateElement(I) :nullptr;
3652if (isa<UndefValue>(MaskElt)) {
3653if (PassthruElt)
3654 NewElements.push_back(PassthruElt);
3655elseif (VecElt)
3656 NewElements.push_back(VecElt);
3657else
3658returnnullptr;
3659 }
3660if (MaskElt->isNullValue()) {
3661if (!PassthruElt)
3662returnnullptr;
3663 NewElements.push_back(PassthruElt);
3664 }elseif (MaskElt->isOneValue()) {
3665if (!VecElt)
3666returnnullptr;
3667 NewElements.push_back(VecElt);
3668 }else {
3669returnnullptr;
3670 }
3671 }
3672if (NewElements.size() != FVTy->getNumElements())
3673returnnullptr;
3674returnConstantVector::get(NewElements);
3675 }
3676case Intrinsic::arm_mve_vctp8:
3677case Intrinsic::arm_mve_vctp16:
3678case Intrinsic::arm_mve_vctp32:
3679case Intrinsic::arm_mve_vctp64: {
3680if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {
3681unsigned Lanes = FVTy->getNumElements();
3682uint64_t Limit =Op->getZExtValue();
3683
3684SmallVector<Constant *, 16> NCs;
3685for (unsigned i = 0; i < Lanes; i++) {
3686if (i < Limit)
3687 NCs.push_back(ConstantInt::getTrue(Ty));
3688else
3689 NCs.push_back(ConstantInt::getFalse(Ty));
3690 }
3691returnConstantVector::get(NCs);
3692 }
3693returnnullptr;
3694 }
3695case Intrinsic::get_active_lane_mask: {
3696auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);
3697auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);
3698if (Op0 && Op1) {
3699unsigned Lanes = FVTy->getNumElements();
3700uint64_tBase = Op0->getZExtValue();
3701uint64_t Limit = Op1->getZExtValue();
3702
3703SmallVector<Constant *, 16> NCs;
3704for (unsigned i = 0; i < Lanes; i++) {
3705if (Base + i < Limit)
3706 NCs.push_back(ConstantInt::getTrue(Ty));
3707else
3708 NCs.push_back(ConstantInt::getFalse(Ty));
3709 }
3710returnConstantVector::get(NCs);
3711 }
3712returnnullptr;
3713 }
3714default:
3715break;
3716 }
3717
3718for (unsignedI = 0, E = FVTy->getNumElements();I != E; ++I) {
3719// Gather a column of constants.
3720for (unsigned J = 0, JE =Operands.size(); J != JE; ++J) {
3721// Some intrinsics use a scalar type for certain arguments.
3722if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, J,/*TTI=*/nullptr)) {
3723 Lane[J] =Operands[J];
3724continue;
3725 }
3726
3727Constant *Agg =Operands[J]->getAggregateElement(I);
3728if (!Agg)
3729returnnullptr;
3730
3731 Lane[J] = Agg;
3732 }
3733
3734// Use the regular scalar folding to simplify this column.
3735Constant *Folded =
3736 ConstantFoldScalarCall(Name, IntrinsicID, Ty, Lane, TLI, Call);
3737if (!Folded)
3738returnnullptr;
3739Result[I] = Folded;
3740 }
3741
3742returnConstantVector::get(Result);
3743}
3744
3745staticConstant *ConstantFoldScalableVectorCall(
3746StringRefName,Intrinsic::ID IntrinsicID,ScalableVectorType *SVTy,
3747ArrayRef<Constant *>Operands,constDataLayout &DL,
3748constTargetLibraryInfo *TLI,constCallBase *Call) {
3749switch (IntrinsicID) {
3750case Intrinsic::aarch64_sve_convert_from_svbool: {
3751auto *Src = dyn_cast<Constant>(Operands[0]);
3752if (!Src || !Src->isNullValue())
3753break;
3754
3755returnConstantInt::getFalse(SVTy);
3756 }
3757default:
3758break;
3759 }
3760returnnullptr;
3761}
3762
3763static std::pair<Constant *, Constant *>
3764ConstantFoldScalarFrexpCall(Constant *Op,Type *IntTy) {
3765if (isa<PoisonValue>(Op))
3766return {Op,PoisonValue::get(IntTy)};
3767
3768auto *ConstFP = dyn_cast<ConstantFP>(Op);
3769if (!ConstFP)
3770return {};
3771
3772constAPFloat &U = ConstFP->getValueAPF();
3773int FrexpExp;
3774APFloat FrexpMant =frexp(U, FrexpExp, APFloat::rmNearestTiesToEven);
3775Constant *Result0 = ConstantFP::get(ConstFP->getType(), FrexpMant);
3776
3777// The exponent is an "unspecified value" for inf/nan. We use zero to avoid
3778// using undef.
3779Constant *Result1 = FrexpMant.isFinite()
3780 ?ConstantInt::getSigned(IntTy, FrexpExp)
3781 :ConstantInt::getNullValue(IntTy);
3782return {Result0, Result1};
3783}
3784
3785/// Handle intrinsics that return tuples, which may be tuples of vectors.
3786staticConstant *
3787ConstantFoldStructCall(StringRefName,Intrinsic::ID IntrinsicID,
3788StructType *StTy,ArrayRef<Constant *>Operands,
3789constDataLayout &DL,constTargetLibraryInfo *TLI,
3790constCallBase *Call) {
3791
3792switch (IntrinsicID) {
3793case Intrinsic::frexp: {
3794Type *Ty0 = StTy->getContainedType(0);
3795Type *Ty1 = StTy->getContainedType(1)->getScalarType();
3796
3797if (auto *FVTy0 = dyn_cast<FixedVectorType>(Ty0)) {
3798SmallVector<Constant *, 4> Results0(FVTy0->getNumElements());
3799SmallVector<Constant *, 4> Results1(FVTy0->getNumElements());
3800
3801for (unsignedI = 0, E = FVTy0->getNumElements();I != E; ++I) {
3802Constant *Lane =Operands[0]->getAggregateElement(I);
3803 std::tie(Results0[I], Results1[I]) =
3804 ConstantFoldScalarFrexpCall(Lane, Ty1);
3805if (!Results0[I])
3806returnnullptr;
3807 }
3808
3809returnConstantStruct::get(StTy,ConstantVector::get(Results0),
3810ConstantVector::get(Results1));
3811 }
3812
3813auto [Result0, Result1] = ConstantFoldScalarFrexpCall(Operands[0], Ty1);
3814if (!Result0)
3815returnnullptr;
3816returnConstantStruct::get(StTy, Result0, Result1);
3817 }
3818case Intrinsic::sincos: {
3819Type *Ty = StTy->getContainedType(0);
3820Type *TyScalar = Ty->getScalarType();
3821
3822auto ConstantFoldScalarSincosCall =
3823 [&](Constant *Op) -> std::pair<Constant *, Constant *> {
3824Constant *SinResult =
3825 ConstantFoldScalarCall(Name, Intrinsic::sin, TyScalar,Op, TLI, Call);
3826Constant *CosResult =
3827 ConstantFoldScalarCall(Name, Intrinsic::cos, TyScalar,Op, TLI, Call);
3828return std::make_pair(SinResult, CosResult);
3829 };
3830
3831if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
3832SmallVector<Constant *> SinResults(FVTy->getNumElements());
3833SmallVector<Constant *> CosResults(FVTy->getNumElements());
3834
3835for (unsignedI = 0, E = FVTy->getNumElements();I != E; ++I) {
3836Constant *Lane =Operands[0]->getAggregateElement(I);
3837 std::tie(SinResults[I], CosResults[I]) =
3838 ConstantFoldScalarSincosCall(Lane);
3839if (!SinResults[I] || !CosResults[I])
3840returnnullptr;
3841 }
3842
3843returnConstantStruct::get(StTy,ConstantVector::get(SinResults),
3844ConstantVector::get(CosResults));
3845 }
3846
3847auto [SinResult, CosResult] = ConstantFoldScalarSincosCall(Operands[0]);
3848if (!SinResult || !CosResult)
3849returnnullptr;
3850returnConstantStruct::get(StTy, SinResult, CosResult);
3851 }
3852default:
3853// TODO: Constant folding of vector intrinsics that fall through here does
3854// not work (e.g. overflow intrinsics)
3855return ConstantFoldScalarCall(Name, IntrinsicID, StTy,Operands, TLI, Call);
3856 }
3857
3858returnnullptr;
3859}
3860
3861}// end anonymous namespace
3862
3863Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::IDID,Constant *LHS,
3864Constant *RHS,Type *Ty,
3865Instruction *FMFSource) {
3866return ConstantFoldIntrinsicCall2(ID, Ty, {LHS,RHS},
3867 dyn_cast_if_present<CallBase>(FMFSource));
3868}
3869
3870Constant *llvm::ConstantFoldCall(constCallBase *Call,Function *F,
3871ArrayRef<Constant *>Operands,
3872constTargetLibraryInfo *TLI,
3873bool AllowNonDeterministic) {
3874if (Call->isNoBuiltin())
3875returnnullptr;
3876if (!F->hasName())
3877returnnullptr;
3878
3879// If this is not an intrinsic and not recognized as a library call, bail out.
3880Intrinsic::ID IID =F->getIntrinsicID();
3881if (IID ==Intrinsic::not_intrinsic) {
3882if (!TLI)
3883returnnullptr;
3884LibFunc LibF;
3885if (!TLI->getLibFunc(*F, LibF))
3886returnnullptr;
3887 }
3888
3889// Conservatively assume that floating-point libcalls may be
3890// non-deterministic.
3891Type *Ty =F->getReturnType();
3892if (!AllowNonDeterministic && Ty->isFPOrFPVectorTy())
3893returnnullptr;
3894
3895StringRefName =F->getName();
3896if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))
3897return ConstantFoldFixedVectorCall(
3898Name, IID, FVTy,Operands,F->getDataLayout(), TLI, Call);
3899
3900if (auto *SVTy = dyn_cast<ScalableVectorType>(Ty))
3901return ConstantFoldScalableVectorCall(
3902Name, IID, SVTy,Operands,F->getDataLayout(), TLI, Call);
3903
3904if (auto *StTy = dyn_cast<StructType>(Ty))
3905return ConstantFoldStructCall(Name, IID, StTy,Operands,
3906F->getDataLayout(), TLI, Call);
3907
3908// TODO: If this is a library function, we already discovered that above,
3909// so we should pass the LibFunc, not the name (and it might be better
3910// still to separate intrinsic handling from libcalls).
3911return ConstantFoldScalarCall(Name, IID, Ty,Operands, TLI, Call);
3912}
3913
3914boolllvm::isMathLibCallNoop(constCallBase *Call,
3915constTargetLibraryInfo *TLI) {
3916// FIXME: Refactor this code; this duplicates logic in LibCallsShrinkWrap
3917// (and to some extent ConstantFoldScalarCall).
3918if (Call->isNoBuiltin() || Call->isStrictFP())
3919returnfalse;
3920Function *F = Call->getCalledFunction();
3921if (!F)
3922returnfalse;
3923
3924LibFunc Func;
3925if (!TLI || !TLI->getLibFunc(*F, Func))
3926returnfalse;
3927
3928if (Call->arg_size() == 1) {
3929if (ConstantFP *OpC = dyn_cast<ConstantFP>(Call->getArgOperand(0))) {
3930constAPFloat &Op = OpC->getValueAPF();
3931switch (Func) {
3932case LibFunc_logl:
3933case LibFunc_log:
3934case LibFunc_logf:
3935case LibFunc_log2l:
3936case LibFunc_log2:
3937case LibFunc_log2f:
3938case LibFunc_log10l:
3939case LibFunc_log10:
3940case LibFunc_log10f:
3941returnOp.isNaN() || (!Op.isZero() && !Op.isNegative());
3942
3943case LibFunc_ilogb:
3944return !Op.isNaN() && !Op.isZero() && !Op.isInfinity();
3945
3946case LibFunc_expl:
3947case LibFunc_exp:
3948case LibFunc_expf:
3949// FIXME: These boundaries are slightly conservative.
3950if (OpC->getType()->isDoubleTy())
3951return !(Op <APFloat(-745.0) ||Op >APFloat(709.0));
3952if (OpC->getType()->isFloatTy())
3953return !(Op <APFloat(-103.0f) ||Op >APFloat(88.0f));
3954break;
3955
3956case LibFunc_exp2l:
3957case LibFunc_exp2:
3958case LibFunc_exp2f:
3959// FIXME: These boundaries are slightly conservative.
3960if (OpC->getType()->isDoubleTy())
3961return !(Op <APFloat(-1074.0) ||Op >APFloat(1023.0));
3962if (OpC->getType()->isFloatTy())
3963return !(Op <APFloat(-149.0f) ||Op >APFloat(127.0f));
3964break;
3965
3966case LibFunc_sinl:
3967case LibFunc_sin:
3968case LibFunc_sinf:
3969case LibFunc_cosl:
3970case LibFunc_cos:
3971case LibFunc_cosf:
3972return !Op.isInfinity();
3973
3974case LibFunc_tanl:
3975case LibFunc_tan:
3976case LibFunc_tanf: {
3977// FIXME: Stop using the host math library.
3978// FIXME: The computation isn't done in the right precision.
3979Type *Ty = OpC->getType();
3980if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy())
3981return ConstantFoldFP(tan, OpC->getValueAPF(), Ty) !=nullptr;
3982break;
3983 }
3984
3985case LibFunc_atan:
3986case LibFunc_atanf:
3987case LibFunc_atanl:
3988// Per POSIX, this MAY fail if Op is denormal. We choose not failing.
3989returntrue;
3990
3991case LibFunc_asinl:
3992case LibFunc_asin:
3993case LibFunc_asinf:
3994case LibFunc_acosl:
3995case LibFunc_acos:
3996case LibFunc_acosf:
3997return !(Op <APFloat::getOne(Op.getSemantics(),true) ||
3998Op >APFloat::getOne(Op.getSemantics()));
3999
4000case LibFunc_sinh:
4001case LibFunc_cosh:
4002case LibFunc_sinhf:
4003case LibFunc_coshf:
4004case LibFunc_sinhl:
4005case LibFunc_coshl:
4006// FIXME: These boundaries are slightly conservative.
4007if (OpC->getType()->isDoubleTy())
4008return !(Op <APFloat(-710.0) ||Op >APFloat(710.0));
4009if (OpC->getType()->isFloatTy())
4010return !(Op <APFloat(-89.0f) ||Op >APFloat(89.0f));
4011break;
4012
4013case LibFunc_sqrtl:
4014case LibFunc_sqrt:
4015case LibFunc_sqrtf:
4016returnOp.isNaN() ||Op.isZero() || !Op.isNegative();
4017
4018// FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p,
4019// maybe others?
4020default:
4021break;
4022 }
4023 }
4024 }
4025
4026if (Call->arg_size() == 2) {
4027ConstantFP *Op0C = dyn_cast<ConstantFP>(Call->getArgOperand(0));
4028ConstantFP *Op1C = dyn_cast<ConstantFP>(Call->getArgOperand(1));
4029if (Op0C && Op1C) {
4030constAPFloat &Op0 = Op0C->getValueAPF();
4031constAPFloat &Op1 = Op1C->getValueAPF();
4032
4033switch (Func) {
4034case LibFunc_powl:
4035case LibFunc_pow:
4036case LibFunc_powf: {
4037// FIXME: Stop using the host math library.
4038// FIXME: The computation isn't done in the right precision.
4039Type *Ty = Op0C->getType();
4040if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy()) {
4041if (Ty == Op1C->getType())
4042return ConstantFoldBinaryFP(pow, Op0, Op1, Ty) !=nullptr;
4043 }
4044break;
4045 }
4046
4047case LibFunc_fmodl:
4048case LibFunc_fmod:
4049case LibFunc_fmodf:
4050case LibFunc_remainderl:
4051case LibFunc_remainder:
4052case LibFunc_remainderf:
4053return Op0.isNaN() || Op1.isNaN() ||
4054 (!Op0.isInfinity() && !Op1.isZero());
4055
4056case LibFunc_atan2:
4057case LibFunc_atan2f:
4058case LibFunc_atan2l:
4059// Although IEEE-754 says atan2(+/-0.0, +/-0.0) are well-defined, and
4060// GLIBC and MSVC do not appear to raise an error on those, we
4061// cannot rely on that behavior. POSIX and C11 say that a domain error
4062// may occur, so allow for that possibility.
4063return !Op0.isZero() || !Op1.isZero();
4064
4065default:
4066break;
4067 }
4068 }
4069 }
4070
4071returnfalse;
4072}
4073
4074void TargetFolder::anchor() {}
SelectTypeKind::FP
@ FP
S1
static const LLT S1
Definition:AMDGPULegalizerInfo.cpp:282
APFloat.h
This file declares a class to represent arbitrary precision floating point values and provide a varie...
APInt.h
This file implements a class to represent arbitrary precision integral constant values and operations...
APSInt.h
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
ArrayRef.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Casting.h
FoldBitCast
static Constant * FoldBitCast(Constant *V, Type *DestTy)
Definition:ConstantFold.cpp:69
ConstantFold.h
flushDenormalConstant
static ConstantFP * flushDenormalConstant(Type *Ty, const APFloat &APF, DenormalMode::DenormalModeKind Mode)
Definition:ConstantFolding.cpp:1313
getConstantAtOffset
Constant * getConstantAtOffset(Constant *Base, APInt Offset, const DataLayout &DL)
If this Offset points exactly to the start of an aggregate element, return that element,...
Definition:ConstantFolding.cpp:678
flushDenormalConstantFP
static ConstantFP * flushDenormalConstantFP(ConstantFP *CFP, const Instruction *Inst, bool IsOutput)
Definition:ConstantFolding.cpp:1342
getInstrDenormalMode
static DenormalMode getInstrDenormalMode(const Instruction *CtxI, Type *Ty)
Return the denormal mode that can be assumed when executing a floating point operation at CtxI.
Definition:ConstantFolding.cpp:1336
ConstantFolding.h
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DataLayout.h
DenseMap.h
This file defines the DenseMap class.
DerivedTypes.h
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
GlobalValue.h
GlobalVariable.h
GEP
Hexagon Common GEP
Definition:HexagonCommonGEP.cpp:170
mode
amode Optimize addressing mode
Definition:HexagonOptAddrMode.cpp:139
Constant.h
Function.h
Instruction.h
IntrinsicInst.h
Operator.h
Type.h
Value.h
InstrTypes.h
Instructions.h
Intrinsics.h
KnownBits.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
Operands
mir Rename Register Operands
Definition:MIRNamerPass.cpp:74
MathExtras.h
InRange
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
Definition:MicroMipsSizeReduction.cpp:327
Signed
@ Signed
Definition:NVPTXISelLowering.cpp:4789
NVVMIntrinsicUtils.h
This file contains the definitions of the enumerations and flags associated with NVVM Intrinsics,...
Cond
const SmallVectorImpl< MachineOperand > & Cond
Definition:RISCVRedundantCopyElimination.cpp:75
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
STLExtras.h
This file contains some templates that are useful if you are working with the STL at all.
SmallVector.h
This file defines the SmallVector class.
StringRef.h
getType
static SymbolRef::Type getType(const Symbol *Sym)
Definition:TapiFile.cpp:39
TargetFolder.h
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
Int
@ Int
Definition:TargetLibraryInfo.cpp:65
TargetLibraryInfo.h
ValueTracking.h
VectorUtils.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
llvm::APFloat
Definition:APFloat.h:904
llvm::APFloat::getQNaN
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
Definition:APFloat.h:1122
llvm::APFloat::divide
opStatus divide(const APFloat &RHS, roundingMode RM)
Definition:APFloat.h:1210
llvm::APFloat::copySign
void copySign(const APFloat &RHS)
Definition:APFloat.h:1304
llvm::APFloat::convert
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition:APFloat.cpp:5463
llvm::APFloat::subtract
opStatus subtract(const APFloat &RHS, roundingMode RM)
Definition:APFloat.h:1192
llvm::APFloat::isNegative
bool isNegative() const
Definition:APFloat.h:1445
llvm::APFloat::convertToDouble
double convertToDouble() const
Converts this APFloat to host double value.
Definition:APFloat.cpp:5525
llvm::APFloat::isPosInfinity
bool isPosInfinity() const
Definition:APFloat.h:1458
llvm::APFloat::isNormal
bool isNormal() const
Definition:APFloat.h:1449
llvm::APFloat::isDenormal
bool isDenormal() const
Definition:APFloat.h:1446
llvm::APFloat::add
opStatus add(const APFloat &RHS, roundingMode RM)
Definition:APFloat.h:1183
llvm::APFloat::getSemantics
const fltSemantics & getSemantics() const
Definition:APFloat.h:1453
llvm::APFloat::isNonZero
bool isNonZero() const
Definition:APFloat.h:1454
llvm::APFloat::isFinite
bool isFinite() const
Definition:APFloat.h:1450
llvm::APFloat::isNaN
bool isNaN() const
Definition:APFloat.h:1443
llvm::APFloat::getOne
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
Definition:APFloat.h:1090
llvm::APFloat::multiply
opStatus multiply(const APFloat &RHS, roundingMode RM)
Definition:APFloat.h:1201
llvm::APFloat::convertToFloat
float convertToFloat() const
Converts this APFloat to host float value.
Definition:APFloat.cpp:5553
llvm::APFloat::isSignaling
bool isSignaling() const
Definition:APFloat.h:1447
llvm::APFloat::fusedMultiplyAdd
opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend, roundingMode RM)
Definition:APFloat.h:1237
llvm::APFloat::isZero
bool isZero() const
Definition:APFloat.h:1441
llvm::APFloat::bitcastToAPInt
APInt bitcastToAPInt() const
Definition:APFloat.h:1351
llvm::APFloat::convertToInteger
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Definition:APFloat.h:1326
llvm::APFloat::mod
opStatus mod(const APFloat &RHS)
Definition:APFloat.h:1228
llvm::APFloat::isNegInfinity
bool isNegInfinity() const
Definition:APFloat.h:1459
llvm::APFloat::changeSign
void changeSign()
Definition:APFloat.h:1299
llvm::APFloat::getZero
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Definition:APFloat.h:1081
llvm::APFloat::isInfinity
bool isInfinity() const
Definition:APFloat.h:1442
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::APInt::umul_ov
APInt umul_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1945
llvm::APInt::usub_sat
APInt usub_sat(const APInt &RHS) const
Definition:APInt.cpp:2029
llvm::APInt::isMinSignedValue
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Definition:APInt.h:423
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition:APInt.h:1520
llvm::APInt::extractBitsAsZExtValue
uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const
Definition:APInt.cpp:493
llvm::APInt::zextOrTrunc
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
Definition:APInt.cpp:1007
llvm::APInt::trunc
APInt trunc(unsigned width) const
Truncate to new width.
Definition:APInt.cpp:910
llvm::APInt::abs
APInt abs() const
Get the absolute value.
Definition:APInt.h:1773
llvm::APInt::sadd_sat
APInt sadd_sat(const APInt &RHS) const
Definition:APInt.cpp:2000
llvm::APInt::sgt
bool sgt(const APInt &RHS) const
Signed greater than comparison.
Definition:APInt.h:1201
llvm::APInt::usub_ov
APInt usub_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1922
llvm::APInt::ugt
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
Definition:APInt.h:1182
llvm::APInt::isZero
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
Definition:APInt.h:380
llvm::APInt::urem
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
Definition:APInt.cpp:1640
llvm::APInt::getBitWidth
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition:APInt.h:1468
llvm::APInt::ult
bool ult(const APInt &RHS) const
Unsigned less than comparison.
Definition:APInt.h:1111
llvm::APInt::getSignedMaxValue
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition:APInt.h:209
llvm::APInt::sadd_ov
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1902
llvm::APInt::uadd_ov
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1909
llvm::APInt::countr_zero
unsigned countr_zero() const
Count the number of trailing zero bits.
Definition:APInt.h:1618
llvm::APInt::countl_zero
unsigned countl_zero() const
The APInt version of std::countl_zero.
Definition:APInt.h:1577
llvm::APInt::getSignedMinValue
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition:APInt.h:219
llvm::APInt::sextOrTrunc
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
Definition:APInt.cpp:1015
llvm::APInt::uadd_sat
APInt uadd_sat(const APInt &RHS) const
Definition:APInt.cpp:2010
llvm::APInt::smul_ov
APInt smul_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1934
llvm::APInt::sext
APInt sext(unsigned width) const
Sign extend to a new width.
Definition:APInt.cpp:959
llvm::APInt::shl
APInt shl(unsigned shiftAmt) const
Left-shift function.
Definition:APInt.h:873
llvm::APInt::slt
bool slt(const APInt &RHS) const
Signed less than comparison.
Definition:APInt.h:1130
llvm::APInt::extractBits
APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
Definition:APInt.cpp:455
llvm::APInt::ssub_ov
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
Definition:APInt.cpp:1915
llvm::APInt::isOne
bool isOne() const
Determine if this is a value of 1.
Definition:APInt.h:389
llvm::APInt::lshr
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition:APInt.h:851
llvm::APInt::ssub_sat
APInt ssub_sat(const APInt &RHS) const
Definition:APInt.cpp:2019
llvm::APSInt
An arbitrary precision integer that knows its signedness.
Definition:APSInt.h:23
llvm::Any
Definition:Any.h:28
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::back
const T & back() const
back - Get the last element.
Definition:ArrayRef.h:177
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::ArrayRef::data
const T * data() const
Definition:ArrayRef.h:165
llvm::ArrayRef::slice
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition:ArrayRef.h:198
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition:InstrTypes.h:1112
llvm::CastInst::getCastOpcode
static Instruction::CastOps getCastOpcode(const Value *Val, bool SrcIsSigned, Type *Ty, bool DstIsSigned)
Returns the opcode necessary to cast Val into Ty using usual casting rules.
Definition:Instructions.cpp:3144
llvm::CastInst::castIsValid
static bool castIsValid(Instruction::CastOps op, Type *SrcTy, Type *DstTy)
This method can be used to determine if a cast from SrcTy to DstTy using Opcode op is valid or not.
Definition:Instructions.cpp:3241
llvm::CmpInst::Predicate
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition:InstrTypes.h:673
llvm::CmpInst::isFPPredicate
bool isFPPredicate() const
Definition:InstrTypes.h:780
llvm::ConstantDataArray::get
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
Definition:Constants.h:709
llvm::ConstantExpr::getIntToPtr
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition:Constants.cpp:2307
llvm::ConstantExpr::getExtractElement
static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
Definition:Constants.cpp:2555
llvm::ConstantExpr::isDesirableCastOp
static bool isDesirableCastOp(unsigned Opcode)
Whether creating a constant expression for this cast is desirable.
Definition:Constants.cpp:2436
llvm::ConstantExpr::getCast
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
Definition:Constants.cpp:2222
llvm::ConstantExpr::getSub
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Definition:Constants.cpp:2645
llvm::ConstantExpr::getInsertElement
static Constant * getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
Definition:Constants.cpp:2577
llvm::ConstantExpr::getPtrToInt
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition:Constants.cpp:2293
llvm::ConstantExpr::getShuffleVector
static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
Definition:Constants.cpp:2600
llvm::ConstantExpr::isSupportedGetElementPtr
static bool isSupportedGetElementPtr(const Type *SrcElemTy)
Whether creating a constant expression for this getelementptr type is supported.
Definition:Constants.h:1379
llvm::ConstantExpr::get
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible.
Definition:Constants.cpp:2340
llvm::ConstantExpr::isDesirableBinOp
static bool isDesirableBinOp(unsigned Opcode)
Whether creating a constant expression for this binary operator is desirable.
Definition:Constants.cpp:2382
llvm::ConstantExpr::getGetElementPtr
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition:Constants.h:1267
llvm::ConstantExpr::getBitCast
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition:Constants.cpp:2321
llvm::ConstantFP
ConstantFP - Floating Point Values [float, double].
Definition:Constants.h:271
llvm::ConstantFP::getValueAPF
const APFloat & getValueAPF() const
Definition:Constants.h:314
llvm::ConstantFP::getZero
static Constant * getZero(Type *Ty, bool Negative=false)
Definition:Constants.cpp:1057
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::ConstantInt::getTrue
static ConstantInt * getTrue(LLVMContext &Context)
Definition:Constants.cpp:866
llvm::ConstantInt::getSigned
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition:Constants.h:126
llvm::ConstantInt::getFalse
static ConstantInt * getFalse(LLVMContext &Context)
Definition:Constants.cpp:873
llvm::ConstantInt::getBool
static ConstantInt * getBool(LLVMContext &Context, bool V)
Definition:Constants.cpp:880
llvm::ConstantStruct::get
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition:Constants.cpp:1378
llvm::ConstantVector::getSplat
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
Definition:Constants.cpp:1472
llvm::ConstantVector::get
static Constant * get(ArrayRef< Constant * > V)
Definition:Constants.cpp:1421
llvm::Constant
This is an important base class in LLVM.
Definition:Constant.h:42
llvm::Constant::getSplatValue
Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
Definition:Constants.cpp:1708
llvm::Constant::getAllOnesValue
static Constant * getAllOnesValue(Type *Ty)
Definition:Constants.cpp:420
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition:Constants.cpp:373
llvm::Constant::getAggregateElement
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Definition:Constants.cpp:435
llvm::Constant::isNullValue
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition:Constants.cpp:90
llvm::ConstrainedFPCmpIntrinsic
Constrained floating point compare intrinsics.
Definition:IntrinsicInst.h:738
llvm::ConstrainedFPIntrinsic
This is the common base class for constrained floating point intrinsics.
Definition:IntrinsicInst.h:723
llvm::ConstrainedFPIntrinsic::getExceptionBehavior
std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
Definition:IntrinsicInst.cpp:288
llvm::ConstrainedFPIntrinsic::getRoundingMode
std::optional< RoundingMode > getRoundingMode() const
Definition:IntrinsicInst.cpp:276
llvm::DSOLocalEquivalent
Wrapper for a function that represents a value that functionally represents the original function.
Definition:Constants.h:941
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition:DataLayout.h:63
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition:DenseMap.h:156
llvm::DenseMapBase::end
iterator end()
Definition:DenseMap.h:84
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition:DenseMap.h:211
llvm::FCmpInst::compare
static bool compare(const APFloat &LHS, const APFloat &RHS, FCmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Definition:Instructions.cpp:3774
llvm::FMFSource
This provides a helper for copying FMF from an instruction or setting specified flags.
Definition:IRBuilder.h:92
llvm::FixedVectorType
Class to represent fixed width SIMD vectors.
Definition:DerivedTypes.h:563
llvm::FixedVectorType::getNumElements
unsigned getNumElements() const
Definition:DerivedTypes.h:606
llvm::FixedVectorType::get
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition:Type.cpp:791
llvm::Function
Definition:Function.h:63
llvm::Function::getDenormalMode
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
Definition:Function.cpp:807
llvm::GEPNoWrapFlags
Represents flags for the getelementptr instruction/expression.
Definition:GEPNoWrapFlags.h:26
llvm::GEPNoWrapFlags::inBounds
static GEPNoWrapFlags inBounds()
Definition:GEPNoWrapFlags.h:50
llvm::GEPNoWrapFlags::withoutNoUnsignedSignedWrap
GEPNoWrapFlags withoutNoUnsignedSignedWrap() const
Definition:GEPNoWrapFlags.h:70
llvm::GEPNoWrapFlags::noUnsignedWrap
static GEPNoWrapFlags noUnsignedWrap()
Definition:GEPNoWrapFlags.h:56
llvm::GEPNoWrapFlags::hasNoUnsignedSignedWrap
bool hasNoUnsignedSignedWrap() const
Definition:GEPNoWrapFlags.h:64
llvm::GEPNoWrapFlags::isInBounds
bool isInBounds() const
Definition:GEPNoWrapFlags.h:63
llvm::GEPOperator
Definition:Operator.h:425
llvm::GetElementPtrInst::getIndexedType
static Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
Definition:Instructions.cpp:1514
llvm::GlobalValue
Definition:GlobalValue.h:48
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition:GlobalValue.h:295
llvm::GlobalValue::getDataLayout
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition:Globals.cpp:130
llvm::GlobalVariable
Definition:GlobalVariable.h:39
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition:GlobalVariable.h:150
llvm::GlobalVariable::isConstant
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
Definition:GlobalVariable.h:173
llvm::GlobalVariable::hasDefinitiveInitializer
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
Definition:GlobalVariable.h:124
llvm::ICmpInst::compare
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Definition:Instructions.cpp:3745
llvm::ICmpInst::getSignedPredicate
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
Definition:Instructions.h:1238
llvm::Init
Definition:Record.h:285
llvm::Instruction
Definition:Instruction.h:68
llvm::Instruction::isCast
bool isCast() const
Definition:Instruction.h:300
llvm::Instruction::isBinaryOp
bool isBinaryOp() const
Definition:Instruction.h:296
llvm::Instruction::getFunction
const Function * getFunction() const
Return the function this instruction belongs to.
Definition:Instruction.cpp:72
llvm::Instruction::isUnaryOp
bool isUnaryOp() const
Definition:Instruction.h:295
llvm::Instruction::CastOps
CastOps
Definition:Instruction.h:1003
llvm::IntegerType::get
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition:Type.cpp:311
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::MinMaxIntrinsic::getSaturationPoint
static APInt getSaturationPoint(Intrinsic::ID ID, unsigned numBits)
Min/max intrinsics are monotonic, they operate on a fixed-bitwidth values, so there is a certain thre...
Definition:IntrinsicInst.h:813
llvm::MinMaxIntrinsic::getPredicate
ICmpInst::Predicate getPredicate() const
Returns the comparison predicate underlying the intrinsic.
Definition:IntrinsicInst.h:798
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition:ArrayRef.h:310
llvm::PoisonValue::get
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition:Constants.cpp:1878
llvm::ScalableVectorType
Class to represent scalable SIMD vectors.
Definition:DerivedTypes.h:610
llvm::SmallDenseMap
Definition:DenseMap.h:883
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::data
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition:SmallVector.h:286
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StructLayout
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
Definition:DataLayout.h:567
llvm::StructLayout::getElementContainingOffset
unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
Definition:DataLayout.cpp:92
llvm::StructLayout::getElementOffset
TypeSize getElementOffset(unsigned Idx) const
Definition:DataLayout.h:596
llvm::StructType
Class to represent struct types.
Definition:DerivedTypes.h:218
llvm::TargetLibraryInfo
Provides information about what library functions are available for the current target.
Definition:TargetLibraryInfo.h:280
llvm::TargetLibraryInfo::has
bool has(LibFunc F) const
Tests whether a library function is available.
Definition:TargetLibraryInfo.h:387
llvm::TargetLibraryInfo::getLibFunc
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Definition:TargetLibraryInfo.h:345
llvm::TypeSize
Definition:TypeSize.h:334
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::getIntegerBitWidth
unsigned getIntegerBitWidth() const
llvm::Type::getStructElementType
Type * getStructElementType(unsigned N) const
llvm::Type::getFltSemantics
const fltSemantics & getFltSemantics() const
llvm::Type::isVectorTy
bool isVectorTy() const
True if this is an instance of VectorType.
Definition:Type.h:270
llvm::Type::isIntOrIntVectorTy
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition:Type.h:243
llvm::Type::isPointerTy
bool isPointerTy() const
True if this is an instance of PointerType.
Definition:Type.h:264
llvm::Type::getInt1Ty
static IntegerType * getInt1Ty(LLVMContext &C)
llvm::Type::isFloatTy
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition:Type.h:153
llvm::Type::isBFloatTy
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
Definition:Type.h:145
llvm::Type::getPointerAddressSpace
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
llvm::Type::HalfTyID
@ HalfTyID
16-bit floating point type
Definition:Type.h:56
llvm::Type::FloatTyID
@ FloatTyID
32-bit floating point type
Definition:Type.h:58
llvm::Type::DoubleTyID
@ DoubleTyID
64-bit floating point type
Definition:Type.h:59
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
llvm::Type::isFP128Ty
bool isFP128Ty() const
Return true if this is 'fp128'.
Definition:Type.h:162
llvm::Type::getScalarSizeInBits
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
llvm::Type::isStructTy
bool isStructTy() const
True if this is an instance of StructType.
Definition:Type.h:258
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition:Type.h:310
llvm::Type::getInt16Ty
static IntegerType * getInt16Ty(LLVMContext &C)
llvm::Type::isAggregateType
bool isAggregateType() const
Return true if the type is an aggregate type.
Definition:Type.h:303
llvm::Type::isHalfTy
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
Definition:Type.h:142
llvm::Type::getContext
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition:Type.h:128
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
llvm::Type::isDoubleTy
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition:Type.h:156
llvm::Type::isFloatingPointTy
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition:Type.h:184
llvm::Type::isPtrOrPtrVectorTy
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition:Type.h:267
llvm::Type::isX86_AMXTy
bool isX86_AMXTy() const
Return true if this is X86 AMX.
Definition:Type.h:200
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
llvm::Type::isIntegerTy
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition:Type.h:237
llvm::Type::getTypeID
TypeID getTypeID() const
Return the type id for the type.
Definition:Type.h:136
llvm::Type::isFPOrFPVectorTy
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition:Type.h:225
llvm::Type::getPrimitiveSizeInBits
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
llvm::Type::getContainedType
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
Definition:Type.h:384
llvm::Type::isIEEELikeFPTy
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Definition:Type.h:170
llvm::Type::getScalarType
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition:Type.h:355
llvm::UndefValue::get
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Definition:Constants.cpp:1859
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition:Use.h:43
llvm::User::getOperand
Value * getOperand(unsigned i) const
Definition:User.h:228
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::Value::stripAndAccumulateInBoundsConstantOffsets
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
Definition:Value.h:740
llvm::Value::getContext
LLVMContext & getContext() const
All values hold a context through their type.
Definition:Value.cpp:1075
llvm::VectorType
Base class of all SIMD vector types.
Definition:DerivedTypes.h:427
llvm::VectorType::getElementCount
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Definition:DerivedTypes.h:665
llvm::VectorType::getElementType
Type * getElementType() const
Definition:DerivedTypes.h:460
llvm::details::FixedOrScalableQuantity::getFixedValue
constexpr ScalarTy getFixedValue() const
Definition:TypeSize.h:202
llvm::details::FixedOrScalableQuantity::isScalable
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition:TypeSize.h:171
llvm::ilist_detail::node_parent_access::getParent
const ParentTy * getParent() const
Definition:ilist_node.h:32
uint64_t
unsigned
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::AArch64::RM
@ RM
Definition:AArch64ISelLowering.h:542
llvm::APIntOps::smin
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
Definition:APInt.h:2217
llvm::APIntOps::smax
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
Definition:APInt.h:2222
llvm::APIntOps::umin
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
Definition:APInt.h:2227
llvm::APIntOps::umax
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
Definition:APInt.h:2232
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition:BitmaskEnum.h:125
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::Intrinsic::not_intrinsic
@ not_intrinsic
Definition:Intrinsics.h:44
llvm::M68k::MemAddrModeKind::j
@ j
llvm::M68k::MemAddrModeKind::U
@ U
llvm::M68k::MemAddrModeKind::V
@ V
llvm::MCID::Call
@ Call
Definition:MCInstrDesc.h:156
llvm::NVPTX::PTXLdStInstCode::V4
@ V4
Definition:NVPTX.h:164
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition:PPCISelLowering.h:429
llvm::RISCVFenceField::W
@ W
Definition:RISCVBaseInfo.h:374
llvm::WinEH::EncodingType::CE
@ CE
Windows NT (Windows on ARM)
llvm::codeview::CompileSym3Flags::Exp
@ Exp
llvm::codeview::EncodedFramePtrReg::BasePtr
@ BasePtr
llvm::detail::ilogb
int ilogb(const IEEEFloat &Arg)
Definition:APFloat.cpp:4771
llvm::dwarf::Index
Index
Definition:Dwarf.h:882
llvm::fp::ebStrict
@ ebStrict
This corresponds to "fpexcept.strict".
Definition:FPEnv.h:41
llvm::fp::ebIgnore
@ ebIgnore
This corresponds to "fpexcept.ignore".
Definition:FPEnv.h:39
llvm::logicalview::LVAttributeKind::Zero
@ Zero
llvm::minidump::StreamType::Unused
@ Unused
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::numbers::pi
constexpr double pi
Definition:MathExtras.h:53
llvm::nvvm::FPToIntegerIntrinsicResultIsSigned
bool FPToIntegerIntrinsicResultIsSigned(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:109
llvm::nvvm::GetFPToIntegerRoundingMode
APFloat::roundingMode GetFPToIntegerRoundingMode(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:177
llvm::nvvm::FPToIntegerIntrinsicShouldFTZ
bool FPToIntegerIntrinsicShouldFTZ(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:41
llvm::nvvm::FMinFMaxIsXorSignAbs
bool FMinFMaxIsXorSignAbs(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:307
llvm::nvvm::FMinFMaxShouldFTZ
bool FMinFMaxShouldFTZ(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:247
llvm::nvvm::FMinFMaxPropagatesNaNs
bool FMinFMaxPropagatesNaNs(Intrinsic::ID IntrinsicID)
Definition:NVVMIntrinsicUtils.h:277
llvm::pdb::PDB_SymType::Caller
@ Caller
llvm::pdb::DbgHeaderType::Max
@ Max
llvm::rdf::Func
NodeAddr< FuncNode * > Func
Definition:RDFGraph.h:393
llvm::sampleprof::Base
@ Base
Definition:Discriminator.h:58
llvm::sys::fs::status
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition:STLExtras.h:329
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::ConstantFoldBinaryIntrinsic
Constant * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty, Instruction *FMFSource)
Definition:ConstantFolding.cpp:3863
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1739
llvm::ConstantFoldLoadThroughBitcast
Constant * ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, const DataLayout &DL)
ConstantFoldLoadThroughBitcast - try to cast constant to destination type returning null if unsuccess...
Definition:ConstantFolding.cpp:352
llvm::log2
static double log2(double V)
Definition:AMDGPULibCalls.cpp:892
llvm::ConstantFoldSelectInstruction
Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)
Attempt to constant fold a select instruction with the specified operands.
Definition:ConstantFold.cpp:261
llvm::ConstantFoldFPInstOperands
Constant * ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL, const Instruction *I, bool AllowNonDeterministic=true)
Attempt to constant fold a floating point binary operation with the specified operands,...
Definition:ConstantFolding.cpp:1419
llvm::canConstantFoldCallTo
bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
Definition:ConstantFolding.cpp:1565
llvm::getPointerAddressSpace
unsigned getPointerAddressSpace(const Type *T)
Definition:SPIRVUtils.h:262
llvm::LibFunc
LibFunc
Definition:TargetLibraryInfo.h:68
llvm::NotLibFunc
@ NotLibFunc
Definition:TargetLibraryInfo.h:73
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition:APFloat.h:1534
llvm::ConstantFoldCompareInstruction
Constant * ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, Constant *C1, Constant *C2)
Definition:ConstantFold.cpp:1101
llvm::ConstantFoldUnaryInstruction
Constant * ConstantFoldUnaryInstruction(unsigned Opcode, Constant *V)
Definition:ConstantFold.cpp:546
llvm::IsConstantOffsetFromGlobal
bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset, const DataLayout &DL, DSOLocalEquivalent **DSOEquiv=nullptr)
If this constant is a constant offset from a global, return the global and the constant.
Definition:ConstantFolding.cpp:299
llvm::isMathLibCallNoop
bool isMathLibCallNoop(const CallBase *Call, const TargetLibraryInfo *TLI)
Check whether the given call has no side-effects.
Definition:ConstantFolding.cpp:3914
llvm::ReadByteArrayFromGlobal
Constant * ReadByteArrayFromGlobal(const GlobalVariable *GV, uint64_t Offset)
Definition:ConstantFolding.cpp:648
llvm::maximum
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
Definition:APFloat.h:1604
llvm::getUnderlyingObject
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
Definition:ValueTracking.cpp:6768
llvm::ConstantFoldCompareInstOperands
Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
Definition:ConstantFolding.cpp:1186
llvm::ConstantFoldCall
Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
Definition:ConstantFolding.cpp:3870
llvm::frexp
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
Definition:APFloat.h:1526
llvm::ConstantFoldExtractValueInstruction
Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)
Attempt to constant fold an extractvalue instruction with the specified operands and indices.
Definition:ConstantFold.cpp:505
llvm::ConstantFoldConstant
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
Definition:ConstantFolding.cpp:1171
llvm::maxnum
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 maximumNumber semantics.
Definition:APFloat.h:1563
llvm::ConstantFoldLoadFromUniformValue
Constant * ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty, const DataLayout &DL)
If C is a uniform value where all bits are the same (either all zero, all ones, all undef or all pois...
Definition:ConstantFolding.cpp:763
llvm::ConstantFoldUnaryOpOperand
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
Definition:ConstantFolding.cpp:1293
llvm::FlushFPConstant
Constant * FlushFPConstant(Constant *Operand, const Instruction *I, bool IsOutput)
Attempt to flush float point constant according to denormal mode set in the instruction's parent func...
Definition:ConstantFolding.cpp:1354
llvm::CodeGenFileType::Null
@ Null
llvm::ComplexDeinterleavingOperation::Splat
@ Splat
llvm::FPClassTest
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
Definition:FloatingPointMode.h:239
llvm::fcNegSubnormal
@ fcNegSubnormal
Definition:FloatingPointMode.h:246
llvm::fcPosNormal
@ fcPosNormal
Definition:FloatingPointMode.h:250
llvm::fcQNan
@ fcQNan
Definition:FloatingPointMode.h:243
llvm::fcNegZero
@ fcNegZero
Definition:FloatingPointMode.h:247
llvm::fcNegInf
@ fcNegInf
Definition:FloatingPointMode.h:244
llvm::fcPosZero
@ fcPosZero
Definition:FloatingPointMode.h:248
llvm::fcSNan
@ fcSNan
Definition:FloatingPointMode.h:242
llvm::fcNegNormal
@ fcNegNormal
Definition:FloatingPointMode.h:245
llvm::fcPosSubnormal
@ fcPosSubnormal
Definition:FloatingPointMode.h:249
llvm::fcPosInf
@ fcPosInf
Definition:FloatingPointMode.h:251
llvm::scalbn
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
Definition:APFloat.h:1514
llvm::NullPointerIsDefined
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
Definition:Function.cpp:1187
llvm::ConstantFoldInstOperands
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
Definition:ConstantFolding.cpp:1177
llvm::ConstantFoldCastOperand
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Definition:ConstantFolding.cpp:1462
llvm::ConstantFoldLoadFromConst
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
Definition:ConstantFolding.cpp:704
llvm::ConstantFoldBinaryOpOperands
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
Definition:ConstantFolding.cpp:1300
llvm::minnum
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 minimumNumber semantics.
Definition:APFloat.h:1549
llvm::isVectorIntrinsicWithScalarOpAtArg
bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
Definition:VectorUtils.cpp:134
llvm::computeKnownBits
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
Definition:ValueTracking.cpp:164
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::ConstantFoldInstruction
Constant * ConstantFoldInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
Definition:ConstantFolding.cpp:1123
llvm::RoundingMode
RoundingMode
Rounding mode.
Definition:FloatingPointMode.h:37
llvm::isGuaranteedNotToBeUndefOrPoison
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
Definition:ValueTracking.cpp:7841
llvm::BitWidth
constexpr unsigned BitWidth
Definition:BitmaskEnum.h:217
llvm::ConstantFoldCastInstruction
Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)
Definition:ConstantFold.cpp:131
llvm::ConstantFoldInsertValueInstruction
Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)
ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue instruction with the spe...
Definition:ConstantFold.cpp:517
llvm::ConstantFoldLoadFromConstPtr
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
Definition:ConstantFolding.cpp:735
llvm::minimum
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 minimum semantics.
Definition:APFloat.h:1577
llvm::ConstantFoldIntegerCast
Constant * ConstantFoldIntegerCast(Constant *C, Type *DestTy, bool IsSigned, const DataLayout &DL)
Constant fold a zext, sext or trunc, depending on IsSigned and whether the DestTy is wider or narrowe...
Definition:ConstantFolding.cpp:1549
llvm::ConstantFoldBinaryInstruction
Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
Definition:ConstantFold.cpp:604
Status
Definition:SIModeRegister.cpp:29
llvm::APFloatBase::opStatus
opStatus
IEEE-754R 7: Default exception handling.
Definition:APFloat.h:318
llvm::DenormalMode
Represent subnormal handling kind for floating point instruction inputs and outputs.
Definition:FloatingPointMode.h:70
llvm::DenormalMode::Input
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
Definition:FloatingPointMode.h:96
llvm::DenormalMode::DenormalModeKind
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
Definition:FloatingPointMode.h:73
llvm::DenormalMode::PreserveSign
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
Definition:FloatingPointMode.h:80
llvm::DenormalMode::PositiveZero
@ PositiveZero
Denormals are flushed to positive zero.
Definition:FloatingPointMode.h:83
llvm::DenormalMode::Dynamic
@ Dynamic
Denormals have unknown treatment.
Definition:FloatingPointMode.h:86
llvm::DenormalMode::IEEE
@ IEEE
IEEE-754 denormal numbers preserved.
Definition:FloatingPointMode.h:77
llvm::DenormalMode::Output
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
Definition:FloatingPointMode.h:91
llvm::DenormalMode::getDynamic
static constexpr DenormalMode getDynamic()
Definition:FloatingPointMode.h:128
llvm::DenormalMode::getIEEE
static constexpr DenormalMode getIEEE()
Definition:FloatingPointMode.h:114
llvm::Incoming
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
Definition:SILowerI1Copies.h:25
llvm::KnownBits
Definition:KnownBits.h:23
llvm::KnownBits::isConstant
bool isConstant() const
Returns true if we know the value of all bits.
Definition:KnownBits.h:53
llvm::KnownBits::One
APInt One
Definition:KnownBits.h:25
llvm::KnownBits::Zero
APInt Zero
Definition:KnownBits.h:24
llvm::KnownBits::getConstant
const APInt & getConstant() const
Returns the value when all bits have a known value.
Definition:KnownBits.h:59
llvm::fltSemantics
Definition:APFloat.cpp:103

Generated on Thu Jul 17 2025 10:49:39 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp