31#include "llvm/Config/config.h"
45#include "llvm/IR/IntrinsicsAArch64.h"
46#include "llvm/IR/IntrinsicsAMDGPU.h"
47#include "llvm/IR/IntrinsicsARM.h"
48#include "llvm/IR/IntrinsicsWebAssembly.h"
49#include "llvm/IR/IntrinsicsX86.h"
77 unsigned BitShift =
DL.getTypeSizeInBits(SrcEltTy);
78 for (
unsigned i = 0; i != NumSrcElts; ++i) {
80 if (
DL.isLittleEndian())
81 Element =
C->getAggregateElement(NumSrcElts - i - 1);
83 Element =
C->getAggregateElement(i);
85 if (isa_and_nonnull<UndefValue>(Element)) {
90 auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
95 Result |= ElementCI->getValue().zext(
Result.getBitWidth());
106 "Invalid constantexpr bitcast!");
112 if (
auto *VTy = dyn_cast<VectorType>(
C->getType())) {
115 unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
116 Type *SrcEltTy = VTy->getElementType();
129 if (
Constant *CE = foldConstVectorToAPInt(Result, DestTy,
C,
130 SrcEltTy, NumSrcElts,
DL))
133 if (isa<IntegerType>(DestTy))
134 return ConstantInt::get(DestTy, Result);
142 auto *DestVTy = dyn_cast<VectorType>(DestTy);
148 if (!isa<VectorType>(
C->getType()) &&
149 (isa<ConstantFP>(
C) || isa<ConstantInt>(
C))) {
156 if (!isa<FixedVectorType>(
C->getType()))
160 if (!isa<ConstantDataVector>(
C) && !isa<ConstantVector>(
C) &&
161 !isa<ConstantInt>(
C) && !isa<ConstantFP>(
C))
165 unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
166 unsigned NumSrcElt = cast<FixedVectorType>(
C->getType())->getNumElements();
167 if (NumDstElt == NumSrcElt)
170 Type *SrcEltTy = cast<VectorType>(
C->getType())->getElementType();
171 Type *DstEltTy = DestVTy->getElementType();
203 assert((isa<ConstantVector>(
C) ||
204 isa<ConstantDataVector>(
C) || isa<ConstantInt>(
C)) &&
205 "Constant folding cannot fail for plain fp->int bitcast!");
212 bool isLittleEndian =
DL.isLittleEndian();
215 if (NumDstElt < NumSrcElt) {
218 unsigned Ratio = NumSrcElt/NumDstElt;
221 for (
unsigned i = 0; i != NumDstElt; ++i) {
224 unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1);
225 for (
unsigned j = 0;
j != Ratio; ++
j) {
226 Constant *Src =
C->getAggregateElement(SrcElt++);
227 if (isa_and_nonnull<UndefValue>(Src))
229 cast<VectorType>(
C->getType())->getElementType());
231 Src = dyn_cast_or_null<ConstantInt>(Src);
238 assert(Src &&
"Constant folding cannot fail on plain integers");
242 Instruction::Shl, Src, ConstantInt::get(Src->getType(), ShiftAmt),
244 assert(Src &&
"Constant folding cannot fail on plain integers");
246 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
250 assert(Elt &&
"Constant folding cannot fail on plain integers");
258 unsigned Ratio = NumDstElt/NumSrcElt;
259 unsigned DstBitSize =
DL.getTypeSizeInBits(DstEltTy);
262 for (
unsigned i = 0; i != NumSrcElt; ++i) {
263 auto *Element =
C->getAggregateElement(i);
268 if (isa<UndefValue>(Element)) {
274 auto *Src = dyn_cast<ConstantInt>(Element);
278 unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1);
279 for (
unsigned j = 0;
j != Ratio; ++
j) {
282 APInt Elt = Src->getValue().lshr(ShiftAmt);
283 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
286 Result.push_back(ConstantInt::get(DstEltTy, Elt.
trunc(DstBitSize)));
304 if ((GV = dyn_cast<GlobalValue>(
C))) {
310 if (
auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(
C)) {
312 *DSOEquiv = FoundDSOEquiv;
313 GV = FoundDSOEquiv->getGlobalValue();
320 auto *CE = dyn_cast<ConstantExpr>(
C);
321 if (!CE)
return false;
324 if (CE->getOpcode() == Instruction::PtrToInt ||
325 CE->getOpcode() == Instruction::BitCast)
330 auto *
GEP = dyn_cast<GEPOperator>(CE);
334 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
343 if (!
GEP->accumulateConstantOffset(
DL, TmpOffset))
353 Type *SrcTy =
C->getType();
357 TypeSize DestSize =
DL.getTypeSizeInBits(DestTy);
358 TypeSize SrcSize =
DL.getTypeSizeInBits(SrcTy);
359 if (!TypeSize::isKnownGE(SrcSize, DestSize))
370 if (SrcSize == DestSize &&
377 Cast = Instruction::IntToPtr;
379 Cast = Instruction::PtrToInt;
400 ElemC =
C->getAggregateElement(Elem++);
401 }
while (ElemC &&
DL.getTypeSizeInBits(ElemC->
getType()).isZero());
406 if (
auto *VT = dyn_cast<VectorType>(SrcTy))
407 if (!
DL.typeSizeEqualsStoreSize(VT->getElementType()))
410 C =
C->getAggregateElement(0u);
425 assert(ByteOffset <=
DL.getTypeAllocSize(
C->getType()) &&
426 "Out of range access");
430 if (isa<ConstantAggregateZero>(
C) || isa<UndefValue>(
C))
433 if (
auto *CI = dyn_cast<ConstantInt>(
C)) {
434 if ((CI->getBitWidth() & 7) != 0)
436 const APInt &Val = CI->getValue();
437 unsigned IntBytes =
unsigned(CI->getBitWidth()/8);
439 for (
unsigned i = 0; i != BytesLeft && ByteOffset != IntBytes; ++i) {
440 unsigned n = ByteOffset;
441 if (!
DL.isLittleEndian())
442 n = IntBytes - n - 1;
449 if (
auto *CFP = dyn_cast<ConstantFP>(
C)) {
450 if (CFP->getType()->isDoubleTy()) {
452 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
454 if (CFP->getType()->isFloatTy()){
456 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
458 if (CFP->getType()->isHalfTy()){
460 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
465 if (
auto *CS = dyn_cast<ConstantStruct>(
C)) {
469 ByteOffset -= CurEltOffset;
474 uint64_t EltSize =
DL.getTypeAllocSize(CS->getOperand(Index)->getType());
476 if (ByteOffset < EltSize &&
477 !ReadDataFromGlobal(CS->getOperand(Index), ByteOffset, CurPtr,
484 if (Index == CS->getType()->getNumElements())
490 if (BytesLeft <= NextEltOffset - CurEltOffset - ByteOffset)
494 CurPtr += NextEltOffset - CurEltOffset - ByteOffset;
495 BytesLeft -= NextEltOffset - CurEltOffset - ByteOffset;
497 CurEltOffset = NextEltOffset;
502 if (isa<ConstantArray>(
C) || isa<ConstantVector>(
C) ||
503 isa<ConstantDataSequential>(
C)) {
506 if (
auto *AT = dyn_cast<ArrayType>(
C->getType())) {
507 NumElts = AT->getNumElements();
508 EltTy = AT->getElementType();
509 EltSize =
DL.getTypeAllocSize(EltTy);
511 NumElts = cast<FixedVectorType>(
C->getType())->getNumElements();
512 EltTy = cast<FixedVectorType>(
C->getType())->getElementType();
515 if (!
DL.typeSizeEqualsStoreSize(EltTy))
518 EltSize =
DL.getTypeStoreSize(EltTy);
524 if (!ReadDataFromGlobal(
C->getAggregateElement(Index),
Offset, CurPtr,
529 assert(BytesWritten <= EltSize &&
"Not indexing into this element?");
530 if (BytesWritten >= BytesLeft)
534 BytesLeft -= BytesWritten;
535 CurPtr += BytesWritten;
540 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
541 if (
CE->getOpcode() == Instruction::IntToPtr &&
542 CE->getOperand(0)->getType() ==
DL.getIntPtrType(
CE->getType())) {
543 return ReadDataFromGlobal(
CE->getOperand(0), ByteOffset, CurPtr,
555 if (isa<ScalableVectorType>(LoadTy))
558 auto *IntType = dyn_cast<IntegerType>(LoadTy);
571 DL.getTypeSizeInBits(LoadTy).getFixedValue());
592 unsigned BytesLoaded = (IntType->getBitWidth() + 7) / 8;
593 if (BytesLoaded > 32 || BytesLoaded == 0)
597 if (
Offset <= -1 *
static_cast<int64_t
>(BytesLoaded))
601 TypeSize InitializerSize =
DL.getTypeAllocSize(
C->getType());
609 unsigned char RawBytes[32] = {0};
610 unsigned char *CurPtr = RawBytes;
611 unsigned BytesLeft = BytesLoaded;
620 if (!ReadDataFromGlobal(
C,
Offset, CurPtr, BytesLeft,
DL))
623 APInt ResultVal =
APInt(IntType->getBitWidth(), 0);
624 if (
DL.isLittleEndian()) {
625 ResultVal = RawBytes[BytesLoaded - 1];
626 for (
unsigned i = 1; i != BytesLoaded; ++i) {
628 ResultVal |= RawBytes[BytesLoaded - 1 - i];
631 ResultVal = RawBytes[0];
632 for (
unsigned i = 1; i != BytesLoaded; ++i) {
634 ResultVal |= RawBytes[i];
638 return ConstantInt::get(IntType->getContext(), ResultVal);
658 if (NBytes > UINT16_MAX)
666 unsigned char *CurPtr = RawBytes.
data();
668 if (!ReadDataFromGlobal(
Init,
Offset, CurPtr, NBytes,
DL))
681 if (!isa<ConstantAggregate>(
Base) && !isa<ConstantDataSequential>(
Base))
686 if (!
Offset.isZero() || !Indices[0].isZero())
691 if (Index.isNegative() || Index.getActiveBits() >= 32)
694 C =
C->getAggregateElement(Index.getZExtValue());
720 if (
Offset.getSignificantBits() <= 64)
722 FoldReinterpretLoadFromConst(
C, Ty,
Offset.getSExtValue(),
DL))
739 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())
742 C = cast<Constant>(
C->stripAndAccumulateConstantOffsets(
763 if (isa<PoisonValue>(
C))
765 if (isa<UndefValue>(
C))
769 if (!
DL.typeSizeEqualsStoreSize(
C->getType()))
773 if (
C->isAllOnesValue() &&
793 if (Opc == Instruction::And) {
796 if ((Known1.
One | Known0.
Zero).isAllOnes()) {
800 if ((Known0.
One | Known1.
Zero).isAllOnes()) {
812 if (Opc == Instruction::Sub) {
818 unsigned OpSize =
DL.getTypeSizeInBits(Op0->
getType());
835 std::optional<ConstantRange>
InRange,
837 Type *IntIdxTy =
DL.getIndexType(ResultTy);
842 for (
unsigned i = 1, e = Ops.
size(); i != e; ++i) {
845 SrcElemTy, Ops.
slice(1, i - 1)))) &&
846 Ops[i]->getType()->getScalarType() != IntIdxScalarTy) {
849 Ops[i]->getType()->isVectorTy() ? IntIdxTy : IntIdxScalarTy;
873 Type *SrcElemTy =
GEP->getSourceElementType();
875 if (!SrcElemTy->
isSized() || isa<ScalableVectorType>(SrcElemTy))
878 if (
Constant *
C = CastGEPIndices(SrcElemTy, Ops, ResTy,
GEP->getNoWrapFlags(),
879 GEP->getInRange(),
DL, TLI))
883 if (!
Ptr->getType()->isPointerTy())
886 Type *IntIdxTy =
DL.getIndexType(
Ptr->getType());
888 for (
unsigned i = 1, e = Ops.
size(); i != e; ++i)
889 if (!isa<ConstantInt>(Ops[i]) || !Ops[i]->
getType()->isIntegerTy())
892 unsigned BitWidth =
DL.getTypeSizeInBits(IntIdxTy);
895 DL.getIndexedOffsetInType(
899 std::optional<ConstantRange>
InRange =
GEP->getInRange();
905 bool Overflow =
false;
906 while (
auto *
GEP = dyn_cast<GEPOperator>(
Ptr)) {
907 NW &=
GEP->getNoWrapFlags();
912 bool AllConstantInt =
true;
913 for (
Value *NestedOp : NestedOps)
914 if (!isa<ConstantInt>(NestedOp)) {
915 AllConstantInt =
false;
929 Ptr = cast<Constant>(
GEP->getOperand(0));
930 SrcElemTy =
GEP->getSourceElementType();
945 if (
auto *CE = dyn_cast<ConstantExpr>(
Ptr)) {
946 if (
CE->getOpcode() == Instruction::IntToPtr) {
947 if (
auto *
Base = dyn_cast<ConstantInt>(
CE->getOperand(0)))
952 auto *PTy = cast<PointerType>(
Ptr->getType());
953 if ((
Ptr->isNullValue() || BasePtr != 0) &&
954 !
DL.isNonIntegralPointerType(PTy)) {
961 bool CanBeNull, CanBeFreed;
963 Ptr->getPointerDereferenceableBytes(
DL, CanBeNull, CanBeFreed);
964 if (DerefBytes != 0 && !CanBeNull &&
Offset.sle(DerefBytes))
975 ConstantInt::get(Ctx,
Offset), NW,
984Constant *ConstantFoldInstOperandsImpl(
const Value *InstOrCE,
unsigned Opcode,
988 bool AllowNonDeterministic) {
998 case Instruction::FAdd:
999 case Instruction::FSub:
1000 case Instruction::FMul:
1001 case Instruction::FDiv:
1002 case Instruction::FRem:
1006 if (
const auto *
I = dyn_cast<Instruction>(InstOrCE)) {
1008 AllowNonDeterministic);
1017 if (
auto *
GEP = dyn_cast<GEPOperator>(InstOrCE)) {
1018 Type *SrcElemTy =
GEP->getSourceElementType();
1026 GEP->getNoWrapFlags(),
1030 if (
auto *CE = dyn_cast<ConstantExpr>(InstOrCE))
1031 return CE->getWithOperands(Ops);
1034 default:
return nullptr;
1035 case Instruction::ICmp:
1036 case Instruction::FCmp: {
1037 auto *
C = cast<CmpInst>(InstOrCE);
1041 case Instruction::Freeze:
1043 case Instruction::Call:
1044 if (
auto *
F = dyn_cast<Function>(Ops.
back())) {
1045 const auto *
Call = cast<CallBase>(InstOrCE);
1048 AllowNonDeterministic);
1051 case Instruction::Select:
1053 case Instruction::ExtractElement:
1055 case Instruction::ExtractValue:
1057 Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());
1058 case Instruction::InsertElement:
1060 case Instruction::InsertValue:
1062 Ops[0], Ops[1], cast<InsertValueInst>(InstOrCE)->getIndices());
1063 case Instruction::ShuffleVector:
1065 Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());
1066 case Instruction::Load: {
1067 const auto *LI = dyn_cast<LoadInst>(InstOrCE);
1068 if (LI->isVolatile())
1087 if (!isa<ConstantVector>(
C) && !isa<ConstantExpr>(
C))
1091 for (
const Use &OldU :
C->operands()) {
1092 Constant *OldC = cast<Constant>(&OldU);
1096 if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
1097 auto It = FoldedOps.
find(OldC);
1098 if (It == FoldedOps.
end()) {
1099 NewC = ConstantFoldConstantImpl(OldC,
DL, TLI, FoldedOps);
1100 FoldedOps.
insert({OldC, NewC});
1108 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1109 if (
Constant *Res = ConstantFoldInstOperandsImpl(
1110 CE,
CE->getOpcode(), Ops,
DL, TLI,
true))
1115 assert(isa<ConstantVector>(
C));
1124 if (
auto *PN = dyn_cast<PHINode>(
I)) {
1140 C = ConstantFoldConstantImpl(
C,
DL, TLI, FoldedOps);
1143 if (CommonValue &&
C != CommonValue)
1154 if (!
all_of(
I->operands(), [](
Use &U) { return isa<Constant>(U); }))
1159 for (
const Use &OpU :
I->operands()) {
1160 auto *
Op = cast<Constant>(&OpU);
1162 Op = ConstantFoldConstantImpl(
Op,
DL, TLI, FoldedOps);
1172 return ConstantFoldConstantImpl(
C,
DL, TLI, FoldedOps);
1179 bool AllowNonDeterministic) {
1180 return ConstantFoldInstOperandsImpl(
I,
I->getOpcode(), Ops,
DL, TLI,
1181 AllowNonDeterministic);
1198 if (
auto *CE0 = dyn_cast<ConstantExpr>(Ops0)) {
1200 if (CE0->getOpcode() == Instruction::IntToPtr) {
1201 Type *IntPtrTy =
DL.getIntPtrType(CE0->getType());
1213 if (CE0->getOpcode() == Instruction::PtrToInt) {
1214 Type *IntPtrTy =
DL.getIntPtrType(CE0->getOperand(0)->getType());
1215 if (CE0->getType() == IntPtrTy) {
1223 if (
auto *CE1 = dyn_cast<ConstantExpr>(Ops1)) {
1224 if (CE0->getOpcode() == CE1->getOpcode()) {
1225 if (CE0->getOpcode() == Instruction::IntToPtr) {
1226 Type *IntPtrTy =
DL.getIntPtrType(CE0->getType());
1240 if (CE0->getOpcode() == Instruction::PtrToInt) {
1241 Type *IntPtrTy =
DL.getIntPtrType(CE0->getOperand(0)->getType());
1242 if (CE0->getType() == IntPtrTy &&
1243 CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()) {
1245 Predicate, CE0->getOperand(0), CE1->getOperand(0),
DL, TLI);
1257 unsigned IndexWidth =
DL.getIndexTypeSizeInBits(Ops0->
getType());
1258 APInt Offset0(IndexWidth, 0);
1261 APInt Offset1(IndexWidth, 0);
1264 if (Stripped0 == Stripped1)
1270 }
else if (isa<ConstantExpr>(Ops1)) {
1273 Predicate = ICmpInst::getSwappedPredicate(Predicate);
1302 if (isa<ConstantExpr>(
LHS) || isa<ConstantExpr>(
RHS))
1317 return ConstantFP::get(Ty->
getContext(), APF);
1319 return ConstantFP::get(
1349 IsOutput ? Mode.Output : Mode.Input);
1354 if (
ConstantFP *CFP = dyn_cast<ConstantFP>(Operand))
1357 if (isa<ConstantAggregateZero, UndefValue, ConstantExpr>(Operand))
1361 VectorType *VecTy = dyn_cast<VectorType>(Ty);
1373 if (
const auto *CV = dyn_cast<ConstantVector>(Operand)) {
1375 for (
unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {
1377 if (isa<UndefValue>(Element)) {
1382 ConstantFP *CFP = dyn_cast<ConstantFP>(Element);
1395 if (
const auto *CDV = dyn_cast<ConstantDataVector>(Operand)) {
1397 for (
unsigned I = 0, E = CDV->getNumElements();
I < E; ++
I) {
1398 const APFloat &Elt = CDV->getElementAsAPFloat(
I);
1400 NewElts.
push_back(ConstantFP::get(Ty, Elt));
1420 bool AllowNonDeterministic) {
1433 if (!AllowNonDeterministic)
1434 if (
auto *
FP = dyn_cast_or_null<FPMathOperator>(
I))
1435 if (
FP->hasNoSignedZeros() ||
FP->hasAllowReassoc() ||
1436 FP->hasAllowContract() ||
FP->hasAllowReciprocal())
1450 if (!AllowNonDeterministic &&
C->isNaN())
1466 case Instruction::PtrToInt:
1467 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1471 if (CE->getOpcode() == Instruction::IntToPtr) {
1474 DL.getIntPtrType(CE->getType()),
1476 }
else if (
auto *
GEP = dyn_cast<GEPOperator>(CE)) {
1480 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1482 auto *
Base = cast<Constant>(
GEP->stripAndAccumulateConstantOffsets(
1483 DL, BaseOffset,
true));
1484 if (
Base->isNullValue()) {
1485 FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset);
1488 if (
GEP->getNumIndices() == 1 &&
1489 GEP->getSourceElementType()->isIntegerTy(8)) {
1490 auto *
Ptr = cast<Constant>(
GEP->getPointerOperand());
1491 auto *Sub = dyn_cast<ConstantExpr>(
GEP->getOperand(1));
1492 Type *IntIdxTy =
DL.getIndexType(
Ptr->getType());
1493 if (Sub && Sub->getType() == IntIdxTy &&
1494 Sub->getOpcode() == Instruction::Sub &&
1495 Sub->getOperand(0)->isNullValue())
1508 case Instruction::IntToPtr:
1513 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1514 if (CE->getOpcode() == Instruction::PtrToInt) {
1515 Constant *SrcPtr = CE->getOperand(0);
1516 unsigned SrcPtrSize =
DL.getPointerTypeSizeInBits(SrcPtr->
getType());
1517 unsigned MidIntSize = CE->getType()->getScalarSizeInBits();
1519 if (MidIntSize >= SrcPtrSize) {
1527 case Instruction::Trunc:
1528 case Instruction::ZExt:
1529 case Instruction::SExt:
1530 case Instruction::FPTrunc:
1531 case Instruction::FPExt:
1532 case Instruction::UIToFP:
1533 case Instruction::SIToFP:
1534 case Instruction::FPToUI:
1535 case Instruction::FPToSI:
1536 case Instruction::AddrSpaceCast:
1538 case Instruction::BitCast:
1549 Type *SrcTy =
C->getType();
1550 if (SrcTy == DestTy)
1564 if (Call->isNoBuiltin())
1566 if (Call->getFunctionType() !=
F->getFunctionType())
1568 switch (
F->getIntrinsicID()) {
1571 case Intrinsic::bswap:
1572 case Intrinsic::ctpop:
1573 case Intrinsic::ctlz:
1574 case Intrinsic::cttz:
1575 case Intrinsic::fshl:
1576 case Intrinsic::fshr:
1577 case Intrinsic::launder_invariant_group:
1578 case Intrinsic::strip_invariant_group:
1579 case Intrinsic::masked_load:
1580 case Intrinsic::get_active_lane_mask:
1581 case Intrinsic::abs:
1582 case Intrinsic::smax:
1583 case Intrinsic::smin:
1584 case Intrinsic::umax:
1585 case Intrinsic::umin:
1586 case Intrinsic::scmp:
1587 case Intrinsic::ucmp:
1588 case Intrinsic::sadd_with_overflow:
1589 case Intrinsic::uadd_with_overflow:
1590 case Intrinsic::ssub_with_overflow:
1591 case Intrinsic::usub_with_overflow:
1592 case Intrinsic::smul_with_overflow:
1593 case Intrinsic::umul_with_overflow:
1594 case Intrinsic::sadd_sat:
1595 case Intrinsic::uadd_sat:
1596 case Intrinsic::ssub_sat:
1597 case Intrinsic::usub_sat:
1598 case Intrinsic::smul_fix:
1599 case Intrinsic::smul_fix_sat:
1600 case Intrinsic::bitreverse:
1601 case Intrinsic::is_constant:
1602 case Intrinsic::vector_reduce_add:
1603 case Intrinsic::vector_reduce_mul:
1604 case Intrinsic::vector_reduce_and:
1605 case Intrinsic::vector_reduce_or:
1606 case Intrinsic::vector_reduce_xor:
1607 case Intrinsic::vector_reduce_smin:
1608 case Intrinsic::vector_reduce_smax:
1609 case Intrinsic::vector_reduce_umin:
1610 case Intrinsic::vector_reduce_umax:
1612 case Intrinsic::amdgcn_perm:
1613 case Intrinsic::amdgcn_wave_reduce_umin:
1614 case Intrinsic::amdgcn_wave_reduce_umax:
1615 case Intrinsic::amdgcn_s_wqm:
1616 case Intrinsic::amdgcn_s_quadmask:
1617 case Intrinsic::amdgcn_s_bitreplicate:
1618 case Intrinsic::arm_mve_vctp8:
1619 case Intrinsic::arm_mve_vctp16:
1620 case Intrinsic::arm_mve_vctp32:
1621 case Intrinsic::arm_mve_vctp64:
1622 case Intrinsic::aarch64_sve_convert_from_svbool:
1624 case Intrinsic::wasm_trunc_signed:
1625 case Intrinsic::wasm_trunc_unsigned:
1630 case Intrinsic::minnum:
1631 case Intrinsic::maxnum:
1632 case Intrinsic::minimum:
1633 case Intrinsic::maximum:
1634 case Intrinsic::log:
1635 case Intrinsic::log2:
1636 case Intrinsic::log10:
1637 case Intrinsic::exp:
1638 case Intrinsic::exp2:
1639 case Intrinsic::exp10:
1640 case Intrinsic::sqrt:
1641 case Intrinsic::sin:
1642 case Intrinsic::cos:
1643 case Intrinsic::sincos:
1644 case Intrinsic::pow:
1645 case Intrinsic::powi:
1646 case Intrinsic::ldexp:
1647 case Intrinsic::fma:
1648 case Intrinsic::fmuladd:
1649 case Intrinsic::frexp:
1650 case Intrinsic::fptoui_sat:
1651 case Intrinsic::fptosi_sat:
1652 case Intrinsic::convert_from_fp16:
1653 case Intrinsic::convert_to_fp16:
1654 case Intrinsic::amdgcn_cos:
1655 case Intrinsic::amdgcn_cubeid:
1656 case Intrinsic::amdgcn_cubema:
1657 case Intrinsic::amdgcn_cubesc:
1658 case Intrinsic::amdgcn_cubetc:
1659 case Intrinsic::amdgcn_fmul_legacy:
1660 case Intrinsic::amdgcn_fma_legacy:
1661 case Intrinsic::amdgcn_fract:
1662 case Intrinsic::amdgcn_sin:
1664 case Intrinsic::x86_sse_cvtss2si:
1665 case Intrinsic::x86_sse_cvtss2si64:
1666 case Intrinsic::x86_sse_cvttss2si:
1667 case Intrinsic::x86_sse_cvttss2si64:
1668 case Intrinsic::x86_sse2_cvtsd2si:
1669 case Intrinsic::x86_sse2_cvtsd2si64:
1670 case Intrinsic::x86_sse2_cvttsd2si:
1671 case Intrinsic::x86_sse2_cvttsd2si64:
1672 case Intrinsic::x86_avx512_vcvtss2si32:
1673 case Intrinsic::x86_avx512_vcvtss2si64:
1674 case Intrinsic::x86_avx512_cvttss2si:
1675 case Intrinsic::x86_avx512_cvttss2si64:
1676 case Intrinsic::x86_avx512_vcvtsd2si32:
1677 case Intrinsic::x86_avx512_vcvtsd2si64:
1678 case Intrinsic::x86_avx512_cvttsd2si:
1679 case Intrinsic::x86_avx512_cvttsd2si64:
1680 case Intrinsic::x86_avx512_vcvtss2usi32:
1681 case Intrinsic::x86_avx512_vcvtss2usi64:
1682 case Intrinsic::x86_avx512_cvttss2usi:
1683 case Intrinsic::x86_avx512_cvttss2usi64:
1684 case Intrinsic::x86_avx512_vcvtsd2usi32:
1685 case Intrinsic::x86_avx512_vcvtsd2usi64:
1686 case Intrinsic::x86_avx512_cvttsd2usi:
1687 case Intrinsic::x86_avx512_cvttsd2usi64:
1688 return !Call->isStrictFP();
1692 case Intrinsic::fabs:
1693 case Intrinsic::copysign:
1694 case Intrinsic::is_fpclass:
1697 case Intrinsic::ceil:
1698 case Intrinsic::floor:
1699 case Intrinsic::round:
1700 case Intrinsic::roundeven:
1701 case Intrinsic::trunc:
1702 case Intrinsic::nearbyint:
1703 case Intrinsic::rint:
1704 case Intrinsic::canonicalize:
1707 case Intrinsic::experimental_constrained_fma:
1708 case Intrinsic::experimental_constrained_fmuladd:
1709 case Intrinsic::experimental_constrained_fadd:
1710 case Intrinsic::experimental_constrained_fsub:
1711 case Intrinsic::experimental_constrained_fmul:
1712 case Intrinsic::experimental_constrained_fdiv:
1713 case Intrinsic::experimental_constrained_frem:
1714 case Intrinsic::experimental_constrained_ceil:
1715 case Intrinsic::experimental_constrained_floor:
1716 case Intrinsic::experimental_constrained_round:
1717 case Intrinsic::experimental_constrained_roundeven:
1718 case Intrinsic::experimental_constrained_trunc:
1719 case Intrinsic::experimental_constrained_nearbyint:
1720 case Intrinsic::experimental_constrained_rint:
1721 case Intrinsic::experimental_constrained_fcmp:
1722 case Intrinsic::experimental_constrained_fcmps:
1729 if (!
F->hasName() || Call->isStrictFP())
1740 return Name ==
"acos" ||
Name ==
"acosf" ||
1741 Name ==
"asin" ||
Name ==
"asinf" ||
1742 Name ==
"atan" ||
Name ==
"atanf" ||
1743 Name ==
"atan2" ||
Name ==
"atan2f";
1745 return Name ==
"ceil" ||
Name ==
"ceilf" ||
1749 return Name ==
"exp" ||
Name ==
"expf" ||
Name ==
"exp2" ||
1752 return Name ==
"fabs" ||
Name ==
"fabsf" ||
1753 Name ==
"floor" ||
Name ==
"floorf" ||
1756 return Name ==
"ilogb" ||
Name ==
"ilogbf";
1758 return Name ==
"log" ||
Name ==
"logf" ||
Name ==
"logl" ||
1759 Name ==
"log2" ||
Name ==
"log2f" ||
Name ==
"log10" ||
1760 Name ==
"log10f" ||
Name ==
"logb" ||
Name ==
"logbf" ||
1761 Name ==
"log1p" ||
Name ==
"log1pf";
1763 return Name ==
"nearbyint" ||
Name ==
"nearbyintf";
1765 return Name ==
"pow" ||
Name ==
"powf";
1767 return Name ==
"remainder" ||
Name ==
"remainderf" ||
1768 Name ==
"rint" ||
Name ==
"rintf" ||
1769 Name ==
"round" ||
Name ==
"roundf";
1771 return Name ==
"sin" ||
Name ==
"sinf" ||
1772 Name ==
"sinh" ||
Name ==
"sinhf" ||
1775 return Name ==
"tan" ||
Name ==
"tanf" ||
1776 Name ==
"tanh" ||
Name ==
"tanhf" ||
1777 Name ==
"trunc" ||
Name ==
"truncf";
1785 if (
Name.size() < 12 ||
Name[1] !=
'_')
1791 return Name ==
"__acos_finite" ||
Name ==
"__acosf_finite" ||
1792 Name ==
"__asin_finite" ||
Name ==
"__asinf_finite" ||
1793 Name ==
"__atan2_finite" ||
Name ==
"__atan2f_finite";
1795 return Name ==
"__cosh_finite" ||
Name ==
"__coshf_finite";
1797 return Name ==
"__exp_finite" ||
Name ==
"__expf_finite" ||
1798 Name ==
"__exp2_finite" ||
Name ==
"__exp2f_finite";
1800 return Name ==
"__log_finite" ||
Name ==
"__logf_finite" ||
1801 Name ==
"__log10_finite" ||
Name ==
"__log10f_finite";
1803 return Name ==
"__pow_finite" ||
Name ==
"__powf_finite";
1805 return Name ==
"__sinh_finite" ||
Name ==
"__sinhf_finite";
1816 APF.convert(Ty->
getFltSemantics(), APFloat::rmNearestTiesToEven, &unused);
1817 return ConstantFP::get(Ty->
getContext(), APF);
1824#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
1825Constant *GetConstantFoldFPValue128(float128 V,
Type *Ty) {
1827 return ConstantFP::get(Ty, V);
1833inline void llvm_fenv_clearexcept() {
1834#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
1835 feclearexcept(FE_ALL_EXCEPT);
1841inline bool llvm_fenv_testexcept() {
1842 int errno_val = errno;
1843 if (errno_val == ERANGE || errno_val == EDOM)
1845#if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
1846 if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
1854 llvm_fenv_clearexcept();
1855 double Result = NativeFP(
V.convertToDouble());
1856 if (llvm_fenv_testexcept()) {
1857 llvm_fenv_clearexcept();
1861 return GetConstantFoldFPValue(Result, Ty);
1864#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
1865Constant *ConstantFoldFP128(float128 (*NativeFP)(float128),
const APFloat &V,
1867 llvm_fenv_clearexcept();
1868 float128
Result = NativeFP(
V.convertToQuad());
1869 if (llvm_fenv_testexcept()) {
1870 llvm_fenv_clearexcept();
1874 return GetConstantFoldFPValue128(Result, Ty);
1878Constant *ConstantFoldBinaryFP(
double (*NativeFP)(
double,
double),
1880 llvm_fenv_clearexcept();
1881 double Result = NativeFP(
V.convertToDouble(),
W.convertToDouble());
1882 if (llvm_fenv_testexcept()) {
1883 llvm_fenv_clearexcept();
1887 return GetConstantFoldFPValue(Result, Ty);
1897 if (isa<ConstantAggregateZero>(
Op))
1901 if (isa<PoisonValue>(
Op) ||
Op->containsPoisonElement())
1905 if (!isa<ConstantVector>(
Op) && !isa<ConstantDataVector>(
Op))
1908 auto *EltC = dyn_cast<ConstantInt>(
Op->getAggregateElement(0U));
1912 APInt Acc = EltC->getValue();
1914 if (!(EltC = dyn_cast<ConstantInt>(
Op->getAggregateElement(
I))))
1916 const APInt &
X = EltC->getValue();
1918 case Intrinsic::vector_reduce_add:
1921 case Intrinsic::vector_reduce_mul:
1924 case Intrinsic::vector_reduce_and:
1927 case Intrinsic::vector_reduce_or:
1930 case Intrinsic::vector_reduce_xor:
1933 case Intrinsic::vector_reduce_smin:
1936 case Intrinsic::vector_reduce_smax:
1939 case Intrinsic::vector_reduce_umin:
1942 case Intrinsic::vector_reduce_umax:
1948 return ConstantInt::get(
Op->getContext(), Acc);
1958Constant *ConstantFoldSSEConvertToInt(
const APFloat &Val,
bool roundTowardZero,
1959 Type *Ty,
bool IsSigned) {
1962 assert(ResultWidth <= 64 &&
1963 "Can only constant fold conversions to 64 and 32 bit ints");
1966 bool isExact =
false;
1968 : APFloat::rmNearestTiesToEven;
1971 IsSigned,
mode, &isExact);
1972 if (status != APFloat::opOK &&
1973 (!roundTowardZero || status != APFloat::opInexact))
1975 return ConstantInt::get(Ty, UIntVal, IsSigned);
1979 Type *Ty =
Op->getType();
1982 return Op->getValueAPF().convertToDouble();
1986 APF.
convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &unused);
1991 if (
auto *CI = dyn_cast<ConstantInt>(
Op)) {
1992 C = &CI->getValue();
1995 if (isa<UndefValue>(
Op)) {
2014 if (St == APFloat::opStatus::opOK)
2019 if (ORM && *ORM == RoundingMode::Dynamic)
2024 if (EB && *EB != fp::ExceptionBehavior::ebStrict)
2036 if (!ORM || *ORM == RoundingMode::Dynamic)
2041 return RoundingMode::NearestTiesToEven;
2051 return ConstantFP::get(
2063 if (Src.isNormal() || Src.isInfinity())
2064 return ConstantFP::get(CI->
getContext(), Src);
2071 return ConstantFP::get(CI->
getContext(), Src);
2103 if (IntrinsicID == Intrinsic::is_constant) {
2107 if (
Operands[0]->isManifestConstant())
2112 if (isa<PoisonValue>(
Operands[0])) {
2114 if (IntrinsicID == Intrinsic::canonicalize)
2118 if (isa<UndefValue>(
Operands[0])) {
2122 if (IntrinsicID == Intrinsic::cos ||
2123 IntrinsicID == Intrinsic::ctpop ||
2124 IntrinsicID == Intrinsic::fptoui_sat ||
2125 IntrinsicID == Intrinsic::fptosi_sat ||
2126 IntrinsicID == Intrinsic::canonicalize)
2128 if (IntrinsicID == Intrinsic::bswap ||
2129 IntrinsicID == Intrinsic::bitreverse ||
2130 IntrinsicID == Intrinsic::launder_invariant_group ||
2131 IntrinsicID == Intrinsic::strip_invariant_group)
2135 if (isa<ConstantPointerNull>(
Operands[0])) {
2137 if (IntrinsicID == Intrinsic::launder_invariant_group ||
2138 IntrinsicID == Intrinsic::strip_invariant_group) {
2143 Call->getParent() ?
Call->getCaller() :
nullptr;
2153 if (
auto *
Op = dyn_cast<ConstantFP>(
Operands[0])) {
2154 if (IntrinsicID == Intrinsic::convert_to_fp16) {
2158 Val.
convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &lost);
2165 if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
2166 IntrinsicID == Intrinsic::wasm_trunc_unsigned) {
2167 bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed;
2174 bool IsExact =
false;
2176 U.convertToInteger(
Int, APFloat::rmTowardZero, &IsExact);
2178 if (
Status == APFloat::opOK ||
Status == APFloat::opInexact)
2179 return ConstantInt::get(Ty,
Int);
2184 if (IntrinsicID == Intrinsic::fptoui_sat ||
2185 IntrinsicID == Intrinsic::fptosi_sat) {
2188 IntrinsicID == Intrinsic::fptoui_sat);
2190 U.convertToInteger(
Int, APFloat::rmTowardZero, &IsExact);
2191 return ConstantInt::get(Ty,
Int);
2194 if (IntrinsicID == Intrinsic::canonicalize)
2195 return constantFoldCanonicalize(Ty, Call, U);
2197#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)
2199 if (IntrinsicID == Intrinsic::log) {
2200 float128
Result = logf128(
Op->getValueAPF().convertToQuad());
2201 return GetConstantFoldFPValue128(Result, Ty);
2206 Fp128Func == LibFunc_logl)
2207 return ConstantFoldFP128(logf128,
Op->getValueAPF(), Ty);
2217 if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
2218 U.roundToIntegral(APFloat::rmNearestTiesToEven);
2222 if (IntrinsicID == Intrinsic::round) {
2223 U.roundToIntegral(APFloat::rmNearestTiesToAway);
2227 if (IntrinsicID == Intrinsic::roundeven) {
2228 U.roundToIntegral(APFloat::rmNearestTiesToEven);
2232 if (IntrinsicID == Intrinsic::ceil) {
2233 U.roundToIntegral(APFloat::rmTowardPositive);
2237 if (IntrinsicID == Intrinsic::floor) {
2238 U.roundToIntegral(APFloat::rmTowardNegative);
2242 if (IntrinsicID == Intrinsic::trunc) {
2243 U.roundToIntegral(APFloat::rmTowardZero);
2247 if (IntrinsicID == Intrinsic::fabs) {
2252 if (IntrinsicID == Intrinsic::amdgcn_fract) {
2258 FloorU.roundToIntegral(APFloat::rmTowardNegative);
2260 APFloat AlmostOne(
U.getSemantics(), 1);
2261 AlmostOne.next(
true);
2268 std::optional<APFloat::roundingMode>
RM;
2269 switch (IntrinsicID) {
2272 case Intrinsic::experimental_constrained_nearbyint:
2273 case Intrinsic::experimental_constrained_rint: {
2274 auto CI = cast<ConstrainedFPIntrinsic>(Call);
2275 RM = CI->getRoundingMode();
2276 if (!RM || *RM == RoundingMode::Dynamic)
2280 case Intrinsic::experimental_constrained_round:
2281 RM = APFloat::rmNearestTiesToAway;
2283 case Intrinsic::experimental_constrained_ceil:
2284 RM = APFloat::rmTowardPositive;
2286 case Intrinsic::experimental_constrained_floor:
2287 RM = APFloat::rmTowardNegative;
2289 case Intrinsic::experimental_constrained_trunc:
2290 RM = APFloat::rmTowardZero;
2294 auto CI = cast<ConstrainedFPIntrinsic>(Call);
2297 if (IntrinsicID == Intrinsic::experimental_constrained_rint &&
2298 St == APFloat::opInexact) {
2299 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
2303 }
else if (
U.isSignaling()) {
2304 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();
2324 switch (IntrinsicID) {
2326 case Intrinsic::log:
2327 return ConstantFoldFP(log, APF, Ty);
2328 case Intrinsic::log2:
2330 return ConstantFoldFP(
log2, APF, Ty);
2331 case Intrinsic::log10:
2333 return ConstantFoldFP(log10, APF, Ty);
2334 case Intrinsic::exp:
2335 return ConstantFoldFP(exp, APF, Ty);
2336 case Intrinsic::exp2:
2338 return ConstantFoldBinaryFP(pow,
APFloat(2.0), APF, Ty);
2339 case Intrinsic::exp10:
2341 return ConstantFoldBinaryFP(pow,
APFloat(10.0), APF, Ty);
2342 case Intrinsic::sin:
2343 return ConstantFoldFP(sin, APF, Ty);
2344 case Intrinsic::cos:
2345 return ConstantFoldFP(cos, APF, Ty);
2346 case Intrinsic::sqrt:
2347 return ConstantFoldFP(sqrt, APF, Ty);
2348 case Intrinsic::amdgcn_cos:
2349 case Intrinsic::amdgcn_sin: {
2350 double V = getValueAsDouble(
Op);
2351 if (V < -256.0 || V > 256.0)
2356 bool IsCos = IntrinsicID == Intrinsic::amdgcn_cos;
2357 double V4 =
V * 4.0;
2358 if (V4 == floor(V4)) {
2360 const double SinVals[4] = { 0.0, 1.0, 0.0, -1.0 };
2361 V = SinVals[((int)V4 + (IsCos ? 1 : 0)) & 3];
2368 return GetConstantFoldFPValue(V, Ty);
2384 case LibFunc_acos_finite:
2385 case LibFunc_acosf_finite:
2387 return ConstantFoldFP(acos, APF, Ty);
2391 case LibFunc_asin_finite:
2392 case LibFunc_asinf_finite:
2394 return ConstantFoldFP(asin, APF, Ty);
2399 return ConstantFoldFP(atan, APF, Ty);
2403 if (TLI->
has(Func)) {
2404 U.roundToIntegral(APFloat::rmTowardPositive);
2411 return ConstantFoldFP(cos, APF, Ty);
2415 case LibFunc_cosh_finite:
2416 case LibFunc_coshf_finite:
2418 return ConstantFoldFP(cosh, APF, Ty);
2422 case LibFunc_exp_finite:
2423 case LibFunc_expf_finite:
2425 return ConstantFoldFP(exp, APF, Ty);
2429 case LibFunc_exp2_finite:
2430 case LibFunc_exp2f_finite:
2433 return ConstantFoldBinaryFP(pow,
APFloat(2.0), APF, Ty);
2437 if (TLI->
has(Func)) {
2443 case LibFunc_floorf:
2444 if (TLI->
has(Func)) {
2445 U.roundToIntegral(APFloat::rmTowardNegative);
2451 case LibFunc_log_finite:
2452 case LibFunc_logf_finite:
2454 return ConstantFoldFP(log, APF, Ty);
2458 case LibFunc_log2_finite:
2459 case LibFunc_log2f_finite:
2462 return ConstantFoldFP(
log2, APF, Ty);
2465 case LibFunc_log10f:
2466 case LibFunc_log10_finite:
2467 case LibFunc_log10f_finite:
2470 return ConstantFoldFP(log10, APF, Ty);
2473 case LibFunc_ilogbf:
2475 return ConstantInt::get(Ty,
ilogb(APF),
true);
2480 return ConstantFoldFP(logb, APF, Ty);
2483 case LibFunc_log1pf:
2488 return ConstantFoldFP(log1p, APF, Ty);
2495 return ConstantFoldFP(erf, APF, Ty);
2497 case LibFunc_nearbyint:
2498 case LibFunc_nearbyintf:
2501 if (TLI->
has(Func)) {
2502 U.roundToIntegral(APFloat::rmNearestTiesToEven);
2507 case LibFunc_roundf:
2508 if (TLI->
has(Func)) {
2509 U.roundToIntegral(APFloat::rmNearestTiesToAway);
2516 return ConstantFoldFP(sin, APF, Ty);
2520 case LibFunc_sinh_finite:
2521 case LibFunc_sinhf_finite:
2523 return ConstantFoldFP(sinh, APF, Ty);
2528 return ConstantFoldFP(sqrt, APF, Ty);
2533 return ConstantFoldFP(tan, APF, Ty);
2538 return ConstantFoldFP(tanh, APF, Ty);
2541 case LibFunc_truncf:
2542 if (TLI->
has(Func)) {
2543 U.roundToIntegral(APFloat::rmTowardZero);
2551 if (
auto *
Op = dyn_cast<ConstantInt>(
Operands[0])) {
2552 switch (IntrinsicID) {
2553 case Intrinsic::bswap:
2554 return ConstantInt::get(Ty->
getContext(),
Op->getValue().byteSwap());
2555 case Intrinsic::ctpop:
2556 return ConstantInt::get(Ty,
Op->getValue().popcount());
2557 case Intrinsic::bitreverse:
2558 return ConstantInt::get(Ty->
getContext(),
Op->getValue().reverseBits());
2559 case Intrinsic::convert_from_fp16: {
2560 APFloat Val(APFloat::IEEEhalf(),
Op->getValue());
2568 assert(status != APFloat::opInexact && !lost &&
2569 "Precision lost during fp16 constfolding");
2571 return ConstantFP::get(Ty->
getContext(), Val);
2574 case Intrinsic::amdgcn_s_wqm: {
2576 Val |= (Val & 0x5555555555555555ULL) << 1 |
2577 ((Val >> 1) & 0x5555555555555555ULL);
2578 Val |= (Val & 0x3333333333333333ULL) << 2 |
2579 ((Val >> 2) & 0x3333333333333333ULL);
2580 return ConstantInt::get(Ty, Val);
2583 case Intrinsic::amdgcn_s_quadmask: {
2586 for (
unsigned I = 0;
I <
Op->getBitWidth() / 4; ++
I, Val >>= 4) {
2590 QuadMask |= (1ULL <<
I);
2592 return ConstantInt::get(Ty, QuadMask);
2595 case Intrinsic::amdgcn_s_bitreplicate: {
2597 Val = (Val & 0x000000000000FFFFULL) | (Val & 0x00000000FFFF0000ULL) << 16;
2598 Val = (Val & 0x000000FF000000FFULL) | (Val & 0x0000FF000000FF00ULL) << 8;
2599 Val = (Val & 0x000F000F000F000FULL) | (Val & 0x00F000F000F000F0ULL) << 4;
2600 Val = (Val & 0x0303030303030303ULL) | (Val & 0x0C0C0C0C0C0C0C0CULL) << 2;
2601 Val = (Val & 0x1111111111111111ULL) | (Val & 0x2222222222222222ULL) << 1;
2602 Val = Val | Val << 1;
2603 return ConstantInt::get(Ty, Val);
2611 switch (IntrinsicID) {
2613 case Intrinsic::vector_reduce_add:
2614 case Intrinsic::vector_reduce_mul:
2615 case Intrinsic::vector_reduce_and:
2616 case Intrinsic::vector_reduce_or:
2617 case Intrinsic::vector_reduce_xor:
2618 case Intrinsic::vector_reduce_smin:
2619 case Intrinsic::vector_reduce_smax:
2620 case Intrinsic::vector_reduce_umin:
2621 case Intrinsic::vector_reduce_umax:
2628 if (isa<ConstantVector>(
Operands[0]) ||
2629 isa<ConstantDataVector>(
Operands[0])) {
2631 switch (IntrinsicID) {
2633 case Intrinsic::x86_sse_cvtss2si:
2634 case Intrinsic::x86_sse_cvtss2si64:
2635 case Intrinsic::x86_sse2_cvtsd2si:
2636 case Intrinsic::x86_sse2_cvtsd2si64:
2638 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2639 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2643 case Intrinsic::x86_sse_cvttss2si:
2644 case Intrinsic::x86_sse_cvttss2si64:
2645 case Intrinsic::x86_sse2_cvttsd2si:
2646 case Intrinsic::x86_sse2_cvttsd2si64:
2648 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2649 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2662 auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
2664 if (FCmp->isSignaling()) {
2666 St = APFloat::opInvalidOp;
2669 St = APFloat::opInvalidOp;
2673 return ConstantInt::get(
Call->getType()->getScalarType(), Result);
2687 const auto *Op1 = dyn_cast<ConstantFP>(
Operands[0]);
2691 const auto *Op2 = dyn_cast<ConstantFP>(
Operands[1]);
2695 const APFloat &Op1V = Op1->getValueAPF();
2696 const APFloat &Op2V = Op2->getValueAPF();
2703 case LibFunc_pow_finite:
2704 case LibFunc_powf_finite:
2706 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
2710 if (TLI->
has(Func)) {
2712 if (APFloat::opStatus::opOK ==
V.mod(Op2->getValueAPF()))
2716 case LibFunc_remainder:
2717 case LibFunc_remainderf:
2718 if (TLI->
has(Func)) {
2720 if (APFloat::opStatus::opOK ==
V.remainder(Op2->getValueAPF()))
2725 case LibFunc_atan2f:
2731 case LibFunc_atan2_finite:
2732 case LibFunc_atan2f_finite:
2734 return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
2749 bool IsOp0Undef = isa<UndefValue>(
Operands[0]);
2750 bool IsOp1Undef = isa<UndefValue>(
Operands[1]);
2751 switch (IntrinsicID) {
2752 case Intrinsic::maxnum:
2753 case Intrinsic::minnum:
2754 case Intrinsic::maximum:
2755 case Intrinsic::minimum:
2765 if (
const auto *Op1 = dyn_cast<ConstantFP>(
Operands[0])) {
2766 const APFloat &Op1V = Op1->getValueAPF();
2768 if (
const auto *Op2 = dyn_cast<ConstantFP>(
Operands[1])) {
2769 if (Op2->getType() != Op1->getType())
2771 const APFloat &Op2V = Op2->getValueAPF();
2773 if (
const auto *ConstrIntr =
2774 dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {
2778 switch (IntrinsicID) {
2781 case Intrinsic::experimental_constrained_fadd:
2782 St = Res.
add(Op2V, RM);
2784 case Intrinsic::experimental_constrained_fsub:
2787 case Intrinsic::experimental_constrained_fmul:
2790 case Intrinsic::experimental_constrained_fdiv:
2791 St = Res.
divide(Op2V, RM);
2793 case Intrinsic::experimental_constrained_frem:
2796 case Intrinsic::experimental_constrained_fcmp:
2797 case Intrinsic::experimental_constrained_fcmps:
2798 return evaluateCompare(Op1V, Op2V, ConstrIntr);
2802 return ConstantFP::get(Ty->
getContext(), Res);
2806 switch (IntrinsicID) {
2809 case Intrinsic::copysign:
2811 case Intrinsic::minnum:
2813 case Intrinsic::maxnum:
2815 case Intrinsic::minimum:
2817 case Intrinsic::maximum:
2824 switch (IntrinsicID) {
2827 case Intrinsic::pow:
2828 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
2829 case Intrinsic::amdgcn_fmul_legacy:
2834 return ConstantFP::get(Ty->
getContext(), Op1V * Op2V);
2837 }
else if (
auto *Op2C = dyn_cast<ConstantInt>(
Operands[1])) {
2838 switch (IntrinsicID) {
2839 case Intrinsic::ldexp: {
2840 return ConstantFP::get(
2842 scalbn(Op1V, Op2C->getSExtValue(), APFloat::rmNearestTiesToEven));
2844 case Intrinsic::is_fpclass: {
2857 return ConstantInt::get(Ty, Result);
2859 case Intrinsic::powi: {
2860 int Exp =
static_cast<int>(Op2C->getSExtValue());
2867 Res.
convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,
2870 return ConstantFP::get(Ty->
getContext(), Res);
2887 const APInt *C0, *C1;
2888 if (!getConstIntOrUndef(
Operands[0], C0) ||
2889 !getConstIntOrUndef(
Operands[1], C1))
2892 switch (IntrinsicID) {
2894 case Intrinsic::smax:
2895 case Intrinsic::smin:
2896 case Intrinsic::umax:
2897 case Intrinsic::umin:
2907 return ConstantInt::get(
2913 case Intrinsic::scmp:
2914 case Intrinsic::ucmp:
2919 return ConstantInt::get(Ty, 0);
2922 if (IntrinsicID == Intrinsic::scmp)
2923 Res = C0->
sgt(*C1) ? 1 : C0->
slt(*C1) ? -1 : 0;
2925 Res = C0->
ugt(*C1) ? 1 : C0->
ult(*C1) ? -1 : 0;
2926 return ConstantInt::get(Ty, Res,
true);
2928 case Intrinsic::usub_with_overflow:
2929 case Intrinsic::ssub_with_overflow:
2935 case Intrinsic::uadd_with_overflow:
2936 case Intrinsic::sadd_with_overflow:
2941 cast<StructType>(Ty),
2946 case Intrinsic::smul_with_overflow:
2947 case Intrinsic::umul_with_overflow: {
2955 switch (IntrinsicID) {
2957 case Intrinsic::sadd_with_overflow:
2958 Res = C0->
sadd_ov(*C1, Overflow);
2960 case Intrinsic::uadd_with_overflow:
2961 Res = C0->
uadd_ov(*C1, Overflow);
2963 case Intrinsic::ssub_with_overflow:
2964 Res = C0->
ssub_ov(*C1, Overflow);
2966 case Intrinsic::usub_with_overflow:
2967 Res = C0->
usub_ov(*C1, Overflow);
2969 case Intrinsic::smul_with_overflow:
2970 Res = C0->
smul_ov(*C1, Overflow);
2972 case Intrinsic::umul_with_overflow:
2973 Res = C0->
umul_ov(*C1, Overflow);
2982 case Intrinsic::uadd_sat:
2983 case Intrinsic::sadd_sat:
2993 if (IntrinsicID == Intrinsic::uadd_sat)
2994 return ConstantInt::get(Ty, C0->
uadd_sat(*C1));
2996 return ConstantInt::get(Ty, C0->
sadd_sat(*C1));
2997 case Intrinsic::usub_sat:
2998 case Intrinsic::ssub_sat:
3008 if (IntrinsicID == Intrinsic::usub_sat)
3009 return ConstantInt::get(Ty, C0->
usub_sat(*C1));
3011 return ConstantInt::get(Ty, C0->
ssub_sat(*C1));
3012 case Intrinsic::cttz:
3013 case Intrinsic::ctlz:
3014 assert(C1 &&
"Must be constant int");
3021 if (IntrinsicID == Intrinsic::cttz)
3026 case Intrinsic::abs:
3027 assert(C1 &&
"Must be constant int");
3038 return ConstantInt::get(Ty, C0->
abs());
3039 case Intrinsic::amdgcn_wave_reduce_umin:
3040 case Intrinsic::amdgcn_wave_reduce_umax:
3041 return dyn_cast<Constant>(
Operands[0]);
3048 if ((isa<ConstantVector>(
Operands[0]) ||
3049 isa<ConstantDataVector>(
Operands[0])) &&
3053 cast<ConstantInt>(
Operands[1])->getValue() == 4) {
3055 switch (IntrinsicID) {
3057 case Intrinsic::x86_avx512_vcvtss2si32:
3058 case Intrinsic::x86_avx512_vcvtss2si64:
3059 case Intrinsic::x86_avx512_vcvtsd2si32:
3060 case Intrinsic::x86_avx512_vcvtsd2si64:
3062 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
3063 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3067 case Intrinsic::x86_avx512_vcvtss2usi32:
3068 case Intrinsic::x86_avx512_vcvtss2usi64:
3069 case Intrinsic::x86_avx512_vcvtsd2usi32:
3070 case Intrinsic::x86_avx512_vcvtsd2usi64:
3072 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
3073 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3077 case Intrinsic::x86_avx512_cvttss2si:
3078 case Intrinsic::x86_avx512_cvttss2si64:
3079 case Intrinsic::x86_avx512_cvttsd2si:
3080 case Intrinsic::x86_avx512_cvttsd2si64:
3082 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
3083 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3087 case Intrinsic::x86_avx512_cvttss2usi:
3088 case Intrinsic::x86_avx512_cvttss2usi64:
3089 case Intrinsic::x86_avx512_cvttsd2usi:
3090 case Intrinsic::x86_avx512_cvttsd2usi64:
3092 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
3093 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
3121 if (
S1.isNegative() &&
S1.isNonZero() && !
S1.isNaN()) {
3143 switch (IntrinsicID) {
3146 case Intrinsic::amdgcn_cubeid:
3148 case Intrinsic::amdgcn_cubema:
3150 case Intrinsic::amdgcn_cubesc:
3152 case Intrinsic::amdgcn_cubetc:
3159 const APInt *C0, *C1, *C2;
3160 if (!getConstIntOrUndef(
Operands[0], C0) ||
3161 !getConstIntOrUndef(
Operands[1], C1) ||
3162 !getConstIntOrUndef(
Operands[2], C2))
3169 unsigned NumUndefBytes = 0;
3170 for (
unsigned I = 0;
I < 32;
I += 8) {
3179 const APInt *Src = ((Sel & 10) == 10 || (Sel & 12) == 4) ? C0 : C1;
3183 B = Src->extractBitsAsZExtValue(8, (Sel & 3) * 8);
3185 B = Src->extractBitsAsZExtValue(1, (Sel & 1) ? 31 : 15) * 0xff;
3188 Val.insertBits(
B,
I, 8);
3191 if (NumUndefBytes == 4)
3194 return ConstantInt::get(Ty, Val);
3205 if (
const auto *Op1 = dyn_cast<ConstantFP>(
Operands[0])) {
3206 if (
const auto *Op2 = dyn_cast<ConstantFP>(
Operands[1])) {
3207 if (
const auto *Op3 = dyn_cast<ConstantFP>(
Operands[2])) {
3208 const APFloat &C1 = Op1->getValueAPF();
3209 const APFloat &C2 = Op2->getValueAPF();
3210 const APFloat &C3 = Op3->getValueAPF();
3212 if (
const auto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {
3216 switch (IntrinsicID) {
3219 case Intrinsic::experimental_constrained_fma:
3220 case Intrinsic::experimental_constrained_fmuladd:
3224 if (mayFoldConstrained(
3226 return ConstantFP::get(Ty->
getContext(), Res);
3230 switch (IntrinsicID) {
3232 case Intrinsic::amdgcn_fma_legacy: {
3242 case Intrinsic::fma:
3243 case Intrinsic::fmuladd: {
3245 V.fusedMultiplyAdd(C2, C3, APFloat::rmNearestTiesToEven);
3248 case Intrinsic::amdgcn_cubeid:
3249 case Intrinsic::amdgcn_cubema:
3250 case Intrinsic::amdgcn_cubesc:
3251 case Intrinsic::amdgcn_cubetc: {
3252 APFloat V = ConstantFoldAMDGCNCubeIntrinsic(IntrinsicID, C1, C2, C3);
3260 if (IntrinsicID == Intrinsic::smul_fix ||
3261 IntrinsicID == Intrinsic::smul_fix_sat) {
3267 const APInt *C0, *C1;
3268 if (!getConstIntOrUndef(
Operands[0], C0) ||
3269 !getConstIntOrUndef(
Operands[1], C1))
3283 unsigned Scale = cast<ConstantInt>(
Operands[2])->getZExtValue();
3285 assert(Scale < Width &&
"Illegal scale.");
3286 unsigned ExtendedWidth = Width * 2;
3288 (C0->
sext(ExtendedWidth) * C1->
sext(ExtendedWidth)).ashr(Scale);
3289 if (IntrinsicID == Intrinsic::smul_fix_sat) {
3298 if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {
3299 const APInt *C0, *C1, *C2;
3300 if (!getConstIntOrUndef(
Operands[0], C0) ||
3301 !getConstIntOrUndef(
Operands[1], C1) ||
3302 !getConstIntOrUndef(
Operands[2], C2))
3305 bool IsRight = IntrinsicID == Intrinsic::fshr;
3319 unsigned LshrAmt = IsRight ? ShAmt :
BitWidth - ShAmt;
3320 unsigned ShlAmt = !IsRight ? ShAmt :
BitWidth - ShAmt;
3322 return ConstantInt::get(Ty, C1->
lshr(LshrAmt));
3324 return ConstantInt::get(Ty, C0->
shl(ShlAmt));
3325 return ConstantInt::get(Ty, C0->
shl(ShlAmt) | C1->
lshr(LshrAmt));
3328 if (IntrinsicID == Intrinsic::amdgcn_perm)
3329 return ConstantFoldAMDGCNPermIntrinsic(
Operands, Ty);
3341 return ConstantFoldScalarCall1(
Name, IntrinsicID, Ty,
Operands, TLI, Call);
3346 return FoldedLibCall;
3348 return ConstantFoldIntrinsicCall2(IntrinsicID, Ty,
Operands, Call);
3352 return ConstantFoldScalarCall3(
Name, IntrinsicID, Ty,
Operands, TLI, Call);
3357static Constant *ConstantFoldFixedVectorCall(
3365 switch (IntrinsicID) {
3366 case Intrinsic::masked_load: {
3375 auto *MaskElt =
Mask->getAggregateElement(
I);
3378 auto *PassthruElt = Passthru->getAggregateElement(
I);
3380 if (isa<UndefValue>(MaskElt)) {
3388 if (MaskElt->isNullValue()) {
3392 }
else if (MaskElt->isOneValue()) {
3404 case Intrinsic::arm_mve_vctp8:
3405 case Intrinsic::arm_mve_vctp16:
3406 case Intrinsic::arm_mve_vctp32:
3407 case Intrinsic::arm_mve_vctp64: {
3408 if (
auto *
Op = dyn_cast<ConstantInt>(
Operands[0])) {
3413 for (
unsigned i = 0; i < Lanes; i++) {
3423 case Intrinsic::get_active_lane_mask: {
3424 auto *Op0 = dyn_cast<ConstantInt>(
Operands[0]);
3425 auto *Op1 = dyn_cast<ConstantInt>(
Operands[1]);
3429 uint64_t Limit = Op1->getZExtValue();
3432 for (
unsigned i = 0; i < Lanes; i++) {
3433 if (
Base + i < Limit)
3448 for (
unsigned J = 0, JE =
Operands.size(); J != JE; ++J) {
3464 ConstantFoldScalarCall(
Name, IntrinsicID, Ty, Lane, TLI, Call);
3473static Constant *ConstantFoldScalableVectorCall(
3477 switch (IntrinsicID) {
3478 case Intrinsic::aarch64_sve_convert_from_svbool: {
3479 auto *Src = dyn_cast<Constant>(
Operands[0]);
3480 if (!Src || !Src->isNullValue())
3491static std::pair<Constant *, Constant *>
3493 if (isa<PoisonValue>(
Op))
3496 auto *ConstFP = dyn_cast<ConstantFP>(
Op);
3500 const APFloat &
U = ConstFP->getValueAPF();
3502 APFloat FrexpMant =
frexp(U, FrexpExp, APFloat::rmNearestTiesToEven);
3503 Constant *Result0 = ConstantFP::get(ConstFP->getType(), FrexpMant);
3510 return {Result0, Result1};
3520 switch (IntrinsicID) {
3521 case Intrinsic::frexp: {
3525 if (
auto *FVTy0 = dyn_cast<FixedVectorType>(Ty0)) {
3529 for (
unsigned I = 0, E = FVTy0->getNumElements();
I != E; ++
I) {
3531 std::tie(Results0[
I], Results1[
I]) =
3532 ConstantFoldScalarFrexpCall(Lane, Ty1);
3541 auto [Result0, Result1] = ConstantFoldScalarFrexpCall(
Operands[0], Ty1);
3546 case Intrinsic::sincos: {
3550 auto ConstantFoldScalarSincosCall =
3551 [&](
Constant *
Op) -> std::pair<Constant *, Constant *> {
3553 ConstantFoldScalarCall(
Name, Intrinsic::sin, TyScalar,
Op, TLI, Call);
3555 ConstantFoldScalarCall(
Name, Intrinsic::cos, TyScalar,
Op, TLI, Call);
3556 return std::make_pair(SinResult, CosResult);
3559 if (
auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {
3565 std::tie(SinResults[
I], CosResults[
I]) =
3566 ConstantFoldScalarSincosCall(Lane);
3567 if (!SinResults[
I] || !CosResults[
I])
3575 auto [SinResult, CosResult] = ConstantFoldScalarSincosCall(
Operands[0]);
3576 if (!SinResult || !CosResult)
3583 return ConstantFoldScalarCall(
Name, IntrinsicID, StTy,
Operands, TLI, Call);
3594 return ConstantFoldIntrinsicCall2(
ID, Ty, {
LHS,
RHS},
3595 dyn_cast_if_present<CallBase>(FMFSource));
3601 bool AllowNonDeterministic) {
3602 if (Call->isNoBuiltin())
3619 Type *Ty =
F->getReturnType();
3624 if (
auto *FVTy = dyn_cast<FixedVectorType>(Ty))
3625 return ConstantFoldFixedVectorCall(
3628 if (
auto *SVTy = dyn_cast<ScalableVectorType>(Ty))
3629 return ConstantFoldScalableVectorCall(
3632 if (
auto *StTy = dyn_cast<StructType>(Ty))
3633 return ConstantFoldStructCall(
Name, IID, StTy,
Operands,
3634 F->getDataLayout(), TLI, Call);
3639 return ConstantFoldScalarCall(
Name, IID, Ty,
Operands, TLI, Call);
3646 if (Call->isNoBuiltin() || Call->isStrictFP())
3648 Function *
F = Call->getCalledFunction();
3656 if (Call->arg_size() == 1) {
3657 if (
ConstantFP *OpC = dyn_cast<ConstantFP>(Call->getArgOperand(0))) {
3666 case LibFunc_log10l:
3668 case LibFunc_log10f:
3669 return Op.isNaN() || (!
Op.isZero() && !
Op.isNegative());
3675 if (OpC->getType()->isDoubleTy())
3677 if (OpC->getType()->isFloatTy())
3685 if (OpC->getType()->isDoubleTy())
3687 if (OpC->getType()->isFloatTy())
3697 return !
Op.isInfinity();
3701 case LibFunc_tanf: {
3704 Type *Ty = OpC->getType();
3706 return ConstantFoldFP(tan, OpC->getValueAPF(), Ty) !=
nullptr;
3732 if (OpC->getType()->isDoubleTy())
3734 if (OpC->getType()->isFloatTy())
3741 return Op.isNaN() ||
Op.isZero() || !
Op.isNegative();
3751 if (Call->arg_size() == 2) {
3752 ConstantFP *Op0C = dyn_cast<ConstantFP>(Call->getArgOperand(0));
3753 ConstantFP *Op1C = dyn_cast<ConstantFP>(Call->getArgOperand(1));
3761 case LibFunc_powf: {
3767 return ConstantFoldBinaryFP(pow, Op0, Op1, Ty) !=
nullptr;
3775 case LibFunc_remainderl:
3776 case LibFunc_remainder:
3777 case LibFunc_remainderf:
3782 case LibFunc_atan2f:
3783 case LibFunc_atan2l:
3799void TargetFolder::anchor() {}
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Constant * FoldBitCast(Constant *V, Type *DestTy)
static ConstantFP * flushDenormalConstant(Type *Ty, const APFloat &APF, DenormalMode::DenormalModeKind Mode)
Constant * getConstantAtOffset(Constant *Base, APInt Offset, const DataLayout &DL)
If this Offset points exactly to the start of an aggregate element, return that element,...
static ConstantFP * flushDenormalConstantFP(ConstantFP *CFP, const Instruction *Inst, bool IsOutput)
static DenormalMode getInstrDenormalMode(const Instruction *CtxI, Type *Ty)
Return the denormal mode that can be assumed when executing a floating point operation at CtxI.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
amode Optimize addressing mode
mir Rename Register Operands
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)
Factory for QNaN values.
opStatus divide(const APFloat &RHS, roundingMode RM)
void copySign(const APFloat &RHS)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
opStatus subtract(const APFloat &RHS, roundingMode RM)
double convertToDouble() const
Converts this APFloat to host double value.
bool isPosInfinity() const
opStatus add(const APFloat &RHS, roundingMode RM)
const fltSemantics & getSemantics() const
static APFloat getOne(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative One.
opStatus multiply(const APFloat &RHS, roundingMode RM)
float convertToFloat() const
Converts this APFloat to host float value.
opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend, roundingMode RM)
APInt bitcastToAPInt() const
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
opStatus mod(const APFloat &RHS)
bool isNegInfinity() const
static APFloat getZero(const fltSemantics &Sem, bool Negative=false)
Factory for Positive and Negative Zero.
Class for arbitrary precision integers.
APInt umul_ov(const APInt &RHS, bool &Overflow) const
APInt usub_sat(const APInt &RHS) const
bool isMinSignedValue() const
Determine if this is the smallest signed value.
uint64_t getZExtValue() const
Get zero extended value.
uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const
APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
APInt trunc(unsigned width) const
Truncate to new width.
APInt abs() const
Get the absolute value.
APInt sadd_sat(const APInt &RHS) const
bool sgt(const APInt &RHS) const
Signed greater than comparison.
APInt usub_ov(const APInt &RHS, bool &Overflow) const
bool ugt(const APInt &RHS) const
Unsigned greater than comparison.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const
APInt uadd_ov(const APInt &RHS, bool &Overflow) const
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned countl_zero() const
The APInt version of std::countl_zero.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
APInt sextOrTrunc(unsigned width) const
Sign extend or truncate to width.
APInt uadd_sat(const APInt &RHS) const
APInt smul_ov(const APInt &RHS, bool &Overflow) const
APInt sext(unsigned width) const
Sign extend to a new width.
APInt shl(unsigned shiftAmt) const
Left-shift function.
bool slt(const APInt &RHS) const
Signed less than comparison.
APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
APInt ssub_ov(const APInt &RHS, bool &Overflow) const
bool isOne() const
Determine if this is a value of 1.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
APInt ssub_sat(const APInt &RHS) const
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
back - Get the last element.
size_t size() const
size - Get the array size.
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.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
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.
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.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
bool isFPPredicate() const
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getExtractElement(Constant *Vec, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static bool isDesirableCastOp(unsigned Opcode)
Whether creating a constant expression for this cast is desirable.
static Constant * getCast(unsigned ops, Constant *C, Type *Ty, bool OnlyIfReduced=false)
Convenience function for getting a Cast operation.
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy=nullptr)
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getShuffleVector(Constant *V1, Constant *V2, ArrayRef< int > Mask, Type *OnlyIfReducedTy=nullptr)
static bool isSupportedGetElementPtr(const Type *SrcElemTy)
Whether creating a constant expression for this getelementptr type is supported.
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.
static bool isDesirableBinOp(unsigned Opcode)
Whether creating a constant expression for this binary operator is desirable.
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.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
static Constant * getZero(Type *Ty, bool Negative=false)
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static ConstantInt * getFalse(LLVMContext &Context)
static ConstantInt * getBool(LLVMContext &Context, bool V)
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Constrained floating point compare intrinsics.
This is the common base class for constrained floating point intrinsics.
std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
std::optional< RoundingMode > getRoundingMode() const
Wrapper for a function that represents a value that functionally represents the original function.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static bool compare(const APFloat &LHS, const APFloat &RHS, FCmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
DenormalMode getDenormalMode(const fltSemantics &FPType) const
Returns the denormal handling type for the default rounding mode of the function.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags inBounds()
GEPNoWrapFlags withoutNoUnsignedSignedWrap() const
static GEPNoWrapFlags noUnsignedWrap()
bool hasNoUnsignedSignedWrap() const
static Type * getIndexedType(Type *Ty, ArrayRef< Value * > IdxList)
Returns the result type of a getelementptr with the given source element type and indexes.
PointerType * getType() const
Global values are always pointers.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
static bool compare(const APInt &LHS, const APInt &RHS, ICmpInst::Predicate Pred)
Return result of LHS Pred RHS comparison.
Predicate getSignedPredicate() const
For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
const Function * getFunction() const
Return the function this instruction belongs to.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
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...
ICmpInst::Predicate getPredicate() const
Returns the comparison predicate underlying the intrinsic.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Class to represent scalable SIMD vectors.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
TypeSize getElementOffset(unsigned Idx) const
Class to represent struct types.
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
Type * getStructElementType(unsigned N) const
const fltSemantics & getFltSemantics() const
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
bool isPointerTy() const
True if this is an instance of PointerType.
static IntegerType * getInt1Ty(LLVMContext &C)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
@ HalfTyID
16-bit floating point type
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isFP128Ty() const
Return true if this is 'fp128'.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isStructTy() const
True if this is an instance of StructType.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
static IntegerType * getInt16Ty(LLVMContext &C)
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isX86_AMXTy() const
Return true if this is X86 AMX.
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getContainedType(unsigned i) const
This method is used to implement the type iterator (defined at the end of the file).
bool isIEEELikeFPTy() const
Return true if this is a well-behaved IEEE-like type, which has a IEEE compatible layout as defined b...
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
This is a wrapper around stripAndAccumulateConstantOffsets with the in-bounds requirement set to fals...
LLVMContext & getContext() const
All values hold a context through their type.
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
const ParentTy * getParent() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
const APInt & umin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be unsigned.
const APInt & umax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be unsigned.
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.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ CE
Windows NT (Windows on ARM)
int ilogb(const IEEEFloat &Arg)
@ ebStrict
This corresponds to "fpexcept.strict".
@ ebIgnore
This corresponds to "fpexcept.ignore".
NodeAddr< FuncNode * > Func
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Constant * ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS, Constant *RHS, Type *Ty, Instruction *FMFSource)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy, const DataLayout &DL)
ConstantFoldLoadThroughBitcast - try to cast constant to destination type returning null if unsuccess...
static double log2(double V)
Constant * ConstantFoldSelectInstruction(Constant *Cond, Constant *V1, Constant *V2)
Attempt to constant fold a select instruction with the specified operands.
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,...
bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
unsigned getPointerAddressSpace(const Type *T)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Constant * ConstantFoldCompareInstruction(CmpInst::Predicate Predicate, Constant *C1, Constant *C2)
Constant * ConstantFoldUnaryInstruction(unsigned Opcode, Constant *V)
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.
bool isMathLibCallNoop(const CallBase *Call, const TargetLibraryInfo *TLI)
Check whether the given call has no side-effects.
Constant * ReadByteArrayFromGlobal(const GlobalVariable *GV, uint64_t Offset)
LLVM_READONLY APFloat maximum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 maximum semantics.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.
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...
APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM)
Equivalent of C standard library function.
Constant * ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef< unsigned > Idxs)
Attempt to constant fold an extractvalue instruction with the specified operands and indices.
Constant * ConstantFoldConstant(const Constant *C, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldConstant - Fold the constant using the specified DataLayout.
LLVM_READONLY APFloat maxnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 maximumNumber semantics.
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...
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
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...
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM)
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
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.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Constant * ConstantFoldLoadFromConst(Constant *C, Type *Ty, const APInt &Offset, const DataLayout &DL)
Extract value of C at the given Offset reinterpreted as Ty.
Constant * ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS, Constant *RHS, const DataLayout &DL)
Attempt to constant fold a binary operation with the specified operands.
LLVM_READONLY APFloat minnum(const APFloat &A, const APFloat &B)
Implements IEEE-754 2019 minimumNumber semantics.
bool isVectorIntrinsicWithScalarOpAtArg(Intrinsic::ID ID, unsigned ScalarOpdIdx, const TargetTransformInfo *TTI)
Identifies if the vector form of the intrinsic has a scalar operand.
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...
DWARFExpression::Operation Op
Constant * ConstantFoldInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstruction - Try to constant fold the specified instruction.
RoundingMode
Rounding mode.
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.
constexpr unsigned BitWidth
Constant * ConstantFoldCastInstruction(unsigned opcode, Constant *V, Type *DestTy)
Constant * ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, ArrayRef< unsigned > Idxs)
ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue instruction with the spe...
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...
LLVM_READONLY APFloat minimum(const APFloat &A, const APFloat &B)
Implements IEEE 754-2019 minimum semantics.
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...
Constant * ConstantFoldBinaryInstruction(unsigned Opcode, Constant *V1, Constant *V2)
opStatus
IEEE-754R 7: Default exception handling.
Represent subnormal handling kind for floating point instruction inputs and outputs.
DenormalModeKind Input
Denormal treatment kind for floating point instruction inputs in the default floating-point environme...
DenormalModeKind
Represent handled modes for denormal (aka subnormal) modes in the floating point environment.
@ PreserveSign
The sign of a flushed-to-zero number is preserved in the sign of 0.
@ PositiveZero
Denormals are flushed to positive zero.
@ Dynamic
Denormals have unknown treatment.
@ IEEE
IEEE-754 denormal numbers preserved.
DenormalModeKind Output
Denormal flushing mode for floating point instruction results in the default floating point environme...
static constexpr DenormalMode getDynamic()
static constexpr DenormalMode getIEEE()
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.