31 #include "llvm/Config/config.h"
44 #include "llvm/IR/IntrinsicsAArch64.h"
45 #include "llvm/IR/IntrinsicsAMDGPU.h"
46 #include "llvm/IR/IntrinsicsARM.h"
47 #include "llvm/IR/IntrinsicsWebAssembly.h"
48 #include "llvm/IR/IntrinsicsX86.h"
76 unsigned BitShift =
DL.getTypeSizeInBits(SrcEltTy);
77 for (
unsigned i = 0;
i != NumSrcElts; ++
i) {
79 if (
DL.isLittleEndian())
84 if (Element && isa<UndefValue>(Element)) {
89 auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);
94 Result |= ElementCI->getValue().zext(
Result.getBitWidth());
105 "Invalid constantexpr bitcast!");
111 if (
auto *VTy = dyn_cast<VectorType>(
C->getType())) {
114 unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();
115 Type *SrcEltTy = VTy->getElementType();
128 if (
Constant *CE = foldConstVectorToAPInt(Result, DestTy,
C,
129 SrcEltTy, NumSrcElts,
DL))
132 if (isa<IntegerType>(DestTy))
141 auto *DestVTy = dyn_cast<VectorType>(DestTy);
147 if (isa<ConstantFP>(
C) || isa<ConstantInt>(
C)) {
153 if (!isa<ConstantDataVector>(
C) && !isa<ConstantVector>(
C))
157 unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();
158 unsigned NumSrcElt = cast<FixedVectorType>(
C->getType())->getNumElements();
159 if (NumDstElt == NumSrcElt)
162 Type *SrcEltTy = cast<VectorType>(
C->getType())->getElementType();
163 Type *DstEltTy = DestVTy->getElementType();
196 if (!isa<ConstantVector>(
C) &&
197 !isa<ConstantDataVector>(
C))
205 bool isLittleEndian =
DL.isLittleEndian();
208 if (NumDstElt < NumSrcElt) {
211 unsigned Ratio = NumSrcElt/NumDstElt;
214 for (
unsigned i = 0;
i != NumDstElt; ++
i) {
217 unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1);
218 for (
unsigned j = 0;
j != Ratio; ++
j) {
219 Constant *Src =
C->getAggregateElement(SrcElt++);
220 if (Src && isa<UndefValue>(Src))
222 cast<VectorType>(
C->getType())->getElementType());
224 Src = dyn_cast_or_null<ConstantInt>(Src);
234 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;
245 unsigned Ratio = NumDstElt/NumSrcElt;
246 unsigned DstBitSize =
DL.getTypeSizeInBits(DstEltTy);
249 for (
unsigned i = 0;
i != NumSrcElt; ++
i) {
255 if (isa<UndefValue>(Element)) {
261 auto *Src = dyn_cast<ConstantInt>(Element);
265 unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1);
266 for (
unsigned j = 0;
j != Ratio; ++
j) {
271 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;
301 if ((GV = dyn_cast<GlobalValue>(
C))) {
307 if (
auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(
C)) {
309 *DSOEquiv = FoundDSOEquiv;
310 GV = FoundDSOEquiv->getGlobalValue();
317 auto *CE = dyn_cast<ConstantExpr>(
C);
318 if (!CE)
return false;
321 if (CE->getOpcode() == Instruction::PtrToInt ||
322 CE->getOpcode() == Instruction::BitCast)
327 auto *
GEP = dyn_cast<GEPOperator>(CE);
331 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
340 if (!
GEP->accumulateConstantOffset(
DL, TmpOffset))
350 Type *SrcTy =
C->getType();
354 TypeSize DestSize =
DL.getTypeSizeInBits(DestTy);
355 TypeSize SrcSize =
DL.getTypeSizeInBits(SrcTy);
367 if (SrcSize == DestSize &&
374 Cast = Instruction::IntToPtr;
376 Cast = Instruction::PtrToInt;
398 }
while (ElemC &&
DL.getTypeSizeInBits(ElemC->
getType()).isZero());
403 if (
auto *VT = dyn_cast<VectorType>(SrcTy))
404 if (!
DL.typeSizeEqualsStoreSize(VT->getElementType()))
422 assert(ByteOffset <=
DL.getTypeAllocSize(
C->getType()) &&
423 "Out of range access");
427 if (isa<ConstantAggregateZero>(
C) || isa<UndefValue>(
C))
430 if (
auto *CI = dyn_cast<ConstantInt>(
C)) {
431 if (CI->getBitWidth() > 64 ||
432 (CI->getBitWidth() & 7) != 0)
436 unsigned IntBytes = unsigned(CI->getBitWidth()/8);
438 for (
unsigned i = 0;
i != BytesLeft && ByteOffset != IntBytes; ++
i) {
440 if (!
DL.isLittleEndian())
441 n = IntBytes -
n - 1;
442 CurPtr[
i] = (
unsigned char)(Val >> (
n * 8));
448 if (
auto *CFP = dyn_cast<ConstantFP>(
C)) {
449 if (CFP->getType()->isDoubleTy()) {
451 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
453 if (CFP->getType()->isFloatTy()){
455 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
457 if (CFP->getType()->isHalfTy()){
459 return ReadDataFromGlobal(
C, ByteOffset, CurPtr, BytesLeft,
DL);
464 if (
auto *CS = dyn_cast<ConstantStruct>(
C)) {
468 ByteOffset -= CurEltOffset;
473 uint64_t EltSize =
DL.getTypeAllocSize(CS->getOperand(Index)->getType());
475 if (ByteOffset < EltSize &&
476 !ReadDataFromGlobal(CS->getOperand(Index), ByteOffset, CurPtr,
483 if (Index == CS->getType()->getNumElements())
489 if (BytesLeft <= NextEltOffset - CurEltOffset - ByteOffset)
493 CurPtr += NextEltOffset - CurEltOffset - ByteOffset;
494 BytesLeft -= NextEltOffset - CurEltOffset - ByteOffset;
496 CurEltOffset = NextEltOffset;
501 if (isa<ConstantArray>(
C) || isa<ConstantVector>(
C) ||
502 isa<ConstantDataSequential>(
C)) {
505 if (
auto *AT = dyn_cast<ArrayType>(
C->getType())) {
506 NumElts = AT->getNumElements();
507 EltTy = AT->getElementType();
509 NumElts = cast<FixedVectorType>(
C->getType())->getNumElements();
510 EltTy = cast<FixedVectorType>(
C->getType())->getElementType();
512 uint64_t EltSize =
DL.getTypeAllocSize(EltTy);
517 if (!ReadDataFromGlobal(
C->getAggregateElement(Index), Offset, CurPtr,
522 assert(BytesWritten <= EltSize &&
"Not indexing into this element?");
523 if (BytesWritten >= BytesLeft)
527 BytesLeft -= BytesWritten;
528 CurPtr += BytesWritten;
533 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
534 if (
CE->getOpcode() == Instruction::IntToPtr &&
535 CE->getOperand(0)->getType() ==
DL.getIntPtrType(
CE->getType())) {
536 return ReadDataFromGlobal(
CE->getOperand(0), ByteOffset, CurPtr,
548 if (isa<ScalableVectorType>(LoadTy))
551 auto *IntType = dyn_cast<IntegerType>(LoadTy);
564 C->getContext(),
DL.getTypeSizeInBits(LoadTy).getFixedSize());
565 if (
Constant *Res = FoldReinterpretLoadFromConst(
C, MapTy, Offset,
DL)) {
566 if (Res->isNullValue() && !LoadTy->
isX86_MMXTy() &&
574 if (Res->isNullValue() && !LoadTy->
isX86_MMXTy() &&
587 unsigned BytesLoaded = (IntType->getBitWidth() + 7) / 8;
588 if (BytesLoaded > 32 || BytesLoaded == 0)
592 if (Offset <= -1 *
static_cast<int64_t
>(BytesLoaded))
596 TypeSize InitializerSize =
DL.getTypeAllocSize(
C->getType());
604 unsigned char RawBytes[32] = {0};
605 unsigned char *CurPtr = RawBytes;
606 unsigned BytesLeft = BytesLoaded;
615 if (!ReadDataFromGlobal(
C, Offset, CurPtr, BytesLeft,
DL))
618 APInt ResultVal =
APInt(IntType->getBitWidth(), 0);
619 if (
DL.isLittleEndian()) {
620 ResultVal = RawBytes[BytesLoaded - 1];
621 for (
unsigned i = 1;
i != BytesLoaded; ++
i) {
623 ResultVal |= RawBytes[BytesLoaded - 1 -
i];
626 ResultVal = RawBytes[0];
627 for (
unsigned i = 1;
i != BytesLoaded; ++
i) {
629 ResultVal |= RawBytes[
i];
643 if (!isa<ConstantAggregate>(
Base) && !isa<ConstantDataSequential>(
Base))
648 if (!
Offset.isZero() || !Indices[0].isZero())
653 if (
Index.isNegative() ||
Index.getActiveBits() >= 32)
656 C =
C->getAggregateElement(
Index.getZExtValue());
669 if (
Constant *AtOffset = getConstantAtOffset(
C, Offset,
DL))
676 if (!Size.isScalable() && Offset.sge(Size.getFixedSize()))
684 if (Offset.getMinSignedBits() <= 64)
686 FoldReinterpretLoadFromConst(
C, Ty, Offset.getSExtValue(),
DL))
700 C = cast<Constant>(
C->stripAndAccumulateConstantOffsets(
703 if (
auto *GV = dyn_cast<GlobalVariable>(
C))
704 if (GV->isConstant() && GV->hasDefinitiveInitializer())
712 if (GV->isConstant() && GV->hasDefinitiveInitializer()) {
724 APInt Offset(
DL.getIndexTypeSizeInBits(
C->getType()), 0);
729 if (isa<PoisonValue>(
C))
731 if (isa<UndefValue>(
C))
735 if (
C->isAllOnesValue() &&
755 if (Opc == Instruction::And) {
758 if ((Known1.
One | Known0.
Zero).isAllOnes()) {
762 if ((Known0.
One | Known1.
Zero).isAllOnes()) {
774 if (Opc == Instruction::Sub) {
780 unsigned OpSize =
DL.getTypeSizeInBits(Op0->
getType());
798 Type *IntIdxTy =
DL.getIndexType(ResultTy);
803 for (
unsigned i = 1,
e = Ops.
size();
i !=
e; ++
i) {
806 SrcElemTy, Ops.
slice(1,
i - 1)))) &&
807 Ops[
i]->getType()->getScalarType() != IntIdxScalarTy) {
809 Type *NewType = Ops[
i]->getType()->isVectorTy()
818 NewIdxs.push_back(Ops[
i]);
825 SrcElemTy, Ops[0], NewIdxs,
false, InRangeIndex);
832 auto *OldPtrTy = cast<PointerType>(Ptr->
getType());
834 auto *NewPtrTy = cast<PointerType>(Ptr->
getType());
837 if (NewPtrTy->getAddressSpace() != OldPtrTy->getAddressSpace()) {
840 OldPtrTy->getAddressSpace()));
851 bool InBounds =
GEP->isInBounds();
853 Type *SrcElemTy =
GEP->getSourceElementType();
854 Type *ResElemTy =
GEP->getResultElementType();
856 if (!SrcElemTy->
isSized() || isa<ScalableVectorType>(SrcElemTy))
859 if (
Constant *
C = CastGEPIndices(SrcElemTy, Ops, ResTy,
860 GEP->getInRangeIndex(),
DL, TLI))
869 for (
unsigned i = 1,
e = Ops.
size();
i !=
e; ++
i)
870 if (!isa<ConstantInt>(Ops[
i]))
873 unsigned BitWidth =
DL.getTypeSizeInBits(IntIdxTy);
876 DL.getIndexedOffsetInType(
879 Ptr = StripPtrCastKeepAS(Ptr);
882 while (
auto *
GEP = dyn_cast<GEPOperator>(Ptr)) {
884 InBounds &=
GEP->isInBounds();
889 bool AllConstantInt =
true;
890 for (
Value *NestedOp : NestedOps)
891 if (!isa<ConstantInt>(NestedOp)) {
892 AllConstantInt =
false;
898 Ptr = cast<Constant>(
GEP->getOperand(0));
899 SrcElemTy =
GEP->getSourceElementType();
901 Ptr = StripPtrCastKeepAS(Ptr);
907 if (
auto *CE = dyn_cast<ConstantExpr>(Ptr)) {
908 if (
CE->getOpcode() == Instruction::IntToPtr) {
909 if (
auto *
Base = dyn_cast<ConstantInt>(
CE->getOperand(0)))
914 auto *PTy = cast<PointerType>(Ptr->
getType());
916 !
DL.isNonIntegralPointerType(PTy)) {
928 if (
auto *GV = dyn_cast<GlobalValue>(Ptr))
929 SrcElemTy = GV->getValueType();
930 else if (!PTy->isOpaque())
938 Type *ElemTy = SrcElemTy;
947 while (ElemTy != ResElemTy) {
957 for (
const APInt &Index : Indices)
966 NewIdxs.size() > *LastIRIndex) {
967 InRangeIndex = LastIRIndex;
968 for (
unsigned I = 0;
I <= *LastIRIndex; ++
I)
975 InBounds, InRangeIndex);
977 cast<PointerType>(
C->getType())->isOpaqueOrPointeeTypeMatches(ElemTy) &&
978 "Computed GetElementPtr has unexpected type!");
982 if (
C->getType() != ResTy)
993 Constant *ConstantFoldInstOperandsImpl(
const Value *InstOrCE,
unsigned Opcode,
1008 if (
auto *
GEP = dyn_cast<GEPOperator>(InstOrCE)) {
1014 GEP->getInRangeIndex());
1017 if (
auto *CE = dyn_cast<ConstantExpr>(InstOrCE))
1018 return CE->getWithOperands(Ops);
1021 default:
return nullptr;
1022 case Instruction::ICmp:
1024 case Instruction::Freeze:
1027 if (
auto *
F = dyn_cast<Function>(Ops.
back())) {
1028 const auto *
Call = cast<CallBase>(InstOrCE);
1035 case Instruction::ExtractElement:
1037 case Instruction::ExtractValue:
1039 Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());
1040 case Instruction::InsertElement:
1042 case Instruction::ShuffleVector:
1044 Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());
1060 if (!isa<ConstantVector>(
C) && !isa<ConstantExpr>(
C))
1064 for (
const Use &OldU :
C->operands()) {
1065 Constant *OldC = cast<Constant>(&OldU);
1069 if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
1070 auto It = FoldedOps.
find(OldC);
1071 if (It == FoldedOps.
end()) {
1072 NewC = ConstantFoldConstantImpl(OldC,
DL, TLI, FoldedOps);
1073 FoldedOps.
insert({OldC, NewC});
1078 Ops.push_back(NewC);
1081 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1082 if (
CE->isCompare())
1086 return ConstantFoldInstOperandsImpl(CE,
CE->getOpcode(), Ops,
DL, TLI);
1089 assert(isa<ConstantVector>(
C));
1098 if (
auto *PN = dyn_cast<PHINode>(
I)) {
1102 for (
Value *Incoming : PN->incoming_values()) {
1107 if (isa<UndefValue>(Incoming))
1110 auto *
C = dyn_cast<Constant>(Incoming);
1114 C = ConstantFoldConstantImpl(
C,
DL, TLI, FoldedOps);
1117 if (CommonValue &&
C != CommonValue)
1128 if (!
all_of(
I->operands(), [](
Use &U) { return isa<Constant>(U); }))
1133 for (
const Use &OpU :
I->operands()) {
1134 auto *
Op = cast<Constant>(&OpU);
1136 Op = ConstantFoldConstantImpl(
Op,
DL, TLI, FoldedOps);
1140 if (
const auto *CI = dyn_cast<CmpInst>(
I))
1144 if (
const auto *LI = dyn_cast<LoadInst>(
I)) {
1145 if (LI->isVolatile())
1150 if (
auto *IVI = dyn_cast<InsertValueInst>(
I))
1153 if (
auto *EVI = dyn_cast<ExtractValueInst>(
I))
1162 return ConstantFoldConstantImpl(
C,
DL, TLI, FoldedOps);
1169 return ConstantFoldInstOperandsImpl(
I,
I->getOpcode(), Ops,
DL, TLI);
1187 if (
auto *CE0 = dyn_cast<ConstantExpr>(Ops0)) {
1189 if (CE0->getOpcode() == Instruction::IntToPtr) {
1190 Type *IntPtrTy =
DL.getIntPtrType(CE0->getType());
1201 if (CE0->getOpcode() == Instruction::PtrToInt) {
1202 Type *IntPtrTy =
DL.getIntPtrType(CE0->getOperand(0)->getType());
1203 if (CE0->getType() == IntPtrTy) {
1211 if (
auto *CE1 = dyn_cast<ConstantExpr>(Ops1)) {
1212 if (CE0->getOpcode() == CE1->getOpcode()) {
1213 if (CE0->getOpcode() == Instruction::IntToPtr) {
1214 Type *IntPtrTy =
DL.getIntPtrType(CE0->getType());
1227 if (CE0->getOpcode() == Instruction::PtrToInt) {
1228 Type *IntPtrTy =
DL.getIntPtrType(CE0->getOperand(0)->getType());
1229 if (CE0->getType() == IntPtrTy &&
1230 CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()) {
1232 Predicate, CE0->getOperand(0), CE1->getOperand(0),
DL, TLI);
1241 CE0->getOpcode() == Instruction::Or && Ops1->
isNullValue()) {
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)) {
1291 if (isa<ConstantExpr>(
LHS) || isa<ConstantExpr>(
RHS))
1304 case Instruction::PtrToInt:
1305 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1309 if (CE->getOpcode() == Instruction::IntToPtr) {
1312 CE->getOperand(0),
DL.getIntPtrType(CE->getType()),
1314 }
else if (
auto *
GEP = dyn_cast<GEPOperator>(CE)) {
1318 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1320 auto *
Base = cast<Constant>(
GEP->stripAndAccumulateConstantOffsets(
1321 DL, BaseOffset,
true));
1322 if (
Base->isNullValue()) {
1326 if (
GEP->getNumIndices() == 1 &&
1327 GEP->getSourceElementType()->isIntegerTy(8)) {
1328 auto *Ptr = cast<Constant>(
GEP->getPointerOperand());
1329 auto *Sub = dyn_cast<ConstantExpr>(
GEP->getOperand(1));
1331 if (Sub && Sub->getType() == IntIdxTy &&
1332 Sub->getOpcode() == Instruction::Sub &&
1333 Sub->getOperand(0)->isNullValue())
1346 case Instruction::IntToPtr:
1351 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
1352 if (CE->getOpcode() == Instruction::PtrToInt) {
1353 Constant *SrcPtr = CE->getOperand(0);
1354 unsigned SrcPtrSize =
DL.getPointerTypeSizeInBits(SrcPtr->
getType());
1355 unsigned MidIntSize = CE->getType()->getScalarSizeInBits();
1357 if (MidIntSize >= SrcPtrSize) {
1366 case Instruction::Trunc:
1367 case Instruction::ZExt:
1368 case Instruction::SExt:
1369 case Instruction::FPTrunc:
1370 case Instruction::FPExt:
1371 case Instruction::UIToFP:
1372 case Instruction::SIToFP:
1373 case Instruction::FPToUI:
1374 case Instruction::FPToSI:
1375 case Instruction::AddrSpaceCast:
1377 case Instruction::BitCast:
1387 if (Call->isNoBuiltin())
1389 if (Call->getFunctionType() !=
F->getFunctionType())
1391 switch (
F->getIntrinsicID()) {
1394 case Intrinsic::bswap:
1395 case Intrinsic::ctpop:
1396 case Intrinsic::ctlz:
1397 case Intrinsic::cttz:
1398 case Intrinsic::fshl:
1399 case Intrinsic::fshr:
1400 case Intrinsic::launder_invariant_group:
1401 case Intrinsic::strip_invariant_group:
1402 case Intrinsic::masked_load:
1403 case Intrinsic::get_active_lane_mask:
1409 case Intrinsic::sadd_with_overflow:
1410 case Intrinsic::uadd_with_overflow:
1411 case Intrinsic::ssub_with_overflow:
1412 case Intrinsic::usub_with_overflow:
1413 case Intrinsic::smul_with_overflow:
1414 case Intrinsic::umul_with_overflow:
1415 case Intrinsic::sadd_sat:
1416 case Intrinsic::uadd_sat:
1417 case Intrinsic::ssub_sat:
1418 case Intrinsic::usub_sat:
1419 case Intrinsic::smul_fix:
1420 case Intrinsic::smul_fix_sat:
1421 case Intrinsic::bitreverse:
1422 case Intrinsic::is_constant:
1423 case Intrinsic::vector_reduce_add:
1424 case Intrinsic::vector_reduce_mul:
1425 case Intrinsic::vector_reduce_and:
1426 case Intrinsic::vector_reduce_or:
1427 case Intrinsic::vector_reduce_xor:
1428 case Intrinsic::vector_reduce_smin:
1429 case Intrinsic::vector_reduce_smax:
1430 case Intrinsic::vector_reduce_umin:
1431 case Intrinsic::vector_reduce_umax:
1433 case Intrinsic::amdgcn_perm:
1434 case Intrinsic::arm_mve_vctp8:
1435 case Intrinsic::arm_mve_vctp16:
1436 case Intrinsic::arm_mve_vctp32:
1437 case Intrinsic::arm_mve_vctp64:
1438 case Intrinsic::aarch64_sve_convert_from_svbool:
1440 case Intrinsic::wasm_trunc_signed:
1441 case Intrinsic::wasm_trunc_unsigned:
1450 case Intrinsic::log:
1452 case Intrinsic::log10:
1453 case Intrinsic::exp:
1454 case Intrinsic::exp2:
1455 case Intrinsic::sqrt:
1456 case Intrinsic::sin:
1457 case Intrinsic::cos:
1458 case Intrinsic::pow:
1460 case Intrinsic::fma:
1461 case Intrinsic::fmuladd:
1462 case Intrinsic::fptoui_sat:
1463 case Intrinsic::fptosi_sat:
1464 case Intrinsic::convert_from_fp16:
1465 case Intrinsic::convert_to_fp16:
1466 case Intrinsic::amdgcn_cos:
1467 case Intrinsic::amdgcn_cubeid:
1468 case Intrinsic::amdgcn_cubema:
1469 case Intrinsic::amdgcn_cubesc:
1470 case Intrinsic::amdgcn_cubetc:
1471 case Intrinsic::amdgcn_fmul_legacy:
1472 case Intrinsic::amdgcn_fma_legacy:
1473 case Intrinsic::amdgcn_fract:
1474 case Intrinsic::amdgcn_ldexp:
1475 case Intrinsic::amdgcn_sin:
1477 case Intrinsic::x86_sse_cvtss2si:
1478 case Intrinsic::x86_sse_cvtss2si64:
1479 case Intrinsic::x86_sse_cvttss2si:
1480 case Intrinsic::x86_sse_cvttss2si64:
1481 case Intrinsic::x86_sse2_cvtsd2si:
1482 case Intrinsic::x86_sse2_cvtsd2si64:
1483 case Intrinsic::x86_sse2_cvttsd2si:
1484 case Intrinsic::x86_sse2_cvttsd2si64:
1485 case Intrinsic::x86_avx512_vcvtss2si32:
1486 case Intrinsic::x86_avx512_vcvtss2si64:
1487 case Intrinsic::x86_avx512_cvttss2si:
1488 case Intrinsic::x86_avx512_cvttss2si64:
1489 case Intrinsic::x86_avx512_vcvtsd2si32:
1490 case Intrinsic::x86_avx512_vcvtsd2si64:
1491 case Intrinsic::x86_avx512_cvttsd2si:
1492 case Intrinsic::x86_avx512_cvttsd2si64:
1493 case Intrinsic::x86_avx512_vcvtss2usi32:
1494 case Intrinsic::x86_avx512_vcvtss2usi64:
1495 case Intrinsic::x86_avx512_cvttss2usi:
1496 case Intrinsic::x86_avx512_cvttss2usi64:
1497 case Intrinsic::x86_avx512_vcvtsd2usi32:
1498 case Intrinsic::x86_avx512_vcvtsd2usi64:
1499 case Intrinsic::x86_avx512_cvttsd2usi:
1500 case Intrinsic::x86_avx512_cvttsd2usi64:
1501 return !Call->isStrictFP();
1505 case Intrinsic::fabs:
1506 case Intrinsic::copysign:
1512 case Intrinsic::roundeven:
1514 case Intrinsic::nearbyint:
1515 case Intrinsic::rint:
1518 case Intrinsic::experimental_constrained_fma:
1519 case Intrinsic::experimental_constrained_fmuladd:
1520 case Intrinsic::experimental_constrained_fadd:
1521 case Intrinsic::experimental_constrained_fsub:
1522 case Intrinsic::experimental_constrained_fmul:
1523 case Intrinsic::experimental_constrained_fdiv:
1524 case Intrinsic::experimental_constrained_frem:
1525 case Intrinsic::experimental_constrained_ceil:
1526 case Intrinsic::experimental_constrained_floor:
1527 case Intrinsic::experimental_constrained_round:
1528 case Intrinsic::experimental_constrained_roundeven:
1529 case Intrinsic::experimental_constrained_trunc:
1530 case Intrinsic::experimental_constrained_nearbyint:
1531 case Intrinsic::experimental_constrained_rint:
1532 case Intrinsic::experimental_constrained_fcmp:
1533 case Intrinsic::experimental_constrained_fcmps:
1540 if (!
F->hasName() || Call->isStrictFP())
1551 return Name ==
"acos" ||
Name ==
"acosf" ||
1552 Name ==
"asin" ||
Name ==
"asinf" ||
1553 Name ==
"atan" ||
Name ==
"atanf" ||
1554 Name ==
"atan2" ||
Name ==
"atan2f";
1556 return Name ==
"ceil" ||
Name ==
"ceilf" ||
1560 return Name ==
"exp" ||
Name ==
"expf" ||
1563 return Name ==
"fabs" ||
Name ==
"fabsf" ||
1564 Name ==
"floor" ||
Name ==
"floorf" ||
1567 return Name ==
"log" ||
Name ==
"logf" ||
1568 Name ==
"log2" ||
Name ==
"log2f" ||
1569 Name ==
"log10" ||
Name ==
"log10f";
1571 return Name ==
"nearbyint" ||
Name ==
"nearbyintf";
1573 return Name ==
"pow" ||
Name ==
"powf";
1575 return Name ==
"remainder" ||
Name ==
"remainderf" ||
1576 Name ==
"rint" ||
Name ==
"rintf" ||
1577 Name ==
"round" ||
Name ==
"roundf";
1579 return Name ==
"sin" ||
Name ==
"sinf" ||
1580 Name ==
"sinh" ||
Name ==
"sinhf" ||
1583 return Name ==
"tan" ||
Name ==
"tanf" ||
1584 Name ==
"tanh" ||
Name ==
"tanhf" ||
1585 Name ==
"trunc" ||
Name ==
"truncf";
1593 if (
Name.size() < 12 ||
Name[1] !=
'_')
1599 return Name ==
"__acos_finite" ||
Name ==
"__acosf_finite" ||
1600 Name ==
"__asin_finite" ||
Name ==
"__asinf_finite" ||
1601 Name ==
"__atan2_finite" ||
Name ==
"__atan2f_finite";
1603 return Name ==
"__cosh_finite" ||
Name ==
"__coshf_finite";
1605 return Name ==
"__exp_finite" ||
Name ==
"__expf_finite" ||
1606 Name ==
"__exp2_finite" ||
Name ==
"__exp2f_finite";
1608 return Name ==
"__log_finite" ||
Name ==
"__logf_finite" ||
1609 Name ==
"__log10_finite" ||
Name ==
"__log10f_finite";
1611 return Name ==
"__pow_finite" ||
Name ==
"__powf_finite";
1613 return Name ==
"__sinh_finite" ||
Name ==
"__sinhf_finite";
1633 inline void llvm_fenv_clearexcept() {
1634 #if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT
1635 feclearexcept(FE_ALL_EXCEPT);
1641 inline bool llvm_fenv_testexcept() {
1642 int errno_val = errno;
1643 if (errno_val == ERANGE || errno_val == EDOM)
1645 #if defined(HAVE_FENV_H) && HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT
1646 if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))
1652 Constant *ConstantFoldFP(
double (*NativeFP)(
double),
const APFloat &V,
1654 llvm_fenv_clearexcept();
1656 if (llvm_fenv_testexcept()) {
1657 llvm_fenv_clearexcept();
1661 return GetConstantFoldFPValue(Result, Ty);
1664 Constant *ConstantFoldBinaryFP(
double (*NativeFP)(
double,
double),
1666 llvm_fenv_clearexcept();
1668 if (llvm_fenv_testexcept()) {
1669 llvm_fenv_clearexcept();
1673 return GetConstantFoldFPValue(Result, Ty);
1683 if (isa<ConstantAggregateZero>(
Op))
1687 if (isa<PoisonValue>(
Op) ||
Op->containsPoisonElement())
1691 if (!isa<ConstantVector>(
Op) && !isa<ConstantDataVector>(
Op))
1694 auto *EltC = dyn_cast<ConstantInt>(
Op->getAggregateElement(0U));
1698 APInt Acc = EltC->getValue();
1700 if (!(EltC = dyn_cast<ConstantInt>(
Op->getAggregateElement(
I))))
1702 const APInt &
X = EltC->getValue();
1704 case Intrinsic::vector_reduce_add:
1707 case Intrinsic::vector_reduce_mul:
1710 case Intrinsic::vector_reduce_and:
1713 case Intrinsic::vector_reduce_or:
1716 case Intrinsic::vector_reduce_xor:
1719 case Intrinsic::vector_reduce_smin:
1722 case Intrinsic::vector_reduce_smax:
1725 case Intrinsic::vector_reduce_umin:
1728 case Intrinsic::vector_reduce_umax:
1744 Constant *ConstantFoldSSEConvertToInt(
const APFloat &Val,
bool roundTowardZero,
1745 Type *Ty,
bool IsSigned) {
1748 assert(ResultWidth <= 64 &&
1749 "Can only constant fold conversions to 64 and 32 bit ints");
1752 bool isExact =
false;
1757 IsSigned,
mode, &isExact);
1765 Type *Ty =
Op->getType();
1768 return Op->getValueAPF().convertToDouble();
1776 static bool getConstIntOrUndef(
Value *
Op,
const APInt *&
C) {
1777 if (
auto *CI = dyn_cast<ConstantInt>(
Op)) {
1778 C = &CI->getValue();
1781 if (isa<UndefValue>(
Op)) {
1800 if (St == APFloat::opStatus::opOK)
1839 if (IntrinsicID == Intrinsic::is_constant) {
1843 if (
Operands[0]->isManifestConstant())
1847 if (isa<UndefValue>(
Operands[0])) {
1851 if (IntrinsicID == Intrinsic::cos ||
1852 IntrinsicID == Intrinsic::ctpop ||
1853 IntrinsicID == Intrinsic::fptoui_sat ||
1854 IntrinsicID == Intrinsic::fptosi_sat)
1856 if (IntrinsicID == Intrinsic::bswap ||
1857 IntrinsicID == Intrinsic::bitreverse ||
1858 IntrinsicID == Intrinsic::launder_invariant_group ||
1859 IntrinsicID == Intrinsic::strip_invariant_group)
1863 if (isa<ConstantPointerNull>(
Operands[0])) {
1865 if (IntrinsicID == Intrinsic::launder_invariant_group ||
1866 IntrinsicID == Intrinsic::strip_invariant_group) {
1871 Call->getParent() ?
Call->getCaller() :
nullptr;
1881 if (
auto *
Op = dyn_cast<ConstantFP>(
Operands[0])) {
1882 if (IntrinsicID == Intrinsic::convert_to_fp16) {
1893 if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
1894 IntrinsicID == Intrinsic::wasm_trunc_unsigned) {
1895 bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed;
1902 bool IsExact =
false;
1912 if (IntrinsicID == Intrinsic::fptoui_sat ||
1913 IntrinsicID == Intrinsic::fptosi_sat) {
1916 IntrinsicID == Intrinsic::fptoui_sat);
1927 if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
1937 if (IntrinsicID == Intrinsic::roundeven) {
1957 if (IntrinsicID == Intrinsic::fabs) {
1962 if (IntrinsicID == Intrinsic::amdgcn_fract) {
1971 AlmostOne.next(
true);
1979 switch (IntrinsicID) {
1982 case Intrinsic::experimental_constrained_nearbyint:
1983 case Intrinsic::experimental_constrained_rint: {
1984 auto CI = cast<ConstrainedFPIntrinsic>(Call);
1990 case Intrinsic::experimental_constrained_round:
1993 case Intrinsic::experimental_constrained_ceil:
1996 case Intrinsic::experimental_constrained_floor:
1999 case Intrinsic::experimental_constrained_trunc:
2004 auto CI = cast<ConstrainedFPIntrinsic>(Call);
2007 if (IntrinsicID == Intrinsic::experimental_constrained_rint &&
2034 switch (IntrinsicID) {
2036 case Intrinsic::log:
2037 return ConstantFoldFP(log, APF, Ty);
2040 return ConstantFoldFP(
Log2, APF, Ty);
2041 case Intrinsic::log10:
2043 return ConstantFoldFP(log10, APF, Ty);
2044 case Intrinsic::exp:
2045 return ConstantFoldFP(exp, APF, Ty);
2046 case Intrinsic::exp2:
2048 return ConstantFoldBinaryFP(pow,
APFloat(2.0), APF, Ty);
2049 case Intrinsic::sin:
2050 return ConstantFoldFP(sin, APF, Ty);
2051 case Intrinsic::cos:
2052 return ConstantFoldFP(cos, APF, Ty);
2053 case Intrinsic::sqrt:
2054 return ConstantFoldFP(sqrt, APF, Ty);
2055 case Intrinsic::amdgcn_cos:
2056 case Intrinsic::amdgcn_sin: {
2057 double V = getValueAsDouble(
Op);
2058 if (V < -256.0 || V > 256.0)
2063 bool IsCos = IntrinsicID == Intrinsic::amdgcn_cos;
2064 double V4 = V * 4.0;
2067 const double SinVals[4] = { 0.0, 1.0, 0.0, -1.0 };
2068 V = SinVals[((
int)
V4 + (IsCos ? 1 : 0)) & 3];
2075 return GetConstantFoldFPValue(V, Ty);
2091 case LibFunc_acos_finite:
2092 case LibFunc_acosf_finite:
2094 return ConstantFoldFP(acos, APF, Ty);
2098 case LibFunc_asin_finite:
2099 case LibFunc_asinf_finite:
2101 return ConstantFoldFP(asin, APF, Ty);
2106 return ConstantFoldFP(atan, APF, Ty);
2110 if (TLI->
has(Func)) {
2118 return ConstantFoldFP(cos, APF, Ty);
2122 case LibFunc_cosh_finite:
2123 case LibFunc_coshf_finite:
2125 return ConstantFoldFP(cosh, APF, Ty);
2129 case LibFunc_exp_finite:
2130 case LibFunc_expf_finite:
2132 return ConstantFoldFP(exp, APF, Ty);
2136 case LibFunc_exp2_finite:
2137 case LibFunc_exp2f_finite:
2140 return ConstantFoldBinaryFP(pow,
APFloat(2.0), APF, Ty);
2144 if (TLI->
has(Func)) {
2150 case LibFunc_floorf:
2151 if (TLI->
has(Func)) {
2158 case LibFunc_log_finite:
2159 case LibFunc_logf_finite:
2161 return ConstantFoldFP(log, APF, Ty);
2165 case LibFunc_log2_finite:
2166 case LibFunc_log2f_finite:
2169 return ConstantFoldFP(
Log2, APF, Ty);
2172 case LibFunc_log10f:
2173 case LibFunc_log10_finite:
2174 case LibFunc_log10f_finite:
2177 return ConstantFoldFP(log10, APF, Ty);
2179 case LibFunc_nearbyint:
2180 case LibFunc_nearbyintf:
2183 if (TLI->
has(Func)) {
2189 case LibFunc_roundf:
2190 if (TLI->
has(Func)) {
2198 return ConstantFoldFP(sin, APF, Ty);
2202 case LibFunc_sinh_finite:
2203 case LibFunc_sinhf_finite:
2205 return ConstantFoldFP(sinh, APF, Ty);
2210 return ConstantFoldFP(sqrt, APF, Ty);
2215 return ConstantFoldFP(tan, APF, Ty);
2220 return ConstantFoldFP(tanh, APF, Ty);
2223 case LibFunc_truncf:
2224 if (TLI->
has(Func)) {
2233 if (
auto *
Op = dyn_cast<ConstantInt>(
Operands[0])) {
2234 switch (IntrinsicID) {
2235 case Intrinsic::bswap:
2237 case Intrinsic::ctpop:
2239 case Intrinsic::bitreverse:
2241 case Intrinsic::convert_from_fp16: {
2251 "Precision lost during fp16 constfolding");
2260 switch (IntrinsicID) {
2262 case Intrinsic::vector_reduce_add:
2263 case Intrinsic::vector_reduce_mul:
2264 case Intrinsic::vector_reduce_and:
2265 case Intrinsic::vector_reduce_or:
2266 case Intrinsic::vector_reduce_xor:
2267 case Intrinsic::vector_reduce_smin:
2268 case Intrinsic::vector_reduce_smax:
2269 case Intrinsic::vector_reduce_umin:
2270 case Intrinsic::vector_reduce_umax:
2277 if (isa<ConstantVector>(
Operands[0]) ||
2278 isa<ConstantDataVector>(
Operands[0])) {
2280 switch (IntrinsicID) {
2282 case Intrinsic::x86_sse_cvtss2si:
2283 case Intrinsic::x86_sse_cvtss2si64:
2284 case Intrinsic::x86_sse2_cvtsd2si:
2285 case Intrinsic::x86_sse2_cvtsd2si64:
2287 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2288 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2292 case Intrinsic::x86_sse_cvttss2si:
2293 case Intrinsic::x86_sse_cvttss2si64:
2294 case Intrinsic::x86_sse2_cvttsd2si:
2295 case Intrinsic::x86_sse2_cvttsd2si64:
2297 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2298 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2311 auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);
2313 if (FCmp->isSignaling()) {
2337 bool IsOp0Undef = isa<UndefValue>(
Operands[0]);
2338 bool IsOp1Undef = isa<UndefValue>(
Operands[1]);
2339 switch (IntrinsicID) {
2353 if (
const auto *Op1 = dyn_cast<ConstantFP>(
Operands[0])) {
2354 const APFloat &Op1V = Op1->getValueAPF();
2356 if (
const auto *Op2 = dyn_cast<ConstantFP>(
Operands[1])) {
2357 if (Op2->getType() != Op1->getType())
2359 const APFloat &Op2V = Op2->getValueAPF();
2361 if (
const auto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {
2365 switch (IntrinsicID) {
2368 case Intrinsic::experimental_constrained_fadd:
2369 St = Res.
add(Op2V,
RM);
2371 case Intrinsic::experimental_constrained_fsub:
2374 case Intrinsic::experimental_constrained_fmul:
2377 case Intrinsic::experimental_constrained_fdiv:
2380 case Intrinsic::experimental_constrained_frem:
2383 case Intrinsic::experimental_constrained_fcmp:
2384 case Intrinsic::experimental_constrained_fcmps:
2385 return evaluateCompare(Op1V, Op2V, ConstrIntr);
2393 switch (IntrinsicID) {
2396 case Intrinsic::copysign:
2411 switch (IntrinsicID) {
2414 case Intrinsic::pow:
2415 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
2416 case Intrinsic::amdgcn_fmul_legacy:
2436 case LibFunc_pow_finite:
2437 case LibFunc_powf_finite:
2439 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
2443 if (TLI->
has(Func)) {
2444 APFloat V = Op1->getValueAPF();
2445 if (APFloat::opStatus::opOK == V.
mod(Op2->getValueAPF()))
2449 case LibFunc_remainder:
2450 case LibFunc_remainderf:
2451 if (TLI->
has(Func)) {
2452 APFloat V = Op1->getValueAPF();
2453 if (APFloat::opStatus::opOK == V.
remainder(Op2->getValueAPF()))
2458 case LibFunc_atan2f:
2459 case LibFunc_atan2_finite:
2460 case LibFunc_atan2f_finite:
2462 return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
2465 }
else if (
auto *Op2C = dyn_cast<ConstantInt>(
Operands[1])) {
2472 (
int)Op2C->getZExtValue())));
2477 (
int)Op2C->getZExtValue())));
2482 (
int)Op2C->getZExtValue())));
2484 if (IntrinsicID == Intrinsic::amdgcn_ldexp) {
2500 if (!getConstIntOrUndef(
Operands[0], C0) ||
2504 switch (IntrinsicID) {
2525 case Intrinsic::usub_with_overflow:
2526 case Intrinsic::ssub_with_overflow:
2532 case Intrinsic::uadd_with_overflow:
2533 case Intrinsic::sadd_with_overflow:
2538 cast<StructType>(Ty),
2543 case Intrinsic::smul_with_overflow:
2544 case Intrinsic::umul_with_overflow: {
2552 switch (IntrinsicID) {
2554 case Intrinsic::sadd_with_overflow:
2557 case Intrinsic::uadd_with_overflow:
2560 case Intrinsic::ssub_with_overflow:
2563 case Intrinsic::usub_with_overflow:
2566 case Intrinsic::smul_with_overflow:
2569 case Intrinsic::umul_with_overflow:
2579 case Intrinsic::uadd_sat:
2580 case Intrinsic::sadd_sat:
2590 if (IntrinsicID == Intrinsic::uadd_sat)
2594 case Intrinsic::usub_sat:
2595 case Intrinsic::ssub_sat:
2605 if (IntrinsicID == Intrinsic::usub_sat)
2609 case Intrinsic::cttz:
2610 case Intrinsic::ctlz:
2611 assert(
C1 &&
"Must be constant int");
2614 if (
C1->isOne() && (!C0 || C0->
isZero()))
2618 if (IntrinsicID == Intrinsic::cttz)
2624 assert(
C1 &&
"Must be constant int");
2625 assert((
C1->isOne() ||
C1->isZero()) &&
"Must be 0 or 1");
2642 if ((isa<ConstantVector>(
Operands[0]) ||
2643 isa<ConstantDataVector>(
Operands[0])) &&
2647 cast<ConstantInt>(
Operands[1])->getValue() == 4) {
2649 switch (IntrinsicID) {
2651 case Intrinsic::x86_avx512_vcvtss2si32:
2652 case Intrinsic::x86_avx512_vcvtss2si64:
2653 case Intrinsic::x86_avx512_vcvtsd2si32:
2654 case Intrinsic::x86_avx512_vcvtsd2si64:
2656 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2657 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2661 case Intrinsic::x86_avx512_vcvtss2usi32:
2662 case Intrinsic::x86_avx512_vcvtss2usi64:
2663 case Intrinsic::x86_avx512_vcvtsd2usi32:
2664 case Intrinsic::x86_avx512_vcvtsd2usi64:
2666 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2667 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2671 case Intrinsic::x86_avx512_cvttss2si:
2672 case Intrinsic::x86_avx512_cvttss2si64:
2673 case Intrinsic::x86_avx512_cvttsd2si:
2674 case Intrinsic::x86_avx512_cvttsd2si64:
2676 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2677 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2681 case Intrinsic::x86_avx512_cvttss2usi:
2682 case Intrinsic::x86_avx512_cvttss2usi64:
2683 case Intrinsic::x86_avx512_cvttsd2usi:
2684 case Intrinsic::x86_avx512_cvttsd2usi64:
2686 dyn_cast_or_null<ConstantFP>(
Op->getAggregateElement(0U)))
2687 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),
2714 }
else if (
abs(S1) >=
abs(S0)) {
2737 switch (IntrinsicID) {
2740 case Intrinsic::amdgcn_cubeid:
2742 case Intrinsic::amdgcn_cubema:
2744 case Intrinsic::amdgcn_cubesc:
2746 case Intrinsic::amdgcn_cubetc:
2754 if (!getConstIntOrUndef(
Operands[0], C0) ||
2756 !getConstIntOrUndef(
Operands[2], C2))
2763 unsigned NumUndefBytes = 0;
2764 for (
unsigned I = 0;
I < 32;
I += 8) {
2773 const APInt *Src = ((Sel & 10) == 10 || (Sel & 12) == 4) ? C0 :
C1;
2777 B = Src->extractBitsAsZExtValue(8, (Sel & 3) * 8);
2779 B = Src->extractBitsAsZExtValue(1, (Sel & 1) ? 31 : 15) * 0xff;
2782 Val.insertBits(
B,
I, 8);
2785 if (NumUndefBytes == 4)
2799 if (
const auto *Op1 = dyn_cast<ConstantFP>(
Operands[0])) {
2800 if (
const auto *Op2 = dyn_cast<ConstantFP>(
Operands[1])) {
2801 if (
const auto *Op3 = dyn_cast<ConstantFP>(
Operands[2])) {
2803 const APFloat &C2 = Op2->getValueAPF();
2804 const APFloat &C3 = Op3->getValueAPF();
2806 if (
const auto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {
2810 switch (IntrinsicID) {
2813 case Intrinsic::experimental_constrained_fma:
2814 case Intrinsic::experimental_constrained_fmuladd:
2818 if (mayFoldConstrained(
2824 switch (IntrinsicID) {
2826 case Intrinsic::amdgcn_fma_legacy: {
2836 case Intrinsic::fma:
2837 case Intrinsic::fmuladd: {
2842 case Intrinsic::amdgcn_cubeid:
2843 case Intrinsic::amdgcn_cubema:
2844 case Intrinsic::amdgcn_cubesc:
2845 case Intrinsic::amdgcn_cubetc: {
2846 APFloat V = ConstantFoldAMDGCNCubeIntrinsic(IntrinsicID,
C1, C2, C3);
2854 if (IntrinsicID == Intrinsic::smul_fix ||
2855 IntrinsicID == Intrinsic::smul_fix_sat) {
2862 if (!getConstIntOrUndef(
Operands[0], C0) ||
2877 unsigned Scale = cast<ConstantInt>(
Operands[2])->getZExtValue();
2880 unsigned ExtendedWidth =
Width * 2;
2882 (C0->
sext(ExtendedWidth) *
C1->sext(ExtendedWidth)).ashr(Scale);
2883 if (IntrinsicID == Intrinsic::smul_fix_sat) {
2892 if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {
2894 if (!getConstIntOrUndef(
Operands[0], C0) ||
2896 !getConstIntOrUndef(
Operands[2], C2))
2899 bool IsRight = IntrinsicID == Intrinsic::fshr;
2913 unsigned LshrAmt = IsRight ? ShAmt :
BitWidth - ShAmt;
2914 unsigned ShlAmt = !IsRight ? ShAmt :
BitWidth - ShAmt;
2922 if (IntrinsicID == Intrinsic::amdgcn_perm)
2923 return ConstantFoldAMDGCNPermIntrinsic(
Operands, Ty);
2935 return ConstantFoldScalarCall1(
Name, IntrinsicID, Ty,
Operands, TLI, Call);
2938 return ConstantFoldScalarCall2(
Name, IntrinsicID, Ty,
Operands, TLI, Call);
2941 return ConstantFoldScalarCall3(
Name, IntrinsicID, Ty,
Operands, TLI, Call);
2946 static Constant *ConstantFoldFixedVectorCall(
2954 switch (IntrinsicID) {
2955 case Intrinsic::masked_load: {
2964 auto *MaskElt =
Mask->getAggregateElement(
I);
2967 auto *PassthruElt = Passthru->getAggregateElement(
I);
2969 if (isa<UndefValue>(MaskElt)) {
2971 NewElements.push_back(PassthruElt);
2973 NewElements.push_back(VecElt);
2977 if (MaskElt->isNullValue()) {
2980 NewElements.push_back(PassthruElt);
2981 }
else if (MaskElt->isOneValue()) {
2984 NewElements.push_back(VecElt);
2993 case Intrinsic::arm_mve_vctp8:
2994 case Intrinsic::arm_mve_vctp16:
2995 case Intrinsic::arm_mve_vctp32:
2996 case Intrinsic::arm_mve_vctp64: {
2997 if (
auto *
Op = dyn_cast<ConstantInt>(
Operands[0])) {
3002 for (
unsigned i = 0;
i < Lanes;
i++) {
3012 case Intrinsic::get_active_lane_mask: {
3013 auto *Op0 = dyn_cast<ConstantInt>(
Operands[0]);
3014 auto *Op1 = dyn_cast<ConstantInt>(
Operands[1]);
3018 uint64_t Limit = Op1->getZExtValue();
3021 for (
unsigned i = 0;
i < Lanes;
i++) {
3022 if (
Base +
i < Limit)
3037 for (
unsigned J = 0, JE =
Operands.size(); J != JE; ++J) {
3053 ConstantFoldScalarCall(
Name, IntrinsicID, Ty, Lane, TLI, Call);
3062 static Constant *ConstantFoldScalableVectorCall(
3066 switch (IntrinsicID) {
3067 case Intrinsic::aarch64_sve_convert_from_svbool: {
3068 auto *Src = dyn_cast<Constant>(
Operands[0]);
3069 if (!Src || !Src->isNullValue())
3085 if (Call->isNoBuiltin())
3100 Type *Ty =
F->getReturnType();
3101 if (
auto *FVTy = dyn_cast<FixedVectorType>(Ty))
3102 return ConstantFoldFixedVectorCall(
3104 F->getParent()->getDataLayout(), TLI, Call);
3106 if (
auto *SVTy = dyn_cast<ScalableVectorType>(Ty))
3107 return ConstantFoldScalableVectorCall(
3109 F->getParent()->getDataLayout(), TLI, Call);
3114 return ConstantFoldScalarCall(
Name,
F->getIntrinsicID(), Ty,
Operands, TLI,
3122 if (Call->isNoBuiltin() || Call->isStrictFP())
3124 Function *
F = Call->getCalledFunction();
3132 if (Call->arg_size() == 1) {
3133 if (
ConstantFP *OpC = dyn_cast<ConstantFP>(Call->getArgOperand(0))) {
3142 case LibFunc_log10l:
3144 case LibFunc_log10f:
3145 return Op.isNaN() || (!
Op.isZero() && !
Op.isNegative());
3151 if (OpC->getType()->isDoubleTy())
3153 if (OpC->getType()->isFloatTy())
3161 if (OpC->getType()->isDoubleTy())
3163 if (OpC->getType()->isFloatTy())
3173 return !
Op.isInfinity();
3177 case LibFunc_tanf: {
3180 Type *Ty = OpC->getType();
3182 return ConstantFoldFP(tan, OpC->getValueAPF(), Ty) !=
nullptr;
3202 if (OpC->getType()->isDoubleTy())
3204 if (OpC->getType()->isFloatTy())
3211 return Op.isNaN() ||
Op.isZero() || !
Op.isNegative();
3221 if (Call->arg_size() == 2) {
3222 ConstantFP *Op0C = dyn_cast<ConstantFP>(Call->getArgOperand(0));
3223 ConstantFP *Op1C = dyn_cast<ConstantFP>(Call->getArgOperand(1));
3231 case LibFunc_powf: {
3237 return ConstantFoldBinaryFP(pow, Op0, Op1, Ty) !=
nullptr;
3245 case LibFunc_remainderl:
3246 case LibFunc_remainder:
3247 case LibFunc_remainderf:
3260 void TargetFolder::anchor() {}