4765 lines · cpp
1//===-- ConstantFolding.cpp - Fold instructions into constants ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines routines for folding instructions into constants.10//11// Also, to supplement the basic IR ConstantExpr simplifications,12// this file defines some additional folding routines that can make use of13// DataLayout information. These functions cannot go in IR due to library14// dependency issues.15//16//===----------------------------------------------------------------------===//17 18#include "llvm/Analysis/ConstantFolding.h"19#include "llvm/ADT/APFloat.h"20#include "llvm/ADT/APInt.h"21#include "llvm/ADT/APSInt.h"22#include "llvm/ADT/ArrayRef.h"23#include "llvm/ADT/DenseMap.h"24#include "llvm/ADT/STLExtras.h"25#include "llvm/ADT/SmallVector.h"26#include "llvm/ADT/StringRef.h"27#include "llvm/Analysis/TargetFolder.h"28#include "llvm/Analysis/TargetLibraryInfo.h"29#include "llvm/Analysis/ValueTracking.h"30#include "llvm/Analysis/VectorUtils.h"31#include "llvm/Config/config.h"32#include "llvm/IR/Constant.h"33#include "llvm/IR/ConstantFold.h"34#include "llvm/IR/Constants.h"35#include "llvm/IR/DataLayout.h"36#include "llvm/IR/DerivedTypes.h"37#include "llvm/IR/Function.h"38#include "llvm/IR/GlobalValue.h"39#include "llvm/IR/GlobalVariable.h"40#include "llvm/IR/InstrTypes.h"41#include "llvm/IR/Instruction.h"42#include "llvm/IR/Instructions.h"43#include "llvm/IR/IntrinsicInst.h"44#include "llvm/IR/Intrinsics.h"45#include "llvm/IR/IntrinsicsAArch64.h"46#include "llvm/IR/IntrinsicsAMDGPU.h"47#include "llvm/IR/IntrinsicsARM.h"48#include "llvm/IR/IntrinsicsNVPTX.h"49#include "llvm/IR/IntrinsicsWebAssembly.h"50#include "llvm/IR/IntrinsicsX86.h"51#include "llvm/IR/NVVMIntrinsicUtils.h"52#include "llvm/IR/Operator.h"53#include "llvm/IR/Type.h"54#include "llvm/IR/Value.h"55#include "llvm/Support/Casting.h"56#include "llvm/Support/ErrorHandling.h"57#include "llvm/Support/KnownBits.h"58#include "llvm/Support/MathExtras.h"59#include <cassert>60#include <cerrno>61#include <cfenv>62#include <cmath>63#include <cstdint>64 65using namespace llvm;66 67static cl::opt<bool> DisableFPCallFolding(68 "disable-fp-call-folding",69 cl::desc("Disable constant-folding of FP intrinsics and libcalls."),70 cl::init(false), cl::Hidden);71 72namespace {73 74//===----------------------------------------------------------------------===//75// Constant Folding internal helper functions76//===----------------------------------------------------------------------===//77 78static Constant *foldConstVectorToAPInt(APInt &Result, Type *DestTy,79 Constant *C, Type *SrcEltTy,80 unsigned NumSrcElts,81 const DataLayout &DL) {82 // Now that we know that the input value is a vector of integers, just shift83 // and insert them into our result.84 unsigned BitShift = DL.getTypeSizeInBits(SrcEltTy);85 for (unsigned i = 0; i != NumSrcElts; ++i) {86 Constant *Element;87 if (DL.isLittleEndian())88 Element = C->getAggregateElement(NumSrcElts - i - 1);89 else90 Element = C->getAggregateElement(i);91 92 if (isa_and_nonnull<UndefValue>(Element)) {93 Result <<= BitShift;94 continue;95 }96 97 auto *ElementCI = dyn_cast_or_null<ConstantInt>(Element);98 if (!ElementCI)99 return ConstantExpr::getBitCast(C, DestTy);100 101 Result <<= BitShift;102 Result |= ElementCI->getValue().zext(Result.getBitWidth());103 }104 105 return nullptr;106}107 108/// Constant fold bitcast, symbolically evaluating it with DataLayout.109/// This always returns a non-null constant, but it may be a110/// ConstantExpr if unfoldable.111Constant *FoldBitCast(Constant *C, Type *DestTy, const DataLayout &DL) {112 assert(CastInst::castIsValid(Instruction::BitCast, C, DestTy) &&113 "Invalid constantexpr bitcast!");114 115 // Catch the obvious splat cases.116 if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy, DL))117 return Res;118 119 if (auto *VTy = dyn_cast<VectorType>(C->getType())) {120 // Handle a vector->scalar integer/fp cast.121 if (isa<IntegerType>(DestTy) || DestTy->isFloatingPointTy()) {122 unsigned NumSrcElts = cast<FixedVectorType>(VTy)->getNumElements();123 Type *SrcEltTy = VTy->getElementType();124 125 // If the vector is a vector of floating point, convert it to vector of int126 // to simplify things.127 if (SrcEltTy->isFloatingPointTy()) {128 unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();129 auto *SrcIVTy = FixedVectorType::get(130 IntegerType::get(C->getContext(), FPWidth), NumSrcElts);131 // Ask IR to do the conversion now that #elts line up.132 C = ConstantExpr::getBitCast(C, SrcIVTy);133 }134 135 APInt Result(DL.getTypeSizeInBits(DestTy), 0);136 if (Constant *CE = foldConstVectorToAPInt(Result, DestTy, C,137 SrcEltTy, NumSrcElts, DL))138 return CE;139 140 if (isa<IntegerType>(DestTy))141 return ConstantInt::get(DestTy, Result);142 143 APFloat FP(DestTy->getFltSemantics(), Result);144 return ConstantFP::get(DestTy->getContext(), FP);145 }146 }147 148 // The code below only handles casts to vectors currently.149 auto *DestVTy = dyn_cast<VectorType>(DestTy);150 if (!DestVTy)151 return ConstantExpr::getBitCast(C, DestTy);152 153 // If this is a scalar -> vector cast, convert the input into a <1 x scalar>154 // vector so the code below can handle it uniformly.155 if (!isa<VectorType>(C->getType()) &&156 (isa<ConstantFP>(C) || isa<ConstantInt>(C))) {157 Constant *Ops = C; // don't take the address of C!158 return FoldBitCast(ConstantVector::get(Ops), DestTy, DL);159 }160 161 // Some of what follows may extend to cover scalable vectors but the current162 // implementation is fixed length specific.163 if (!isa<FixedVectorType>(C->getType()))164 return ConstantExpr::getBitCast(C, DestTy);165 166 // If this is a bitcast from constant vector -> vector, fold it.167 if (!isa<ConstantDataVector>(C) && !isa<ConstantVector>(C) &&168 !isa<ConstantInt>(C) && !isa<ConstantFP>(C))169 return ConstantExpr::getBitCast(C, DestTy);170 171 // If the element types match, IR can fold it.172 unsigned NumDstElt = cast<FixedVectorType>(DestVTy)->getNumElements();173 unsigned NumSrcElt = cast<FixedVectorType>(C->getType())->getNumElements();174 if (NumDstElt == NumSrcElt)175 return ConstantExpr::getBitCast(C, DestTy);176 177 Type *SrcEltTy = cast<VectorType>(C->getType())->getElementType();178 Type *DstEltTy = DestVTy->getElementType();179 180 // Otherwise, we're changing the number of elements in a vector, which181 // requires endianness information to do the right thing. For example,182 // bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)183 // folds to (little endian):184 // <4 x i32> <i32 0, i32 0, i32 1, i32 0>185 // and to (big endian):186 // <4 x i32> <i32 0, i32 0, i32 0, i32 1>187 188 // First thing is first. We only want to think about integer here, so if189 // we have something in FP form, recast it as integer.190 if (DstEltTy->isFloatingPointTy()) {191 // Fold to an vector of integers with same size as our FP type.192 unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits();193 auto *DestIVTy = FixedVectorType::get(194 IntegerType::get(C->getContext(), FPWidth), NumDstElt);195 // Recursively handle this integer conversion, if possible.196 C = FoldBitCast(C, DestIVTy, DL);197 198 // Finally, IR can handle this now that #elts line up.199 return ConstantExpr::getBitCast(C, DestTy);200 }201 202 // Okay, we know the destination is integer, if the input is FP, convert203 // it to integer first.204 if (SrcEltTy->isFloatingPointTy()) {205 unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits();206 auto *SrcIVTy = FixedVectorType::get(207 IntegerType::get(C->getContext(), FPWidth), NumSrcElt);208 // Ask IR to do the conversion now that #elts line up.209 C = ConstantExpr::getBitCast(C, SrcIVTy);210 assert((isa<ConstantVector>(C) || // FIXME: Remove ConstantVector.211 isa<ConstantDataVector>(C) || isa<ConstantInt>(C)) &&212 "Constant folding cannot fail for plain fp->int bitcast!");213 }214 215 // Now we know that the input and output vectors are both integer vectors216 // of the same size, and that their #elements is not the same. Do the217 // conversion here, which depends on whether the input or output has218 // more elements.219 bool isLittleEndian = DL.isLittleEndian();220 221 SmallVector<Constant*, 32> Result;222 if (NumDstElt < NumSrcElt) {223 // Handle: bitcast (<4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>)224 Constant *Zero = Constant::getNullValue(DstEltTy);225 unsigned Ratio = NumSrcElt/NumDstElt;226 unsigned SrcBitSize = SrcEltTy->getPrimitiveSizeInBits();227 unsigned SrcElt = 0;228 for (unsigned i = 0; i != NumDstElt; ++i) {229 // Build each element of the result.230 Constant *Elt = Zero;231 unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1);232 for (unsigned j = 0; j != Ratio; ++j) {233 Constant *Src = C->getAggregateElement(SrcElt++);234 if (isa_and_nonnull<UndefValue>(Src))235 Src = Constant::getNullValue(236 cast<VectorType>(C->getType())->getElementType());237 else238 Src = dyn_cast_or_null<ConstantInt>(Src);239 if (!Src) // Reject constantexpr elements.240 return ConstantExpr::getBitCast(C, DestTy);241 242 // Zero extend the element to the right size.243 Src = ConstantFoldCastOperand(Instruction::ZExt, Src, Elt->getType(),244 DL);245 assert(Src && "Constant folding cannot fail on plain integers");246 247 // Shift it to the right place, depending on endianness.248 Src = ConstantFoldBinaryOpOperands(249 Instruction::Shl, Src, ConstantInt::get(Src->getType(), ShiftAmt),250 DL);251 assert(Src && "Constant folding cannot fail on plain integers");252 253 ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize;254 255 // Mix it in.256 Elt = ConstantFoldBinaryOpOperands(Instruction::Or, Elt, Src, DL);257 assert(Elt && "Constant folding cannot fail on plain integers");258 }259 Result.push_back(Elt);260 }261 return ConstantVector::get(Result);262 }263 264 // Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>)265 unsigned Ratio = NumDstElt/NumSrcElt;266 unsigned DstBitSize = DL.getTypeSizeInBits(DstEltTy);267 268 // Loop over each source value, expanding into multiple results.269 for (unsigned i = 0; i != NumSrcElt; ++i) {270 auto *Element = C->getAggregateElement(i);271 272 if (!Element) // Reject constantexpr elements.273 return ConstantExpr::getBitCast(C, DestTy);274 275 if (isa<UndefValue>(Element)) {276 // Correctly Propagate undef values.277 Result.append(Ratio, UndefValue::get(DstEltTy));278 continue;279 }280 281 auto *Src = dyn_cast<ConstantInt>(Element);282 if (!Src)283 return ConstantExpr::getBitCast(C, DestTy);284 285 unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1);286 for (unsigned j = 0; j != Ratio; ++j) {287 // Shift the piece of the value into the right place, depending on288 // endianness.289 APInt Elt = Src->getValue().lshr(ShiftAmt);290 ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize;291 292 // Truncate and remember this piece.293 Result.push_back(ConstantInt::get(DstEltTy, Elt.trunc(DstBitSize)));294 }295 }296 297 return ConstantVector::get(Result);298}299 300} // end anonymous namespace301 302/// If this constant is a constant offset from a global, return the global and303/// the constant. Because of constantexprs, this function is recursive.304bool llvm::IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,305 APInt &Offset, const DataLayout &DL,306 DSOLocalEquivalent **DSOEquiv) {307 if (DSOEquiv)308 *DSOEquiv = nullptr;309 310 // Trivial case, constant is the global.311 if ((GV = dyn_cast<GlobalValue>(C))) {312 unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());313 Offset = APInt(BitWidth, 0);314 return true;315 }316 317 if (auto *FoundDSOEquiv = dyn_cast<DSOLocalEquivalent>(C)) {318 if (DSOEquiv)319 *DSOEquiv = FoundDSOEquiv;320 GV = FoundDSOEquiv->getGlobalValue();321 unsigned BitWidth = DL.getIndexTypeSizeInBits(GV->getType());322 Offset = APInt(BitWidth, 0);323 return true;324 }325 326 // Otherwise, if this isn't a constant expr, bail out.327 auto *CE = dyn_cast<ConstantExpr>(C);328 if (!CE) return false;329 330 // Look through ptr->int and ptr->ptr casts.331 if (CE->getOpcode() == Instruction::PtrToInt ||332 CE->getOpcode() == Instruction::PtrToAddr ||333 CE->getOpcode() == Instruction::BitCast)334 return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, DL,335 DSOEquiv);336 337 // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)338 auto *GEP = dyn_cast<GEPOperator>(CE);339 if (!GEP)340 return false;341 342 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());343 APInt TmpOffset(BitWidth, 0);344 345 // If the base isn't a global+constant, we aren't either.346 if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, TmpOffset, DL,347 DSOEquiv))348 return false;349 350 // Otherwise, add any offset that our operands provide.351 if (!GEP->accumulateConstantOffset(DL, TmpOffset))352 return false;353 354 Offset = TmpOffset;355 return true;356}357 358Constant *llvm::ConstantFoldLoadThroughBitcast(Constant *C, Type *DestTy,359 const DataLayout &DL) {360 do {361 Type *SrcTy = C->getType();362 if (SrcTy == DestTy)363 return C;364 365 TypeSize DestSize = DL.getTypeSizeInBits(DestTy);366 TypeSize SrcSize = DL.getTypeSizeInBits(SrcTy);367 if (!TypeSize::isKnownGE(SrcSize, DestSize))368 return nullptr;369 370 // Catch the obvious splat cases (since all-zeros can coerce non-integral371 // pointers legally).372 if (Constant *Res = ConstantFoldLoadFromUniformValue(C, DestTy, DL))373 return Res;374 375 // If the type sizes are the same and a cast is legal, just directly376 // cast the constant.377 // But be careful not to coerce non-integral pointers illegally.378 if (SrcSize == DestSize &&379 DL.isNonIntegralPointerType(SrcTy->getScalarType()) ==380 DL.isNonIntegralPointerType(DestTy->getScalarType())) {381 Instruction::CastOps Cast = Instruction::BitCast;382 // If we are going from a pointer to int or vice versa, we spell the cast383 // differently.384 if (SrcTy->isIntegerTy() && DestTy->isPointerTy())385 Cast = Instruction::IntToPtr;386 else if (SrcTy->isPointerTy() && DestTy->isIntegerTy())387 Cast = Instruction::PtrToInt;388 389 if (CastInst::castIsValid(Cast, C, DestTy))390 return ConstantFoldCastOperand(Cast, C, DestTy, DL);391 }392 393 // If this isn't an aggregate type, there is nothing we can do to drill down394 // and find a bitcastable constant.395 if (!SrcTy->isAggregateType() && !SrcTy->isVectorTy())396 return nullptr;397 398 // We're simulating a load through a pointer that was bitcast to point to399 // a different type, so we can try to walk down through the initial400 // elements of an aggregate to see if some part of the aggregate is401 // castable to implement the "load" semantic model.402 if (SrcTy->isStructTy()) {403 // Struct types might have leading zero-length elements like [0 x i32],404 // which are certainly not what we are looking for, so skip them.405 unsigned Elem = 0;406 Constant *ElemC;407 do {408 ElemC = C->getAggregateElement(Elem++);409 } while (ElemC && DL.getTypeSizeInBits(ElemC->getType()).isZero());410 C = ElemC;411 } else {412 // For non-byte-sized vector elements, the first element is not413 // necessarily located at the vector base address.414 if (auto *VT = dyn_cast<VectorType>(SrcTy))415 if (!DL.typeSizeEqualsStoreSize(VT->getElementType()))416 return nullptr;417 418 C = C->getAggregateElement(0u);419 }420 } while (C);421 422 return nullptr;423}424 425namespace {426 427/// Recursive helper to read bits out of global. C is the constant being copied428/// out of. ByteOffset is an offset into C. CurPtr is the pointer to copy429/// results into and BytesLeft is the number of bytes left in430/// the CurPtr buffer. DL is the DataLayout.431bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned char *CurPtr,432 unsigned BytesLeft, const DataLayout &DL) {433 assert(ByteOffset <= DL.getTypeAllocSize(C->getType()) &&434 "Out of range access");435 436 // Reading type padding, return zero.437 if (ByteOffset >= DL.getTypeStoreSize(C->getType()))438 return true;439 440 // If this element is zero or undefined, we can just return since *CurPtr is441 // zero initialized.442 if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))443 return true;444 445 if (auto *CI = dyn_cast<ConstantInt>(C)) {446 if ((CI->getBitWidth() & 7) != 0)447 return false;448 const APInt &Val = CI->getValue();449 unsigned IntBytes = unsigned(CI->getBitWidth()/8);450 451 for (unsigned i = 0; i != BytesLeft && ByteOffset != IntBytes; ++i) {452 unsigned n = ByteOffset;453 if (!DL.isLittleEndian())454 n = IntBytes - n - 1;455 CurPtr[i] = Val.extractBits(8, n * 8).getZExtValue();456 ++ByteOffset;457 }458 return true;459 }460 461 if (auto *CFP = dyn_cast<ConstantFP>(C)) {462 if (CFP->getType()->isDoubleTy()) {463 C = FoldBitCast(C, Type::getInt64Ty(C->getContext()), DL);464 return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);465 }466 if (CFP->getType()->isFloatTy()){467 C = FoldBitCast(C, Type::getInt32Ty(C->getContext()), DL);468 return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);469 }470 if (CFP->getType()->isHalfTy()){471 C = FoldBitCast(C, Type::getInt16Ty(C->getContext()), DL);472 return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, DL);473 }474 return false;475 }476 477 if (auto *CS = dyn_cast<ConstantStruct>(C)) {478 const StructLayout *SL = DL.getStructLayout(CS->getType());479 unsigned Index = SL->getElementContainingOffset(ByteOffset);480 uint64_t CurEltOffset = SL->getElementOffset(Index);481 ByteOffset -= CurEltOffset;482 483 while (true) {484 // If the element access is to the element itself and not to tail padding,485 // read the bytes from the element.486 uint64_t EltSize = DL.getTypeAllocSize(CS->getOperand(Index)->getType());487 488 if (ByteOffset < EltSize &&489 !ReadDataFromGlobal(CS->getOperand(Index), ByteOffset, CurPtr,490 BytesLeft, DL))491 return false;492 493 ++Index;494 495 // Check to see if we read from the last struct element, if so we're done.496 if (Index == CS->getType()->getNumElements())497 return true;498 499 // If we read all of the bytes we needed from this element we're done.500 uint64_t NextEltOffset = SL->getElementOffset(Index);501 502 if (BytesLeft <= NextEltOffset - CurEltOffset - ByteOffset)503 return true;504 505 // Move to the next element of the struct.506 CurPtr += NextEltOffset - CurEltOffset - ByteOffset;507 BytesLeft -= NextEltOffset - CurEltOffset - ByteOffset;508 ByteOffset = 0;509 CurEltOffset = NextEltOffset;510 }511 // not reached.512 }513 514 if (isa<ConstantArray>(C) || isa<ConstantVector>(C) ||515 isa<ConstantDataSequential>(C)) {516 uint64_t NumElts, EltSize;517 Type *EltTy;518 if (auto *AT = dyn_cast<ArrayType>(C->getType())) {519 NumElts = AT->getNumElements();520 EltTy = AT->getElementType();521 EltSize = DL.getTypeAllocSize(EltTy);522 } else {523 NumElts = cast<FixedVectorType>(C->getType())->getNumElements();524 EltTy = cast<FixedVectorType>(C->getType())->getElementType();525 // TODO: For non-byte-sized vectors, current implementation assumes there is526 // padding to the next byte boundary between elements.527 if (!DL.typeSizeEqualsStoreSize(EltTy))528 return false;529 530 EltSize = DL.getTypeStoreSize(EltTy);531 }532 uint64_t Index = ByteOffset / EltSize;533 uint64_t Offset = ByteOffset - Index * EltSize;534 535 for (; Index != NumElts; ++Index) {536 if (!ReadDataFromGlobal(C->getAggregateElement(Index), Offset, CurPtr,537 BytesLeft, DL))538 return false;539 540 uint64_t BytesWritten = EltSize - Offset;541 assert(BytesWritten <= EltSize && "Not indexing into this element?");542 if (BytesWritten >= BytesLeft)543 return true;544 545 Offset = 0;546 BytesLeft -= BytesWritten;547 CurPtr += BytesWritten;548 }549 return true;550 }551 552 if (auto *CE = dyn_cast<ConstantExpr>(C)) {553 if (CE->getOpcode() == Instruction::IntToPtr &&554 CE->getOperand(0)->getType() == DL.getIntPtrType(CE->getType())) {555 return ReadDataFromGlobal(CE->getOperand(0), ByteOffset, CurPtr,556 BytesLeft, DL);557 }558 }559 560 // Otherwise, unknown initializer type.561 return false;562}563 564Constant *FoldReinterpretLoadFromConst(Constant *C, Type *LoadTy,565 int64_t Offset, const DataLayout &DL) {566 // Bail out early. Not expect to load from scalable global variable.567 if (isa<ScalableVectorType>(LoadTy))568 return nullptr;569 570 auto *IntType = dyn_cast<IntegerType>(LoadTy);571 572 // If this isn't an integer load we can't fold it directly.573 if (!IntType) {574 // If this is a non-integer load, we can try folding it as an int load and575 // then bitcast the result. This can be useful for union cases. Note576 // that address spaces don't matter here since we're not going to result in577 // an actual new load.578 if (!LoadTy->isFloatingPointTy() && !LoadTy->isPointerTy() &&579 !LoadTy->isVectorTy())580 return nullptr;581 582 Type *MapTy = Type::getIntNTy(C->getContext(),583 DL.getTypeSizeInBits(LoadTy).getFixedValue());584 if (Constant *Res = FoldReinterpretLoadFromConst(C, MapTy, Offset, DL)) {585 if (Res->isNullValue() && !LoadTy->isX86_AMXTy())586 // Materializing a zero can be done trivially without a bitcast587 return Constant::getNullValue(LoadTy);588 Type *CastTy = LoadTy->isPtrOrPtrVectorTy() ? DL.getIntPtrType(LoadTy) : LoadTy;589 Res = FoldBitCast(Res, CastTy, DL);590 if (LoadTy->isPtrOrPtrVectorTy()) {591 // For vector of pointer, we needed to first convert to a vector of integer, then do vector inttoptr592 if (Res->isNullValue() && !LoadTy->isX86_AMXTy())593 return Constant::getNullValue(LoadTy);594 if (DL.isNonIntegralPointerType(LoadTy->getScalarType()))595 // Be careful not to replace a load of an addrspace value with an inttoptr here596 return nullptr;597 Res = ConstantExpr::getIntToPtr(Res, LoadTy);598 }599 return Res;600 }601 return nullptr;602 }603 604 unsigned BytesLoaded = (IntType->getBitWidth() + 7) / 8;605 if (BytesLoaded > 32 || BytesLoaded == 0)606 return nullptr;607 608 // If we're not accessing anything in this constant, the result is undefined.609 if (Offset <= -1 * static_cast<int64_t>(BytesLoaded))610 return PoisonValue::get(IntType);611 612 // TODO: We should be able to support scalable types.613 TypeSize InitializerSize = DL.getTypeAllocSize(C->getType());614 if (InitializerSize.isScalable())615 return nullptr;616 617 // If we're not accessing anything in this constant, the result is undefined.618 if (Offset >= (int64_t)InitializerSize.getFixedValue())619 return PoisonValue::get(IntType);620 621 unsigned char RawBytes[32] = {0};622 unsigned char *CurPtr = RawBytes;623 unsigned BytesLeft = BytesLoaded;624 625 // If we're loading off the beginning of the global, some bytes may be valid.626 if (Offset < 0) {627 CurPtr += -Offset;628 BytesLeft += Offset;629 Offset = 0;630 }631 632 if (!ReadDataFromGlobal(C, Offset, CurPtr, BytesLeft, DL))633 return nullptr;634 635 APInt ResultVal = APInt(IntType->getBitWidth(), 0);636 if (DL.isLittleEndian()) {637 ResultVal = RawBytes[BytesLoaded - 1];638 for (unsigned i = 1; i != BytesLoaded; ++i) {639 ResultVal <<= 8;640 ResultVal |= RawBytes[BytesLoaded - 1 - i];641 }642 } else {643 ResultVal = RawBytes[0];644 for (unsigned i = 1; i != BytesLoaded; ++i) {645 ResultVal <<= 8;646 ResultVal |= RawBytes[i];647 }648 }649 650 return ConstantInt::get(IntType->getContext(), ResultVal);651}652 653} // anonymous namespace654 655// If GV is a constant with an initializer read its representation starting656// at Offset and return it as a constant array of unsigned char. Otherwise657// return null.658Constant *llvm::ReadByteArrayFromGlobal(const GlobalVariable *GV,659 uint64_t Offset) {660 if (!GV->isConstant() || !GV->hasDefinitiveInitializer())661 return nullptr;662 663 const DataLayout &DL = GV->getDataLayout();664 Constant *Init = const_cast<Constant *>(GV->getInitializer());665 TypeSize InitSize = DL.getTypeAllocSize(Init->getType());666 if (InitSize < Offset)667 return nullptr;668 669 uint64_t NBytes = InitSize - Offset;670 if (NBytes > UINT16_MAX)671 // Bail for large initializers in excess of 64K to avoid allocating672 // too much memory.673 // Offset is assumed to be less than or equal than InitSize (this674 // is enforced in ReadDataFromGlobal).675 return nullptr;676 677 SmallVector<unsigned char, 256> RawBytes(static_cast<size_t>(NBytes));678 unsigned char *CurPtr = RawBytes.data();679 680 if (!ReadDataFromGlobal(Init, Offset, CurPtr, NBytes, DL))681 return nullptr;682 683 return ConstantDataArray::get(GV->getContext(), RawBytes);684}685 686/// If this Offset points exactly to the start of an aggregate element, return687/// that element, otherwise return nullptr.688Constant *getConstantAtOffset(Constant *Base, APInt Offset,689 const DataLayout &DL) {690 if (Offset.isZero())691 return Base;692 693 if (!isa<ConstantAggregate>(Base) && !isa<ConstantDataSequential>(Base))694 return nullptr;695 696 Type *ElemTy = Base->getType();697 SmallVector<APInt> Indices = DL.getGEPIndicesForOffset(ElemTy, Offset);698 if (!Offset.isZero() || !Indices[0].isZero())699 return nullptr;700 701 Constant *C = Base;702 for (const APInt &Index : drop_begin(Indices)) {703 if (Index.isNegative() || Index.getActiveBits() >= 32)704 return nullptr;705 706 C = C->getAggregateElement(Index.getZExtValue());707 if (!C)708 return nullptr;709 }710 711 return C;712}713 714Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,715 const APInt &Offset,716 const DataLayout &DL) {717 if (Constant *AtOffset = getConstantAtOffset(C, Offset, DL))718 if (Constant *Result = ConstantFoldLoadThroughBitcast(AtOffset, Ty, DL))719 return Result;720 721 // Explicitly check for out-of-bounds access, so we return poison even if the722 // constant is a uniform value.723 TypeSize Size = DL.getTypeAllocSize(C->getType());724 if (!Size.isScalable() && Offset.sge(Size.getFixedValue()))725 return PoisonValue::get(Ty);726 727 // Try an offset-independent fold of a uniform value.728 if (Constant *Result = ConstantFoldLoadFromUniformValue(C, Ty, DL))729 return Result;730 731 // Try hard to fold loads from bitcasted strange and non-type-safe things.732 if (Offset.getSignificantBits() <= 64)733 if (Constant *Result =734 FoldReinterpretLoadFromConst(C, Ty, Offset.getSExtValue(), DL))735 return Result;736 737 return nullptr;738}739 740Constant *llvm::ConstantFoldLoadFromConst(Constant *C, Type *Ty,741 const DataLayout &DL) {742 return ConstantFoldLoadFromConst(C, Ty, APInt(64, 0), DL);743}744 745Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,746 APInt Offset,747 const DataLayout &DL) {748 // We can only fold loads from constant globals with a definitive initializer.749 // Check this upfront, to skip expensive offset calculations.750 auto *GV = dyn_cast<GlobalVariable>(getUnderlyingObject(C));751 if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer())752 return nullptr;753 754 C = cast<Constant>(C->stripAndAccumulateConstantOffsets(755 DL, Offset, /* AllowNonInbounds */ true));756 757 if (C == GV)758 if (Constant *Result = ConstantFoldLoadFromConst(GV->getInitializer(), Ty,759 Offset, DL))760 return Result;761 762 // If this load comes from anywhere in a uniform constant global, the value763 // is always the same, regardless of the loaded offset.764 return ConstantFoldLoadFromUniformValue(GV->getInitializer(), Ty, DL);765}766 767Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty,768 const DataLayout &DL) {769 APInt Offset(DL.getIndexTypeSizeInBits(C->getType()), 0);770 return ConstantFoldLoadFromConstPtr(C, Ty, std::move(Offset), DL);771}772 773Constant *llvm::ConstantFoldLoadFromUniformValue(Constant *C, Type *Ty,774 const DataLayout &DL) {775 if (isa<PoisonValue>(C))776 return PoisonValue::get(Ty);777 if (isa<UndefValue>(C))778 return UndefValue::get(Ty);779 // If padding is needed when storing C to memory, then it isn't considered as780 // uniform.781 if (!DL.typeSizeEqualsStoreSize(C->getType()))782 return nullptr;783 if (C->isNullValue() && !Ty->isX86_AMXTy())784 return Constant::getNullValue(Ty);785 if (C->isAllOnesValue() &&786 (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()))787 return Constant::getAllOnesValue(Ty);788 return nullptr;789}790 791namespace {792 793/// One of Op0/Op1 is a constant expression.794/// Attempt to symbolically evaluate the result of a binary operator merging795/// these together. If target data info is available, it is provided as DL,796/// otherwise DL is null.797Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, Constant *Op1,798 const DataLayout &DL) {799 // SROA800 801 // Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.802 // Fold (lshr (or X, Y), 32) -> (lshr [X/Y], 32) if one doesn't contribute803 // bits.804 805 if (Opc == Instruction::And) {806 KnownBits Known0 = computeKnownBits(Op0, DL);807 KnownBits Known1 = computeKnownBits(Op1, DL);808 if ((Known1.One | Known0.Zero).isAllOnes()) {809 // All the bits of Op0 that the 'and' could be masking are already zero.810 return Op0;811 }812 if ((Known0.One | Known1.Zero).isAllOnes()) {813 // All the bits of Op1 that the 'and' could be masking are already zero.814 return Op1;815 }816 817 Known0 &= Known1;818 if (Known0.isConstant())819 return ConstantInt::get(Op0->getType(), Known0.getConstant());820 }821 822 // If the constant expr is something like &A[123] - &A[4].f, fold this into a823 // constant. This happens frequently when iterating over a global array.824 if (Opc == Instruction::Sub) {825 GlobalValue *GV1, *GV2;826 APInt Offs1, Offs2;827 828 if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, DL))829 if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, DL) && GV1 == GV2) {830 unsigned OpSize = DL.getTypeSizeInBits(Op0->getType());831 832 // (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.833 // PtrToInt may change the bitwidth so we have convert to the right size834 // first.835 return ConstantInt::get(Op0->getType(), Offs1.zextOrTrunc(OpSize) -836 Offs2.zextOrTrunc(OpSize));837 }838 }839 840 return nullptr;841}842 843/// If array indices are not pointer-sized integers, explicitly cast them so844/// that they aren't implicitly casted by the getelementptr.845Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,846 Type *ResultTy, GEPNoWrapFlags NW,847 std::optional<ConstantRange> InRange,848 const DataLayout &DL, const TargetLibraryInfo *TLI) {849 Type *IntIdxTy = DL.getIndexType(ResultTy);850 Type *IntIdxScalarTy = IntIdxTy->getScalarType();851 852 bool Any = false;853 SmallVector<Constant*, 32> NewIdxs;854 for (unsigned i = 1, e = Ops.size(); i != e; ++i) {855 if ((i == 1 ||856 !isa<StructType>(GetElementPtrInst::getIndexedType(857 SrcElemTy, Ops.slice(1, i - 1)))) &&858 Ops[i]->getType()->getScalarType() != IntIdxScalarTy) {859 Any = true;860 Type *NewType =861 Ops[i]->getType()->isVectorTy() ? IntIdxTy : IntIdxScalarTy;862 Constant *NewIdx = ConstantFoldCastOperand(863 CastInst::getCastOpcode(Ops[i], true, NewType, true), Ops[i], NewType,864 DL);865 if (!NewIdx)866 return nullptr;867 NewIdxs.push_back(NewIdx);868 } else869 NewIdxs.push_back(Ops[i]);870 }871 872 if (!Any)873 return nullptr;874 875 Constant *C =876 ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], NewIdxs, NW, InRange);877 return ConstantFoldConstant(C, DL, TLI);878}879 880/// If we can symbolically evaluate the GEP constant expression, do so.881Constant *SymbolicallyEvaluateGEP(const GEPOperator *GEP,882 ArrayRef<Constant *> Ops,883 const DataLayout &DL,884 const TargetLibraryInfo *TLI) {885 Type *SrcElemTy = GEP->getSourceElementType();886 Type *ResTy = GEP->getType();887 if (!SrcElemTy->isSized() || isa<ScalableVectorType>(SrcElemTy))888 return nullptr;889 890 if (Constant *C = CastGEPIndices(SrcElemTy, Ops, ResTy, GEP->getNoWrapFlags(),891 GEP->getInRange(), DL, TLI))892 return C;893 894 Constant *Ptr = Ops[0];895 if (!Ptr->getType()->isPointerTy())896 return nullptr;897 898 Type *IntIdxTy = DL.getIndexType(Ptr->getType());899 900 for (unsigned i = 1, e = Ops.size(); i != e; ++i)901 if (!isa<ConstantInt>(Ops[i]) || !Ops[i]->getType()->isIntegerTy())902 return nullptr;903 904 unsigned BitWidth = DL.getTypeSizeInBits(IntIdxTy);905 APInt Offset = APInt(906 BitWidth,907 DL.getIndexedOffsetInType(908 SrcElemTy, ArrayRef((Value *const *)Ops.data() + 1, Ops.size() - 1)),909 /*isSigned=*/true, /*implicitTrunc=*/true);910 911 std::optional<ConstantRange> InRange = GEP->getInRange();912 if (InRange)913 InRange = InRange->sextOrTrunc(BitWidth);914 915 // If this is a GEP of a GEP, fold it all into a single GEP.916 GEPNoWrapFlags NW = GEP->getNoWrapFlags();917 bool Overflow = false;918 while (auto *GEP = dyn_cast<GEPOperator>(Ptr)) {919 NW &= GEP->getNoWrapFlags();920 921 SmallVector<Value *, 4> NestedOps(llvm::drop_begin(GEP->operands()));922 923 // Do not try the incorporate the sub-GEP if some index is not a number.924 bool AllConstantInt = true;925 for (Value *NestedOp : NestedOps)926 if (!isa<ConstantInt>(NestedOp)) {927 AllConstantInt = false;928 break;929 }930 if (!AllConstantInt)931 break;932 933 // Adjust inrange offset and intersect inrange attributes934 if (auto GEPRange = GEP->getInRange()) {935 auto AdjustedGEPRange = GEPRange->sextOrTrunc(BitWidth).subtract(Offset);936 InRange =937 InRange ? InRange->intersectWith(AdjustedGEPRange) : AdjustedGEPRange;938 }939 940 Ptr = cast<Constant>(GEP->getOperand(0));941 SrcElemTy = GEP->getSourceElementType();942 Offset = Offset.sadd_ov(943 APInt(BitWidth, DL.getIndexedOffsetInType(SrcElemTy, NestedOps),944 /*isSigned=*/true, /*implicitTrunc=*/true),945 Overflow);946 }947 948 // Preserving nusw (without inbounds) also requires that the offset949 // additions did not overflow.950 if (NW.hasNoUnsignedSignedWrap() && !NW.isInBounds() && Overflow)951 NW = NW.withoutNoUnsignedSignedWrap();952 953 // If the base value for this address is a literal integer value, fold the954 // getelementptr to the resulting integer value casted to the pointer type.955 APInt BaseIntVal(DL.getPointerTypeSizeInBits(Ptr->getType()), 0);956 if (auto *CE = dyn_cast<ConstantExpr>(Ptr)) {957 if (CE->getOpcode() == Instruction::IntToPtr) {958 if (auto *Base = dyn_cast<ConstantInt>(CE->getOperand(0)))959 BaseIntVal = Base->getValue().zextOrTrunc(BaseIntVal.getBitWidth());960 }961 }962 963 if ((Ptr->isNullValue() || BaseIntVal != 0) &&964 !DL.mustNotIntroduceIntToPtr(Ptr->getType())) {965 966 // If the index size is smaller than the pointer size, add to the low967 // bits only.968 BaseIntVal.insertBits(BaseIntVal.trunc(BitWidth) + Offset, 0);969 Constant *C = ConstantInt::get(Ptr->getContext(), BaseIntVal);970 return ConstantExpr::getIntToPtr(C, ResTy);971 }972 973 // Try to infer inbounds for GEPs of globals.974 if (!NW.isInBounds() && Offset.isNonNegative()) {975 bool CanBeNull, CanBeFreed;976 uint64_t DerefBytes =977 Ptr->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed);978 if (DerefBytes != 0 && !CanBeNull && Offset.sle(DerefBytes))979 NW |= GEPNoWrapFlags::inBounds();980 }981 982 // nusw + nneg -> nuw983 if (NW.hasNoUnsignedSignedWrap() && Offset.isNonNegative())984 NW |= GEPNoWrapFlags::noUnsignedWrap();985 986 // Otherwise canonicalize this to a single ptradd.987 LLVMContext &Ctx = Ptr->getContext();988 return ConstantExpr::getGetElementPtr(Type::getInt8Ty(Ctx), Ptr,989 ConstantInt::get(Ctx, Offset), NW,990 InRange);991}992 993/// Attempt to constant fold an instruction with the994/// specified opcode and operands. If successful, the constant result is995/// returned, if not, null is returned. Note that this function can fail when996/// attempting to fold instructions like loads and stores, which have no997/// constant expression form.998Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode,999 ArrayRef<Constant *> Ops,1000 const DataLayout &DL,1001 const TargetLibraryInfo *TLI,1002 bool AllowNonDeterministic) {1003 Type *DestTy = InstOrCE->getType();1004 1005 if (Instruction::isUnaryOp(Opcode))1006 return ConstantFoldUnaryOpOperand(Opcode, Ops[0], DL);1007 1008 if (Instruction::isBinaryOp(Opcode)) {1009 switch (Opcode) {1010 default:1011 break;1012 case Instruction::FAdd:1013 case Instruction::FSub:1014 case Instruction::FMul:1015 case Instruction::FDiv:1016 case Instruction::FRem:1017 // Handle floating point instructions separately to account for denormals1018 // TODO: If a constant expression is being folded rather than an1019 // instruction, denormals will not be flushed/treated as zero1020 if (const auto *I = dyn_cast<Instruction>(InstOrCE)) {1021 return ConstantFoldFPInstOperands(Opcode, Ops[0], Ops[1], DL, I,1022 AllowNonDeterministic);1023 }1024 }1025 return ConstantFoldBinaryOpOperands(Opcode, Ops[0], Ops[1], DL);1026 }1027 1028 if (Instruction::isCast(Opcode))1029 return ConstantFoldCastOperand(Opcode, Ops[0], DestTy, DL);1030 1031 if (auto *GEP = dyn_cast<GEPOperator>(InstOrCE)) {1032 Type *SrcElemTy = GEP->getSourceElementType();1033 if (!ConstantExpr::isSupportedGetElementPtr(SrcElemTy))1034 return nullptr;1035 1036 if (Constant *C = SymbolicallyEvaluateGEP(GEP, Ops, DL, TLI))1037 return C;1038 1039 return ConstantExpr::getGetElementPtr(SrcElemTy, Ops[0], Ops.slice(1),1040 GEP->getNoWrapFlags(),1041 GEP->getInRange());1042 }1043 1044 if (auto *CE = dyn_cast<ConstantExpr>(InstOrCE))1045 return CE->getWithOperands(Ops);1046 1047 switch (Opcode) {1048 default: return nullptr;1049 case Instruction::ICmp:1050 case Instruction::FCmp: {1051 auto *C = cast<CmpInst>(InstOrCE);1052 return ConstantFoldCompareInstOperands(C->getPredicate(), Ops[0], Ops[1],1053 DL, TLI, C);1054 }1055 case Instruction::Freeze:1056 return isGuaranteedNotToBeUndefOrPoison(Ops[0]) ? Ops[0] : nullptr;1057 case Instruction::Call:1058 if (auto *F = dyn_cast<Function>(Ops.back())) {1059 const auto *Call = cast<CallBase>(InstOrCE);1060 if (canConstantFoldCallTo(Call, F))1061 return ConstantFoldCall(Call, F, Ops.slice(0, Ops.size() - 1), TLI,1062 AllowNonDeterministic);1063 }1064 return nullptr;1065 case Instruction::Select:1066 return ConstantFoldSelectInstruction(Ops[0], Ops[1], Ops[2]);1067 case Instruction::ExtractElement:1068 return ConstantExpr::getExtractElement(Ops[0], Ops[1]);1069 case Instruction::ExtractValue:1070 return ConstantFoldExtractValueInstruction(1071 Ops[0], cast<ExtractValueInst>(InstOrCE)->getIndices());1072 case Instruction::InsertElement:1073 return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);1074 case Instruction::InsertValue:1075 return ConstantFoldInsertValueInstruction(1076 Ops[0], Ops[1], cast<InsertValueInst>(InstOrCE)->getIndices());1077 case Instruction::ShuffleVector:1078 return ConstantExpr::getShuffleVector(1079 Ops[0], Ops[1], cast<ShuffleVectorInst>(InstOrCE)->getShuffleMask());1080 case Instruction::Load: {1081 const auto *LI = dyn_cast<LoadInst>(InstOrCE);1082 if (LI->isVolatile())1083 return nullptr;1084 return ConstantFoldLoadFromConstPtr(Ops[0], LI->getType(), DL);1085 }1086 }1087}1088 1089} // end anonymous namespace1090 1091//===----------------------------------------------------------------------===//1092// Constant Folding public APIs1093//===----------------------------------------------------------------------===//1094 1095namespace {1096 1097Constant *1098ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,1099 const TargetLibraryInfo *TLI,1100 SmallDenseMap<Constant *, Constant *> &FoldedOps) {1101 if (!isa<ConstantVector>(C) && !isa<ConstantExpr>(C))1102 return const_cast<Constant *>(C);1103 1104 SmallVector<Constant *, 8> Ops;1105 for (const Use &OldU : C->operands()) {1106 Constant *OldC = cast<Constant>(&OldU);1107 Constant *NewC = OldC;1108 // Recursively fold the ConstantExpr's operands. If we have already folded1109 // a ConstantExpr, we don't have to process it again.1110 if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {1111 auto It = FoldedOps.find(OldC);1112 if (It == FoldedOps.end()) {1113 NewC = ConstantFoldConstantImpl(OldC, DL, TLI, FoldedOps);1114 FoldedOps.insert({OldC, NewC});1115 } else {1116 NewC = It->second;1117 }1118 }1119 Ops.push_back(NewC);1120 }1121 1122 if (auto *CE = dyn_cast<ConstantExpr>(C)) {1123 if (Constant *Res = ConstantFoldInstOperandsImpl(1124 CE, CE->getOpcode(), Ops, DL, TLI, /*AllowNonDeterministic=*/true))1125 return Res;1126 return const_cast<Constant *>(C);1127 }1128 1129 assert(isa<ConstantVector>(C));1130 return ConstantVector::get(Ops);1131}1132 1133} // end anonymous namespace1134 1135Constant *llvm::ConstantFoldInstruction(const Instruction *I,1136 const DataLayout &DL,1137 const TargetLibraryInfo *TLI) {1138 // Handle PHI nodes quickly here...1139 if (auto *PN = dyn_cast<PHINode>(I)) {1140 Constant *CommonValue = nullptr;1141 1142 SmallDenseMap<Constant *, Constant *> FoldedOps;1143 for (Value *Incoming : PN->incoming_values()) {1144 // If the incoming value is undef then skip it. Note that while we could1145 // skip the value if it is equal to the phi node itself we choose not to1146 // because that would break the rule that constant folding only applies if1147 // all operands are constants.1148 if (isa<UndefValue>(Incoming))1149 continue;1150 // If the incoming value is not a constant, then give up.1151 auto *C = dyn_cast<Constant>(Incoming);1152 if (!C)1153 return nullptr;1154 // Fold the PHI's operands.1155 C = ConstantFoldConstantImpl(C, DL, TLI, FoldedOps);1156 // If the incoming value is a different constant to1157 // the one we saw previously, then give up.1158 if (CommonValue && C != CommonValue)1159 return nullptr;1160 CommonValue = C;1161 }1162 1163 // If we reach here, all incoming values are the same constant or undef.1164 return CommonValue ? CommonValue : UndefValue::get(PN->getType());1165 }1166 1167 // Scan the operand list, checking to see if they are all constants, if so,1168 // hand off to ConstantFoldInstOperandsImpl.1169 if (!all_of(I->operands(), [](const Use &U) { return isa<Constant>(U); }))1170 return nullptr;1171 1172 SmallDenseMap<Constant *, Constant *> FoldedOps;1173 SmallVector<Constant *, 8> Ops;1174 for (const Use &OpU : I->operands()) {1175 auto *Op = cast<Constant>(&OpU);1176 // Fold the Instruction's operands.1177 Op = ConstantFoldConstantImpl(Op, DL, TLI, FoldedOps);1178 Ops.push_back(Op);1179 }1180 1181 return ConstantFoldInstOperands(I, Ops, DL, TLI);1182}1183 1184Constant *llvm::ConstantFoldConstant(const Constant *C, const DataLayout &DL,1185 const TargetLibraryInfo *TLI) {1186 SmallDenseMap<Constant *, Constant *> FoldedOps;1187 return ConstantFoldConstantImpl(C, DL, TLI, FoldedOps);1188}1189 1190Constant *llvm::ConstantFoldInstOperands(const Instruction *I,1191 ArrayRef<Constant *> Ops,1192 const DataLayout &DL,1193 const TargetLibraryInfo *TLI,1194 bool AllowNonDeterministic) {1195 return ConstantFoldInstOperandsImpl(I, I->getOpcode(), Ops, DL, TLI,1196 AllowNonDeterministic);1197}1198 1199Constant *llvm::ConstantFoldCompareInstOperands(1200 unsigned IntPredicate, Constant *Ops0, Constant *Ops1, const DataLayout &DL,1201 const TargetLibraryInfo *TLI, const Instruction *I) {1202 CmpInst::Predicate Predicate = (CmpInst::Predicate)IntPredicate;1203 // fold: icmp (inttoptr x), null -> icmp x, 01204 // fold: icmp null, (inttoptr x) -> icmp 0, x1205 // fold: icmp (ptrtoint x), 0 -> icmp x, null1206 // fold: icmp 0, (ptrtoint x) -> icmp null, x1207 // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y1208 // fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y1209 //1210 // FIXME: The following comment is out of data and the DataLayout is here now.1211 // ConstantExpr::getCompare cannot do this, because it doesn't have DL1212 // around to know if bit truncation is happening.1213 if (auto *CE0 = dyn_cast<ConstantExpr>(Ops0)) {1214 if (Ops1->isNullValue()) {1215 if (CE0->getOpcode() == Instruction::IntToPtr) {1216 Type *IntPtrTy = DL.getIntPtrType(CE0->getType());1217 // Convert the integer value to the right size to ensure we get the1218 // proper extension or truncation.1219 if (Constant *C = ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,1220 /*IsSigned*/ false, DL)) {1221 Constant *Null = Constant::getNullValue(C->getType());1222 return ConstantFoldCompareInstOperands(Predicate, C, Null, DL, TLI);1223 }1224 }1225 1226 // Only do this transformation if the int is intptrty in size, otherwise1227 // there is a truncation or extension that we aren't modeling.1228 if (CE0->getOpcode() == Instruction::PtrToInt) {1229 Type *IntPtrTy = DL.getIntPtrType(CE0->getOperand(0)->getType());1230 if (CE0->getType() == IntPtrTy) {1231 Constant *C = CE0->getOperand(0);1232 Constant *Null = Constant::getNullValue(C->getType());1233 return ConstantFoldCompareInstOperands(Predicate, C, Null, DL, TLI);1234 }1235 }1236 }1237 1238 if (auto *CE1 = dyn_cast<ConstantExpr>(Ops1)) {1239 if (CE0->getOpcode() == CE1->getOpcode()) {1240 if (CE0->getOpcode() == Instruction::IntToPtr) {1241 Type *IntPtrTy = DL.getIntPtrType(CE0->getType());1242 1243 // Convert the integer value to the right size to ensure we get the1244 // proper extension or truncation.1245 Constant *C0 = ConstantFoldIntegerCast(CE0->getOperand(0), IntPtrTy,1246 /*IsSigned*/ false, DL);1247 Constant *C1 = ConstantFoldIntegerCast(CE1->getOperand(0), IntPtrTy,1248 /*IsSigned*/ false, DL);1249 if (C0 && C1)1250 return ConstantFoldCompareInstOperands(Predicate, C0, C1, DL, TLI);1251 }1252 1253 // Only do this transformation if the int is intptrty in size, otherwise1254 // there is a truncation or extension that we aren't modeling.1255 if (CE0->getOpcode() == Instruction::PtrToInt) {1256 Type *IntPtrTy = DL.getIntPtrType(CE0->getOperand(0)->getType());1257 if (CE0->getType() == IntPtrTy &&1258 CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType()) {1259 return ConstantFoldCompareInstOperands(1260 Predicate, CE0->getOperand(0), CE1->getOperand(0), DL, TLI);1261 }1262 }1263 }1264 }1265 1266 // Convert pointer comparison (base+offset1) pred (base+offset2) into1267 // offset1 pred offset2, for the case where the offset is inbounds. This1268 // only works for equality and unsigned comparison, as inbounds permits1269 // crossing the sign boundary. However, the offset comparison itself is1270 // signed.1271 if (Ops0->getType()->isPointerTy() && !ICmpInst::isSigned(Predicate)) {1272 unsigned IndexWidth = DL.getIndexTypeSizeInBits(Ops0->getType());1273 APInt Offset0(IndexWidth, 0);1274 bool IsEqPred = ICmpInst::isEquality(Predicate);1275 Value *Stripped0 = Ops0->stripAndAccumulateConstantOffsets(1276 DL, Offset0, /*AllowNonInbounds=*/IsEqPred,1277 /*AllowInvariantGroup=*/false, /*ExternalAnalysis=*/nullptr,1278 /*LookThroughIntToPtr=*/IsEqPred);1279 APInt Offset1(IndexWidth, 0);1280 Value *Stripped1 = Ops1->stripAndAccumulateConstantOffsets(1281 DL, Offset1, /*AllowNonInbounds=*/IsEqPred,1282 /*AllowInvariantGroup=*/false, /*ExternalAnalysis=*/nullptr,1283 /*LookThroughIntToPtr=*/IsEqPred);1284 if (Stripped0 == Stripped1)1285 return ConstantInt::getBool(1286 Ops0->getContext(),1287 ICmpInst::compare(Offset0, Offset1,1288 ICmpInst::getSignedPredicate(Predicate)));1289 }1290 } else if (isa<ConstantExpr>(Ops1)) {1291 // If RHS is a constant expression, but the left side isn't, swap the1292 // operands and try again.1293 Predicate = ICmpInst::getSwappedPredicate(Predicate);1294 return ConstantFoldCompareInstOperands(Predicate, Ops1, Ops0, DL, TLI);1295 }1296 1297 if (CmpInst::isFPPredicate(Predicate)) {1298 // Flush any denormal constant float input according to denormal handling1299 // mode.1300 Ops0 = FlushFPConstant(Ops0, I, /*IsOutput=*/false);1301 if (!Ops0)1302 return nullptr;1303 Ops1 = FlushFPConstant(Ops1, I, /*IsOutput=*/false);1304 if (!Ops1)1305 return nullptr;1306 }1307 1308 return ConstantFoldCompareInstruction(Predicate, Ops0, Ops1);1309}1310 1311Constant *llvm::ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op,1312 const DataLayout &DL) {1313 assert(Instruction::isUnaryOp(Opcode));1314 1315 return ConstantFoldUnaryInstruction(Opcode, Op);1316}1317 1318Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,1319 Constant *RHS,1320 const DataLayout &DL) {1321 assert(Instruction::isBinaryOp(Opcode));1322 if (isa<ConstantExpr>(LHS) || isa<ConstantExpr>(RHS))1323 if (Constant *C = SymbolicallyEvaluateBinop(Opcode, LHS, RHS, DL))1324 return C;1325 1326 if (ConstantExpr::isDesirableBinOp(Opcode))1327 return ConstantExpr::get(Opcode, LHS, RHS);1328 return ConstantFoldBinaryInstruction(Opcode, LHS, RHS);1329}1330 1331static ConstantFP *flushDenormalConstant(Type *Ty, const APFloat &APF,1332 DenormalMode::DenormalModeKind Mode) {1333 switch (Mode) {1334 case DenormalMode::Dynamic:1335 return nullptr;1336 case DenormalMode::IEEE:1337 return ConstantFP::get(Ty->getContext(), APF);1338 case DenormalMode::PreserveSign:1339 return ConstantFP::get(1340 Ty->getContext(),1341 APFloat::getZero(APF.getSemantics(), APF.isNegative()));1342 case DenormalMode::PositiveZero:1343 return ConstantFP::get(Ty->getContext(),1344 APFloat::getZero(APF.getSemantics(), false));1345 default:1346 break;1347 }1348 1349 llvm_unreachable("unknown denormal mode");1350}1351 1352/// Return the denormal mode that can be assumed when executing a floating point1353/// operation at \p CtxI.1354static DenormalMode getInstrDenormalMode(const Instruction *CtxI, Type *Ty) {1355 if (!CtxI || !CtxI->getParent() || !CtxI->getFunction())1356 return DenormalMode::getDynamic();1357 return CtxI->getFunction()->getDenormalMode(Ty->getFltSemantics());1358}1359 1360static ConstantFP *flushDenormalConstantFP(ConstantFP *CFP,1361 const Instruction *Inst,1362 bool IsOutput) {1363 const APFloat &APF = CFP->getValueAPF();1364 if (!APF.isDenormal())1365 return CFP;1366 1367 DenormalMode Mode = getInstrDenormalMode(Inst, CFP->getType());1368 return flushDenormalConstant(CFP->getType(), APF,1369 IsOutput ? Mode.Output : Mode.Input);1370}1371 1372Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *Inst,1373 bool IsOutput) {1374 if (ConstantFP *CFP = dyn_cast<ConstantFP>(Operand))1375 return flushDenormalConstantFP(CFP, Inst, IsOutput);1376 1377 if (isa<ConstantAggregateZero, UndefValue>(Operand))1378 return Operand;1379 1380 Type *Ty = Operand->getType();1381 VectorType *VecTy = dyn_cast<VectorType>(Ty);1382 if (VecTy) {1383 if (auto *Splat = dyn_cast_or_null<ConstantFP>(Operand->getSplatValue())) {1384 ConstantFP *Folded = flushDenormalConstantFP(Splat, Inst, IsOutput);1385 if (!Folded)1386 return nullptr;1387 return ConstantVector::getSplat(VecTy->getElementCount(), Folded);1388 }1389 1390 Ty = VecTy->getElementType();1391 }1392 1393 if (isa<ConstantExpr>(Operand))1394 return Operand;1395 1396 if (const auto *CV = dyn_cast<ConstantVector>(Operand)) {1397 SmallVector<Constant *, 16> NewElts;1398 for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) {1399 Constant *Element = CV->getAggregateElement(i);1400 if (isa<UndefValue>(Element)) {1401 NewElts.push_back(Element);1402 continue;1403 }1404 1405 ConstantFP *CFP = dyn_cast<ConstantFP>(Element);1406 if (!CFP)1407 return nullptr;1408 1409 ConstantFP *Folded = flushDenormalConstantFP(CFP, Inst, IsOutput);1410 if (!Folded)1411 return nullptr;1412 NewElts.push_back(Folded);1413 }1414 1415 return ConstantVector::get(NewElts);1416 }1417 1418 if (const auto *CDV = dyn_cast<ConstantDataVector>(Operand)) {1419 SmallVector<Constant *, 16> NewElts;1420 for (unsigned I = 0, E = CDV->getNumElements(); I < E; ++I) {1421 const APFloat &Elt = CDV->getElementAsAPFloat(I);1422 if (!Elt.isDenormal()) {1423 NewElts.push_back(ConstantFP::get(Ty, Elt));1424 } else {1425 DenormalMode Mode = getInstrDenormalMode(Inst, Ty);1426 ConstantFP *Folded =1427 flushDenormalConstant(Ty, Elt, IsOutput ? Mode.Output : Mode.Input);1428 if (!Folded)1429 return nullptr;1430 NewElts.push_back(Folded);1431 }1432 }1433 1434 return ConstantVector::get(NewElts);1435 }1436 1437 return nullptr;1438}1439 1440Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,1441 Constant *RHS, const DataLayout &DL,1442 const Instruction *I,1443 bool AllowNonDeterministic) {1444 if (Instruction::isBinaryOp(Opcode)) {1445 // Flush denormal inputs if needed.1446 Constant *Op0 = FlushFPConstant(LHS, I, /* IsOutput */ false);1447 if (!Op0)1448 return nullptr;1449 Constant *Op1 = FlushFPConstant(RHS, I, /* IsOutput */ false);1450 if (!Op1)1451 return nullptr;1452 1453 // If nsz or an algebraic FMF flag is set, the result of the FP operation1454 // may change due to future optimization. Don't constant fold them if1455 // non-deterministic results are not allowed.1456 if (!AllowNonDeterministic)1457 if (auto *FP = dyn_cast_or_null<FPMathOperator>(I))1458 if (FP->hasNoSignedZeros() || FP->hasAllowReassoc() ||1459 FP->hasAllowContract() || FP->hasAllowReciprocal())1460 return nullptr;1461 1462 // Calculate constant result.1463 Constant *C = ConstantFoldBinaryOpOperands(Opcode, Op0, Op1, DL);1464 if (!C)1465 return nullptr;1466 1467 // Flush denormal output if needed.1468 C = FlushFPConstant(C, I, /* IsOutput */ true);1469 if (!C)1470 return nullptr;1471 1472 // The precise NaN value is non-deterministic.1473 if (!AllowNonDeterministic && C->isNaN())1474 return nullptr;1475 1476 return C;1477 }1478 // If instruction lacks a parent/function and the denormal mode cannot be1479 // determined, use the default (IEEE).1480 return ConstantFoldBinaryOpOperands(Opcode, LHS, RHS, DL);1481}1482 1483Constant *llvm::ConstantFoldCastOperand(unsigned Opcode, Constant *C,1484 Type *DestTy, const DataLayout &DL) {1485 assert(Instruction::isCast(Opcode));1486 1487 if (auto *CE = dyn_cast<ConstantExpr>(C))1488 if (CE->isCast())1489 if (unsigned NewOp = CastInst::isEliminableCastPair(1490 Instruction::CastOps(CE->getOpcode()),1491 Instruction::CastOps(Opcode), CE->getOperand(0)->getType(),1492 C->getType(), DestTy, &DL))1493 return ConstantFoldCastOperand(NewOp, CE->getOperand(0), DestTy, DL);1494 1495 switch (Opcode) {1496 default:1497 llvm_unreachable("Missing case");1498 case Instruction::PtrToAddr:1499 case Instruction::PtrToInt:1500 if (auto *CE = dyn_cast<ConstantExpr>(C)) {1501 Constant *FoldedValue = nullptr;1502 // If the input is an inttoptr, eliminate the pair. This requires knowing1503 // the width of a pointer, so it can't be done in ConstantExpr::getCast.1504 if (CE->getOpcode() == Instruction::IntToPtr) {1505 // zext/trunc the inttoptr to pointer/address size.1506 Type *MidTy = Opcode == Instruction::PtrToInt1507 ? DL.getAddressType(CE->getType())1508 : DL.getIntPtrType(CE->getType());1509 FoldedValue = ConstantFoldIntegerCast(CE->getOperand(0), MidTy,1510 /*IsSigned=*/false, DL);1511 } else if (auto *GEP = dyn_cast<GEPOperator>(CE)) {1512 // If we have GEP, we can perform the following folds:1513 // (ptrtoint/ptrtoaddr (gep null, x)) -> x1514 // (ptrtoint/ptrtoaddr (gep (gep null, x), y) -> x + y, etc.1515 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType());1516 APInt BaseOffset(BitWidth, 0);1517 auto *Base = cast<Constant>(GEP->stripAndAccumulateConstantOffsets(1518 DL, BaseOffset, /*AllowNonInbounds=*/true));1519 if (Base->isNullValue()) {1520 FoldedValue = ConstantInt::get(CE->getContext(), BaseOffset);1521 } else {1522 // ptrtoint/ptrtoaddr (gep i8, Ptr, (sub 0, V))1523 // -> sub (ptrtoint/ptrtoaddr Ptr), V1524 if (GEP->getNumIndices() == 1 &&1525 GEP->getSourceElementType()->isIntegerTy(8)) {1526 auto *Ptr = cast<Constant>(GEP->getPointerOperand());1527 auto *Sub = dyn_cast<ConstantExpr>(GEP->getOperand(1));1528 Type *IntIdxTy = DL.getIndexType(Ptr->getType());1529 if (Sub && Sub->getType() == IntIdxTy &&1530 Sub->getOpcode() == Instruction::Sub &&1531 Sub->getOperand(0)->isNullValue())1532 FoldedValue = ConstantExpr::getSub(1533 ConstantExpr::getCast(Opcode, Ptr, IntIdxTy),1534 Sub->getOperand(1));1535 }1536 }1537 }1538 if (FoldedValue) {1539 // Do a zext or trunc to get to the ptrtoint/ptrtoaddr dest size.1540 return ConstantFoldIntegerCast(FoldedValue, DestTy, /*IsSigned=*/false,1541 DL);1542 }1543 }1544 break;1545 case Instruction::IntToPtr:1546 // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if1547 // the int size is >= the ptr size and the address spaces are the same.1548 // This requires knowing the width of a pointer, so it can't be done in1549 // ConstantExpr::getCast.1550 if (auto *CE = dyn_cast<ConstantExpr>(C)) {1551 if (CE->getOpcode() == Instruction::PtrToInt) {1552 Constant *SrcPtr = CE->getOperand(0);1553 unsigned SrcPtrSize = DL.getPointerTypeSizeInBits(SrcPtr->getType());1554 unsigned MidIntSize = CE->getType()->getScalarSizeInBits();1555 1556 if (MidIntSize >= SrcPtrSize) {1557 unsigned SrcAS = SrcPtr->getType()->getPointerAddressSpace();1558 if (SrcAS == DestTy->getPointerAddressSpace())1559 return FoldBitCast(CE->getOperand(0), DestTy, DL);1560 }1561 }1562 }1563 break;1564 case Instruction::Trunc:1565 case Instruction::ZExt:1566 case Instruction::SExt:1567 case Instruction::FPTrunc:1568 case Instruction::FPExt:1569 case Instruction::UIToFP:1570 case Instruction::SIToFP:1571 case Instruction::FPToUI:1572 case Instruction::FPToSI:1573 case Instruction::AddrSpaceCast:1574 break;1575 case Instruction::BitCast:1576 return FoldBitCast(C, DestTy, DL);1577 }1578 1579 if (ConstantExpr::isDesirableCastOp(Opcode))1580 return ConstantExpr::getCast(Opcode, C, DestTy);1581 return ConstantFoldCastInstruction(Opcode, C, DestTy);1582}1583 1584Constant *llvm::ConstantFoldIntegerCast(Constant *C, Type *DestTy,1585 bool IsSigned, const DataLayout &DL) {1586 Type *SrcTy = C->getType();1587 if (SrcTy == DestTy)1588 return C;1589 if (SrcTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())1590 return ConstantFoldCastOperand(Instruction::Trunc, C, DestTy, DL);1591 if (IsSigned)1592 return ConstantFoldCastOperand(Instruction::SExt, C, DestTy, DL);1593 return ConstantFoldCastOperand(Instruction::ZExt, C, DestTy, DL);1594}1595 1596//===----------------------------------------------------------------------===//1597// Constant Folding for Calls1598//1599 1600bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {1601 if (Call->isNoBuiltin())1602 return false;1603 if (Call->getFunctionType() != F->getFunctionType())1604 return false;1605 1606 // Allow FP calls (both libcalls and intrinsics) to avoid being folded.1607 // This can be useful for GPU targets or in cross-compilation scenarios1608 // when the exact target FP behaviour is required, and the host compiler's1609 // behaviour may be slightly different from the device's run-time behaviour.1610 if (DisableFPCallFolding && (F->getReturnType()->isFloatingPointTy() ||1611 any_of(F->args(), [](const Argument &Arg) {1612 return Arg.getType()->isFloatingPointTy();1613 })))1614 return false;1615 1616 switch (F->getIntrinsicID()) {1617 // Operations that do not operate floating-point numbers and do not depend on1618 // FP environment can be folded even in strictfp functions.1619 case Intrinsic::bswap:1620 case Intrinsic::ctpop:1621 case Intrinsic::ctlz:1622 case Intrinsic::cttz:1623 case Intrinsic::fshl:1624 case Intrinsic::fshr:1625 case Intrinsic::launder_invariant_group:1626 case Intrinsic::strip_invariant_group:1627 case Intrinsic::masked_load:1628 case Intrinsic::get_active_lane_mask:1629 case Intrinsic::abs:1630 case Intrinsic::smax:1631 case Intrinsic::smin:1632 case Intrinsic::umax:1633 case Intrinsic::umin:1634 case Intrinsic::scmp:1635 case Intrinsic::ucmp:1636 case Intrinsic::sadd_with_overflow:1637 case Intrinsic::uadd_with_overflow:1638 case Intrinsic::ssub_with_overflow:1639 case Intrinsic::usub_with_overflow:1640 case Intrinsic::smul_with_overflow:1641 case Intrinsic::umul_with_overflow:1642 case Intrinsic::sadd_sat:1643 case Intrinsic::uadd_sat:1644 case Intrinsic::ssub_sat:1645 case Intrinsic::usub_sat:1646 case Intrinsic::smul_fix:1647 case Intrinsic::smul_fix_sat:1648 case Intrinsic::bitreverse:1649 case Intrinsic::is_constant:1650 case Intrinsic::vector_reduce_add:1651 case Intrinsic::vector_reduce_mul:1652 case Intrinsic::vector_reduce_and:1653 case Intrinsic::vector_reduce_or:1654 case Intrinsic::vector_reduce_xor:1655 case Intrinsic::vector_reduce_smin:1656 case Intrinsic::vector_reduce_smax:1657 case Intrinsic::vector_reduce_umin:1658 case Intrinsic::vector_reduce_umax:1659 case Intrinsic::vector_extract:1660 case Intrinsic::vector_insert:1661 case Intrinsic::vector_interleave2:1662 case Intrinsic::vector_interleave3:1663 case Intrinsic::vector_interleave4:1664 case Intrinsic::vector_interleave5:1665 case Intrinsic::vector_interleave6:1666 case Intrinsic::vector_interleave7:1667 case Intrinsic::vector_interleave8:1668 case Intrinsic::vector_deinterleave2:1669 case Intrinsic::vector_deinterleave3:1670 case Intrinsic::vector_deinterleave4:1671 case Intrinsic::vector_deinterleave5:1672 case Intrinsic::vector_deinterleave6:1673 case Intrinsic::vector_deinterleave7:1674 case Intrinsic::vector_deinterleave8:1675 // Target intrinsics1676 case Intrinsic::amdgcn_perm:1677 case Intrinsic::amdgcn_wave_reduce_umin:1678 case Intrinsic::amdgcn_wave_reduce_umax:1679 case Intrinsic::amdgcn_wave_reduce_max:1680 case Intrinsic::amdgcn_wave_reduce_min:1681 case Intrinsic::amdgcn_wave_reduce_add:1682 case Intrinsic::amdgcn_wave_reduce_sub:1683 case Intrinsic::amdgcn_wave_reduce_and:1684 case Intrinsic::amdgcn_wave_reduce_or:1685 case Intrinsic::amdgcn_wave_reduce_xor:1686 case Intrinsic::amdgcn_s_wqm:1687 case Intrinsic::amdgcn_s_quadmask:1688 case Intrinsic::amdgcn_s_bitreplicate:1689 case Intrinsic::arm_mve_vctp8:1690 case Intrinsic::arm_mve_vctp16:1691 case Intrinsic::arm_mve_vctp32:1692 case Intrinsic::arm_mve_vctp64:1693 case Intrinsic::aarch64_sve_convert_from_svbool:1694 case Intrinsic::wasm_alltrue:1695 case Intrinsic::wasm_anytrue:1696 case Intrinsic::wasm_dot:1697 // WebAssembly float semantics are always known1698 case Intrinsic::wasm_trunc_signed:1699 case Intrinsic::wasm_trunc_unsigned:1700 return true;1701 1702 // Floating point operations cannot be folded in strictfp functions in1703 // general case. They can be folded if FP environment is known to compiler.1704 case Intrinsic::minnum:1705 case Intrinsic::maxnum:1706 case Intrinsic::minimum:1707 case Intrinsic::maximum:1708 case Intrinsic::minimumnum:1709 case Intrinsic::maximumnum:1710 case Intrinsic::log:1711 case Intrinsic::log2:1712 case Intrinsic::log10:1713 case Intrinsic::exp:1714 case Intrinsic::exp2:1715 case Intrinsic::exp10:1716 case Intrinsic::sqrt:1717 case Intrinsic::sin:1718 case Intrinsic::cos:1719 case Intrinsic::sincos:1720 case Intrinsic::sinh:1721 case Intrinsic::cosh:1722 case Intrinsic::atan:1723 case Intrinsic::pow:1724 case Intrinsic::powi:1725 case Intrinsic::ldexp:1726 case Intrinsic::fma:1727 case Intrinsic::fmuladd:1728 case Intrinsic::frexp:1729 case Intrinsic::fptoui_sat:1730 case Intrinsic::fptosi_sat:1731 case Intrinsic::convert_from_fp16:1732 case Intrinsic::convert_to_fp16:1733 case Intrinsic::amdgcn_cos:1734 case Intrinsic::amdgcn_cubeid:1735 case Intrinsic::amdgcn_cubema:1736 case Intrinsic::amdgcn_cubesc:1737 case Intrinsic::amdgcn_cubetc:1738 case Intrinsic::amdgcn_fmul_legacy:1739 case Intrinsic::amdgcn_fma_legacy:1740 case Intrinsic::amdgcn_fract:1741 case Intrinsic::amdgcn_sin:1742 // The intrinsics below depend on rounding mode in MXCSR.1743 case Intrinsic::x86_sse_cvtss2si:1744 case Intrinsic::x86_sse_cvtss2si64:1745 case Intrinsic::x86_sse_cvttss2si:1746 case Intrinsic::x86_sse_cvttss2si64:1747 case Intrinsic::x86_sse2_cvtsd2si:1748 case Intrinsic::x86_sse2_cvtsd2si64:1749 case Intrinsic::x86_sse2_cvttsd2si:1750 case Intrinsic::x86_sse2_cvttsd2si64:1751 case Intrinsic::x86_avx512_vcvtss2si32:1752 case Intrinsic::x86_avx512_vcvtss2si64:1753 case Intrinsic::x86_avx512_cvttss2si:1754 case Intrinsic::x86_avx512_cvttss2si64:1755 case Intrinsic::x86_avx512_vcvtsd2si32:1756 case Intrinsic::x86_avx512_vcvtsd2si64:1757 case Intrinsic::x86_avx512_cvttsd2si:1758 case Intrinsic::x86_avx512_cvttsd2si64:1759 case Intrinsic::x86_avx512_vcvtss2usi32:1760 case Intrinsic::x86_avx512_vcvtss2usi64:1761 case Intrinsic::x86_avx512_cvttss2usi:1762 case Intrinsic::x86_avx512_cvttss2usi64:1763 case Intrinsic::x86_avx512_vcvtsd2usi32:1764 case Intrinsic::x86_avx512_vcvtsd2usi64:1765 case Intrinsic::x86_avx512_cvttsd2usi:1766 case Intrinsic::x86_avx512_cvttsd2usi64:1767 1768 // NVVM FMax intrinsics1769 case Intrinsic::nvvm_fmax_d:1770 case Intrinsic::nvvm_fmax_f:1771 case Intrinsic::nvvm_fmax_ftz_f:1772 case Intrinsic::nvvm_fmax_ftz_nan_f:1773 case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:1774 case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:1775 case Intrinsic::nvvm_fmax_nan_f:1776 case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:1777 case Intrinsic::nvvm_fmax_xorsign_abs_f:1778 1779 // NVVM FMin intrinsics1780 case Intrinsic::nvvm_fmin_d:1781 case Intrinsic::nvvm_fmin_f:1782 case Intrinsic::nvvm_fmin_ftz_f:1783 case Intrinsic::nvvm_fmin_ftz_nan_f:1784 case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:1785 case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:1786 case Intrinsic::nvvm_fmin_nan_f:1787 case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:1788 case Intrinsic::nvvm_fmin_xorsign_abs_f:1789 1790 // NVVM float/double to int32/uint32 conversion intrinsics1791 case Intrinsic::nvvm_f2i_rm:1792 case Intrinsic::nvvm_f2i_rn:1793 case Intrinsic::nvvm_f2i_rp:1794 case Intrinsic::nvvm_f2i_rz:1795 case Intrinsic::nvvm_f2i_rm_ftz:1796 case Intrinsic::nvvm_f2i_rn_ftz:1797 case Intrinsic::nvvm_f2i_rp_ftz:1798 case Intrinsic::nvvm_f2i_rz_ftz:1799 case Intrinsic::nvvm_f2ui_rm:1800 case Intrinsic::nvvm_f2ui_rn:1801 case Intrinsic::nvvm_f2ui_rp:1802 case Intrinsic::nvvm_f2ui_rz:1803 case Intrinsic::nvvm_f2ui_rm_ftz:1804 case Intrinsic::nvvm_f2ui_rn_ftz:1805 case Intrinsic::nvvm_f2ui_rp_ftz:1806 case Intrinsic::nvvm_f2ui_rz_ftz:1807 case Intrinsic::nvvm_d2i_rm:1808 case Intrinsic::nvvm_d2i_rn:1809 case Intrinsic::nvvm_d2i_rp:1810 case Intrinsic::nvvm_d2i_rz:1811 case Intrinsic::nvvm_d2ui_rm:1812 case Intrinsic::nvvm_d2ui_rn:1813 case Intrinsic::nvvm_d2ui_rp:1814 case Intrinsic::nvvm_d2ui_rz:1815 1816 // NVVM float/double to int64/uint64 conversion intrinsics1817 case Intrinsic::nvvm_f2ll_rm:1818 case Intrinsic::nvvm_f2ll_rn:1819 case Intrinsic::nvvm_f2ll_rp:1820 case Intrinsic::nvvm_f2ll_rz:1821 case Intrinsic::nvvm_f2ll_rm_ftz:1822 case Intrinsic::nvvm_f2ll_rn_ftz:1823 case Intrinsic::nvvm_f2ll_rp_ftz:1824 case Intrinsic::nvvm_f2ll_rz_ftz:1825 case Intrinsic::nvvm_f2ull_rm:1826 case Intrinsic::nvvm_f2ull_rn:1827 case Intrinsic::nvvm_f2ull_rp:1828 case Intrinsic::nvvm_f2ull_rz:1829 case Intrinsic::nvvm_f2ull_rm_ftz:1830 case Intrinsic::nvvm_f2ull_rn_ftz:1831 case Intrinsic::nvvm_f2ull_rp_ftz:1832 case Intrinsic::nvvm_f2ull_rz_ftz:1833 case Intrinsic::nvvm_d2ll_rm:1834 case Intrinsic::nvvm_d2ll_rn:1835 case Intrinsic::nvvm_d2ll_rp:1836 case Intrinsic::nvvm_d2ll_rz:1837 case Intrinsic::nvvm_d2ull_rm:1838 case Intrinsic::nvvm_d2ull_rn:1839 case Intrinsic::nvvm_d2ull_rp:1840 case Intrinsic::nvvm_d2ull_rz:1841 1842 // NVVM math intrinsics:1843 case Intrinsic::nvvm_ceil_d:1844 case Intrinsic::nvvm_ceil_f:1845 case Intrinsic::nvvm_ceil_ftz_f:1846 1847 case Intrinsic::nvvm_fabs:1848 case Intrinsic::nvvm_fabs_ftz:1849 1850 case Intrinsic::nvvm_floor_d:1851 case Intrinsic::nvvm_floor_f:1852 case Intrinsic::nvvm_floor_ftz_f:1853 1854 case Intrinsic::nvvm_rcp_rm_d:1855 case Intrinsic::nvvm_rcp_rm_f:1856 case Intrinsic::nvvm_rcp_rm_ftz_f:1857 case Intrinsic::nvvm_rcp_rn_d:1858 case Intrinsic::nvvm_rcp_rn_f:1859 case Intrinsic::nvvm_rcp_rn_ftz_f:1860 case Intrinsic::nvvm_rcp_rp_d:1861 case Intrinsic::nvvm_rcp_rp_f:1862 case Intrinsic::nvvm_rcp_rp_ftz_f:1863 case Intrinsic::nvvm_rcp_rz_d:1864 case Intrinsic::nvvm_rcp_rz_f:1865 case Intrinsic::nvvm_rcp_rz_ftz_f:1866 1867 case Intrinsic::nvvm_round_d:1868 case Intrinsic::nvvm_round_f:1869 case Intrinsic::nvvm_round_ftz_f:1870 1871 case Intrinsic::nvvm_saturate_d:1872 case Intrinsic::nvvm_saturate_f:1873 case Intrinsic::nvvm_saturate_ftz_f:1874 1875 case Intrinsic::nvvm_sqrt_f:1876 case Intrinsic::nvvm_sqrt_rn_d:1877 case Intrinsic::nvvm_sqrt_rn_f:1878 case Intrinsic::nvvm_sqrt_rn_ftz_f:1879 return !Call->isStrictFP();1880 1881 // NVVM add intrinsics with explicit rounding modes1882 case Intrinsic::nvvm_add_rm_d:1883 case Intrinsic::nvvm_add_rn_d:1884 case Intrinsic::nvvm_add_rp_d:1885 case Intrinsic::nvvm_add_rz_d:1886 case Intrinsic::nvvm_add_rm_f:1887 case Intrinsic::nvvm_add_rn_f:1888 case Intrinsic::nvvm_add_rp_f:1889 case Intrinsic::nvvm_add_rz_f:1890 case Intrinsic::nvvm_add_rm_ftz_f:1891 case Intrinsic::nvvm_add_rn_ftz_f:1892 case Intrinsic::nvvm_add_rp_ftz_f:1893 case Intrinsic::nvvm_add_rz_ftz_f:1894 1895 // NVVM div intrinsics with explicit rounding modes1896 case Intrinsic::nvvm_div_rm_d:1897 case Intrinsic::nvvm_div_rn_d:1898 case Intrinsic::nvvm_div_rp_d:1899 case Intrinsic::nvvm_div_rz_d:1900 case Intrinsic::nvvm_div_rm_f:1901 case Intrinsic::nvvm_div_rn_f:1902 case Intrinsic::nvvm_div_rp_f:1903 case Intrinsic::nvvm_div_rz_f:1904 case Intrinsic::nvvm_div_rm_ftz_f:1905 case Intrinsic::nvvm_div_rn_ftz_f:1906 case Intrinsic::nvvm_div_rp_ftz_f:1907 case Intrinsic::nvvm_div_rz_ftz_f:1908 1909 // NVVM mul intrinsics with explicit rounding modes1910 case Intrinsic::nvvm_mul_rm_d:1911 case Intrinsic::nvvm_mul_rn_d:1912 case Intrinsic::nvvm_mul_rp_d:1913 case Intrinsic::nvvm_mul_rz_d:1914 case Intrinsic::nvvm_mul_rm_f:1915 case Intrinsic::nvvm_mul_rn_f:1916 case Intrinsic::nvvm_mul_rp_f:1917 case Intrinsic::nvvm_mul_rz_f:1918 case Intrinsic::nvvm_mul_rm_ftz_f:1919 case Intrinsic::nvvm_mul_rn_ftz_f:1920 case Intrinsic::nvvm_mul_rp_ftz_f:1921 case Intrinsic::nvvm_mul_rz_ftz_f:1922 1923 // NVVM fma intrinsics with explicit rounding modes1924 case Intrinsic::nvvm_fma_rm_d:1925 case Intrinsic::nvvm_fma_rn_d:1926 case Intrinsic::nvvm_fma_rp_d:1927 case Intrinsic::nvvm_fma_rz_d:1928 case Intrinsic::nvvm_fma_rm_f:1929 case Intrinsic::nvvm_fma_rn_f:1930 case Intrinsic::nvvm_fma_rp_f:1931 case Intrinsic::nvvm_fma_rz_f:1932 case Intrinsic::nvvm_fma_rm_ftz_f:1933 case Intrinsic::nvvm_fma_rn_ftz_f:1934 case Intrinsic::nvvm_fma_rp_ftz_f:1935 case Intrinsic::nvvm_fma_rz_ftz_f:1936 1937 // Sign operations are actually bitwise operations, they do not raise1938 // exceptions even for SNANs.1939 case Intrinsic::fabs:1940 case Intrinsic::copysign:1941 case Intrinsic::is_fpclass:1942 // Non-constrained variants of rounding operations means default FP1943 // environment, they can be folded in any case.1944 case Intrinsic::ceil:1945 case Intrinsic::floor:1946 case Intrinsic::round:1947 case Intrinsic::roundeven:1948 case Intrinsic::trunc:1949 case Intrinsic::nearbyint:1950 case Intrinsic::rint:1951 case Intrinsic::canonicalize:1952 1953 // Constrained intrinsics can be folded if FP environment is known1954 // to compiler.1955 case Intrinsic::experimental_constrained_fma:1956 case Intrinsic::experimental_constrained_fmuladd:1957 case Intrinsic::experimental_constrained_fadd:1958 case Intrinsic::experimental_constrained_fsub:1959 case Intrinsic::experimental_constrained_fmul:1960 case Intrinsic::experimental_constrained_fdiv:1961 case Intrinsic::experimental_constrained_frem:1962 case Intrinsic::experimental_constrained_ceil:1963 case Intrinsic::experimental_constrained_floor:1964 case Intrinsic::experimental_constrained_round:1965 case Intrinsic::experimental_constrained_roundeven:1966 case Intrinsic::experimental_constrained_trunc:1967 case Intrinsic::experimental_constrained_nearbyint:1968 case Intrinsic::experimental_constrained_rint:1969 case Intrinsic::experimental_constrained_fcmp:1970 case Intrinsic::experimental_constrained_fcmps:1971 return true;1972 default:1973 return false;1974 case Intrinsic::not_intrinsic: break;1975 }1976 1977 if (!F->hasName() || Call->isStrictFP())1978 return false;1979 1980 // In these cases, the check of the length is required. We don't want to1981 // return true for a name like "cos\0blah" which strcmp would return equal to1982 // "cos", but has length 8.1983 StringRef Name = F->getName();1984 switch (Name[0]) {1985 default:1986 return false;1987 case 'a':1988 return Name == "acos" || Name == "acosf" ||1989 Name == "asin" || Name == "asinf" ||1990 Name == "atan" || Name == "atanf" ||1991 Name == "atan2" || Name == "atan2f";1992 case 'c':1993 return Name == "ceil" || Name == "ceilf" ||1994 Name == "cos" || Name == "cosf" ||1995 Name == "cosh" || Name == "coshf";1996 case 'e':1997 return Name == "exp" || Name == "expf" || Name == "exp2" ||1998 Name == "exp2f" || Name == "erf" || Name == "erff";1999 case 'f':2000 return Name == "fabs" || Name == "fabsf" ||2001 Name == "floor" || Name == "floorf" ||2002 Name == "fmod" || Name == "fmodf";2003 case 'i':2004 return Name == "ilogb" || Name == "ilogbf";2005 case 'l':2006 return Name == "log" || Name == "logf" || Name == "logl" ||2007 Name == "log2" || Name == "log2f" || Name == "log10" ||2008 Name == "log10f" || Name == "logb" || Name == "logbf" ||2009 Name == "log1p" || Name == "log1pf";2010 case 'n':2011 return Name == "nearbyint" || Name == "nearbyintf";2012 case 'p':2013 return Name == "pow" || Name == "powf";2014 case 'r':2015 return Name == "remainder" || Name == "remainderf" ||2016 Name == "rint" || Name == "rintf" ||2017 Name == "round" || Name == "roundf";2018 case 's':2019 return Name == "sin" || Name == "sinf" ||2020 Name == "sinh" || Name == "sinhf" ||2021 Name == "sqrt" || Name == "sqrtf";2022 case 't':2023 return Name == "tan" || Name == "tanf" ||2024 Name == "tanh" || Name == "tanhf" ||2025 Name == "trunc" || Name == "truncf";2026 case '_':2027 // Check for various function names that get used for the math functions2028 // when the header files are preprocessed with the macro2029 // __FINITE_MATH_ONLY__ enabled.2030 // The '12' here is the length of the shortest name that can match.2031 // We need to check the size before looking at Name[1] and Name[2]2032 // so we may as well check a limit that will eliminate mismatches.2033 if (Name.size() < 12 || Name[1] != '_')2034 return false;2035 switch (Name[2]) {2036 default:2037 return false;2038 case 'a':2039 return Name == "__acos_finite" || Name == "__acosf_finite" ||2040 Name == "__asin_finite" || Name == "__asinf_finite" ||2041 Name == "__atan2_finite" || Name == "__atan2f_finite";2042 case 'c':2043 return Name == "__cosh_finite" || Name == "__coshf_finite";2044 case 'e':2045 return Name == "__exp_finite" || Name == "__expf_finite" ||2046 Name == "__exp2_finite" || Name == "__exp2f_finite";2047 case 'l':2048 return Name == "__log_finite" || Name == "__logf_finite" ||2049 Name == "__log10_finite" || Name == "__log10f_finite";2050 case 'p':2051 return Name == "__pow_finite" || Name == "__powf_finite";2052 case 's':2053 return Name == "__sinh_finite" || Name == "__sinhf_finite";2054 }2055 }2056}2057 2058namespace {2059 2060Constant *GetConstantFoldFPValue(double V, Type *Ty) {2061 if (Ty->isHalfTy() || Ty->isFloatTy()) {2062 APFloat APF(V);2063 bool unused;2064 APF.convert(Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &unused);2065 return ConstantFP::get(Ty->getContext(), APF);2066 }2067 if (Ty->isDoubleTy())2068 return ConstantFP::get(Ty->getContext(), APFloat(V));2069 llvm_unreachable("Can only constant fold half/float/double");2070}2071 2072#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)2073Constant *GetConstantFoldFPValue128(float128 V, Type *Ty) {2074 if (Ty->isFP128Ty())2075 return ConstantFP::get(Ty, V);2076 llvm_unreachable("Can only constant fold fp128");2077}2078#endif2079 2080/// Clear the floating-point exception state.2081inline void llvm_fenv_clearexcept() {2082#if HAVE_DECL_FE_ALL_EXCEPT2083 feclearexcept(FE_ALL_EXCEPT);2084#endif2085 errno = 0;2086}2087 2088/// Test if a floating-point exception was raised.2089inline bool llvm_fenv_testexcept() {2090 int errno_val = errno;2091 if (errno_val == ERANGE || errno_val == EDOM)2092 return true;2093#if HAVE_DECL_FE_ALL_EXCEPT && HAVE_DECL_FE_INEXACT2094 if (fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT))2095 return true;2096#endif2097 return false;2098}2099 2100static APFloat FTZPreserveSign(const APFloat &V) {2101 if (V.isDenormal())2102 return APFloat::getZero(V.getSemantics(), V.isNegative());2103 return V;2104}2105 2106static APFloat FlushToPositiveZero(const APFloat &V) {2107 if (V.isDenormal())2108 return APFloat::getZero(V.getSemantics(), false);2109 return V;2110}2111 2112static APFloat FlushWithDenormKind(const APFloat &V,2113 DenormalMode::DenormalModeKind DenormKind) {2114 assert(DenormKind != DenormalMode::DenormalModeKind::Invalid &&2115 DenormKind != DenormalMode::DenormalModeKind::Dynamic);2116 switch (DenormKind) {2117 case DenormalMode::DenormalModeKind::IEEE:2118 return V;2119 case DenormalMode::DenormalModeKind::PreserveSign:2120 return FTZPreserveSign(V);2121 case DenormalMode::DenormalModeKind::PositiveZero:2122 return FlushToPositiveZero(V);2123 default:2124 llvm_unreachable("Invalid denormal mode!");2125 }2126}2127 2128Constant *ConstantFoldFP(double (*NativeFP)(double), const APFloat &V, Type *Ty,2129 DenormalMode DenormMode = DenormalMode::getIEEE()) {2130 if (!DenormMode.isValid() ||2131 DenormMode.Input == DenormalMode::DenormalModeKind::Dynamic ||2132 DenormMode.Output == DenormalMode::DenormalModeKind::Dynamic)2133 return nullptr;2134 2135 llvm_fenv_clearexcept();2136 auto Input = FlushWithDenormKind(V, DenormMode.Input);2137 double Result = NativeFP(Input.convertToDouble());2138 if (llvm_fenv_testexcept()) {2139 llvm_fenv_clearexcept();2140 return nullptr;2141 }2142 2143 Constant *Output = GetConstantFoldFPValue(Result, Ty);2144 if (DenormMode.Output == DenormalMode::DenormalModeKind::IEEE)2145 return Output;2146 const auto *CFP = static_cast<ConstantFP *>(Output);2147 const auto Res = FlushWithDenormKind(CFP->getValueAPF(), DenormMode.Output);2148 return ConstantFP::get(Ty->getContext(), Res);2149}2150 2151#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)2152Constant *ConstantFoldFP128(float128 (*NativeFP)(float128), const APFloat &V,2153 Type *Ty) {2154 llvm_fenv_clearexcept();2155 float128 Result = NativeFP(V.convertToQuad());2156 if (llvm_fenv_testexcept()) {2157 llvm_fenv_clearexcept();2158 return nullptr;2159 }2160 2161 return GetConstantFoldFPValue128(Result, Ty);2162}2163#endif2164 2165Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),2166 const APFloat &V, const APFloat &W, Type *Ty) {2167 llvm_fenv_clearexcept();2168 double Result = NativeFP(V.convertToDouble(), W.convertToDouble());2169 if (llvm_fenv_testexcept()) {2170 llvm_fenv_clearexcept();2171 return nullptr;2172 }2173 2174 return GetConstantFoldFPValue(Result, Ty);2175}2176 2177Constant *constantFoldVectorReduce(Intrinsic::ID IID, Constant *Op) {2178 auto *OpVT = cast<VectorType>(Op->getType());2179 2180 // This is the same as the underlying binops - poison propagates.2181 if (Op->containsPoisonElement())2182 return PoisonValue::get(OpVT->getElementType());2183 2184 // Shortcut non-accumulating reductions.2185 if (Constant *SplatVal = Op->getSplatValue()) {2186 switch (IID) {2187 case Intrinsic::vector_reduce_and:2188 case Intrinsic::vector_reduce_or:2189 case Intrinsic::vector_reduce_smin:2190 case Intrinsic::vector_reduce_smax:2191 case Intrinsic::vector_reduce_umin:2192 case Intrinsic::vector_reduce_umax:2193 return SplatVal;2194 case Intrinsic::vector_reduce_add:2195 if (SplatVal->isNullValue())2196 return SplatVal;2197 break;2198 case Intrinsic::vector_reduce_mul:2199 if (SplatVal->isNullValue() || SplatVal->isOneValue())2200 return SplatVal;2201 break;2202 case Intrinsic::vector_reduce_xor:2203 if (SplatVal->isNullValue())2204 return SplatVal;2205 if (OpVT->getElementCount().isKnownMultipleOf(2))2206 return Constant::getNullValue(OpVT->getElementType());2207 break;2208 }2209 }2210 2211 FixedVectorType *VT = dyn_cast<FixedVectorType>(OpVT);2212 if (!VT)2213 return nullptr;2214 2215 // TODO: Handle undef.2216 auto *EltC = dyn_cast_or_null<ConstantInt>(Op->getAggregateElement(0U));2217 if (!EltC)2218 return nullptr;2219 2220 APInt Acc = EltC->getValue();2221 for (unsigned I = 1, E = VT->getNumElements(); I != E; I++) {2222 if (!(EltC = dyn_cast_or_null<ConstantInt>(Op->getAggregateElement(I))))2223 return nullptr;2224 const APInt &X = EltC->getValue();2225 switch (IID) {2226 case Intrinsic::vector_reduce_add:2227 Acc = Acc + X;2228 break;2229 case Intrinsic::vector_reduce_mul:2230 Acc = Acc * X;2231 break;2232 case Intrinsic::vector_reduce_and:2233 Acc = Acc & X;2234 break;2235 case Intrinsic::vector_reduce_or:2236 Acc = Acc | X;2237 break;2238 case Intrinsic::vector_reduce_xor:2239 Acc = Acc ^ X;2240 break;2241 case Intrinsic::vector_reduce_smin:2242 Acc = APIntOps::smin(Acc, X);2243 break;2244 case Intrinsic::vector_reduce_smax:2245 Acc = APIntOps::smax(Acc, X);2246 break;2247 case Intrinsic::vector_reduce_umin:2248 Acc = APIntOps::umin(Acc, X);2249 break;2250 case Intrinsic::vector_reduce_umax:2251 Acc = APIntOps::umax(Acc, X);2252 break;2253 }2254 }2255 2256 return ConstantInt::get(Op->getContext(), Acc);2257}2258 2259/// Attempt to fold an SSE floating point to integer conversion of a constant2260/// floating point. If roundTowardZero is false, the default IEEE rounding is2261/// used (toward nearest, ties to even). This matches the behavior of the2262/// non-truncating SSE instructions in the default rounding mode. The desired2263/// integer type Ty is used to select how many bits are available for the2264/// result. Returns null if the conversion cannot be performed, otherwise2265/// returns the Constant value resulting from the conversion.2266Constant *ConstantFoldSSEConvertToInt(const APFloat &Val, bool roundTowardZero,2267 Type *Ty, bool IsSigned) {2268 // All of these conversion intrinsics form an integer of at most 64bits.2269 unsigned ResultWidth = Ty->getIntegerBitWidth();2270 assert(ResultWidth <= 64 &&2271 "Can only constant fold conversions to 64 and 32 bit ints");2272 2273 uint64_t UIntVal;2274 bool isExact = false;2275 APFloat::roundingMode mode = roundTowardZero? APFloat::rmTowardZero2276 : APFloat::rmNearestTiesToEven;2277 APFloat::opStatus status =2278 Val.convertToInteger(MutableArrayRef(UIntVal), ResultWidth,2279 IsSigned, mode, &isExact);2280 if (status != APFloat::opOK &&2281 (!roundTowardZero || status != APFloat::opInexact))2282 return nullptr;2283 return ConstantInt::get(Ty, UIntVal, IsSigned);2284}2285 2286double getValueAsDouble(ConstantFP *Op) {2287 Type *Ty = Op->getType();2288 2289 if (Ty->isBFloatTy() || Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy())2290 return Op->getValueAPF().convertToDouble();2291 2292 bool unused;2293 APFloat APF = Op->getValueAPF();2294 APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &unused);2295 return APF.convertToDouble();2296}2297 2298static bool getConstIntOrUndef(Value *Op, const APInt *&C) {2299 if (auto *CI = dyn_cast<ConstantInt>(Op)) {2300 C = &CI->getValue();2301 return true;2302 }2303 if (isa<UndefValue>(Op)) {2304 C = nullptr;2305 return true;2306 }2307 return false;2308}2309 2310/// Checks if the given intrinsic call, which evaluates to constant, is allowed2311/// to be folded.2312///2313/// \param CI Constrained intrinsic call.2314/// \param St Exception flags raised during constant evaluation.2315static bool mayFoldConstrained(ConstrainedFPIntrinsic *CI,2316 APFloat::opStatus St) {2317 std::optional<RoundingMode> ORM = CI->getRoundingMode();2318 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();2319 2320 // If the operation does not change exception status flags, it is safe2321 // to fold.2322 if (St == APFloat::opStatus::opOK)2323 return true;2324 2325 // If evaluation raised FP exception, the result can depend on rounding2326 // mode. If the latter is unknown, folding is not possible.2327 if (ORM == RoundingMode::Dynamic)2328 return false;2329 2330 // If FP exceptions are ignored, fold the call, even if such exception is2331 // raised.2332 if (EB && *EB != fp::ExceptionBehavior::ebStrict)2333 return true;2334 2335 // Leave the calculation for runtime so that exception flags be correctly set2336 // in hardware.2337 return false;2338}2339 2340/// Returns the rounding mode that should be used for constant evaluation.2341static RoundingMode2342getEvaluationRoundingMode(const ConstrainedFPIntrinsic *CI) {2343 std::optional<RoundingMode> ORM = CI->getRoundingMode();2344 if (!ORM || *ORM == RoundingMode::Dynamic)2345 // Even if the rounding mode is unknown, try evaluating the operation.2346 // If it does not raise inexact exception, rounding was not applied,2347 // so the result is exact and does not depend on rounding mode. Whether2348 // other FP exceptions are raised, it does not depend on rounding mode.2349 return RoundingMode::NearestTiesToEven;2350 return *ORM;2351}2352 2353/// Try to constant fold llvm.canonicalize for the given caller and value.2354static Constant *constantFoldCanonicalize(const Type *Ty, const CallBase *CI,2355 const APFloat &Src) {2356 // Zero, positive and negative, is always OK to fold.2357 if (Src.isZero()) {2358 // Get a fresh 0, since ppc_fp128 does have non-canonical zeros.2359 return ConstantFP::get(2360 CI->getContext(),2361 APFloat::getZero(Src.getSemantics(), Src.isNegative()));2362 }2363 2364 if (!Ty->isIEEELikeFPTy())2365 return nullptr;2366 2367 // Zero is always canonical and the sign must be preserved.2368 //2369 // Denorms and nans may have special encodings, but it should be OK to fold a2370 // totally average number.2371 if (Src.isNormal() || Src.isInfinity())2372 return ConstantFP::get(CI->getContext(), Src);2373 2374 if (Src.isDenormal() && CI->getParent() && CI->getFunction()) {2375 DenormalMode DenormMode =2376 CI->getFunction()->getDenormalMode(Src.getSemantics());2377 2378 if (DenormMode == DenormalMode::getIEEE())2379 return ConstantFP::get(CI->getContext(), Src);2380 2381 if (DenormMode.Input == DenormalMode::Dynamic)2382 return nullptr;2383 2384 // If we know if either input or output is flushed, we can fold.2385 if ((DenormMode.Input == DenormalMode::Dynamic &&2386 DenormMode.Output == DenormalMode::IEEE) ||2387 (DenormMode.Input == DenormalMode::IEEE &&2388 DenormMode.Output == DenormalMode::Dynamic))2389 return nullptr;2390 2391 bool IsPositive =2392 (!Src.isNegative() || DenormMode.Input == DenormalMode::PositiveZero ||2393 (DenormMode.Output == DenormalMode::PositiveZero &&2394 DenormMode.Input == DenormalMode::IEEE));2395 2396 return ConstantFP::get(CI->getContext(),2397 APFloat::getZero(Src.getSemantics(), !IsPositive));2398 }2399 2400 return nullptr;2401}2402 2403static Constant *ConstantFoldScalarCall1(StringRef Name,2404 Intrinsic::ID IntrinsicID,2405 Type *Ty,2406 ArrayRef<Constant *> Operands,2407 const TargetLibraryInfo *TLI,2408 const CallBase *Call) {2409 assert(Operands.size() == 1 && "Wrong number of operands.");2410 2411 if (IntrinsicID == Intrinsic::is_constant) {2412 // We know we have a "Constant" argument. But we want to only2413 // return true for manifest constants, not those that depend on2414 // constants with unknowable values, e.g. GlobalValue or BlockAddress.2415 if (Operands[0]->isManifestConstant())2416 return ConstantInt::getTrue(Ty->getContext());2417 return nullptr;2418 }2419 2420 if (isa<UndefValue>(Operands[0])) {2421 // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.2422 // ctpop() is between 0 and bitwidth, pick 0 for undef.2423 // fptoui.sat and fptosi.sat can always fold to zero (for a zero input).2424 if (IntrinsicID == Intrinsic::cos ||2425 IntrinsicID == Intrinsic::ctpop ||2426 IntrinsicID == Intrinsic::fptoui_sat ||2427 IntrinsicID == Intrinsic::fptosi_sat ||2428 IntrinsicID == Intrinsic::canonicalize)2429 return Constant::getNullValue(Ty);2430 if (IntrinsicID == Intrinsic::bswap ||2431 IntrinsicID == Intrinsic::bitreverse ||2432 IntrinsicID == Intrinsic::launder_invariant_group ||2433 IntrinsicID == Intrinsic::strip_invariant_group)2434 return Operands[0];2435 }2436 2437 if (isa<ConstantPointerNull>(Operands[0])) {2438 // launder(null) == null == strip(null) iff in addrspace 02439 if (IntrinsicID == Intrinsic::launder_invariant_group ||2440 IntrinsicID == Intrinsic::strip_invariant_group) {2441 // If instruction is not yet put in a basic block (e.g. when cloning2442 // a function during inlining), Call's caller may not be available.2443 // So check Call's BB first before querying Call->getCaller.2444 const Function *Caller =2445 Call->getParent() ? Call->getCaller() : nullptr;2446 if (Caller &&2447 !NullPointerIsDefined(2448 Caller, Operands[0]->getType()->getPointerAddressSpace())) {2449 return Operands[0];2450 }2451 return nullptr;2452 }2453 }2454 2455 if (auto *Op = dyn_cast<ConstantFP>(Operands[0])) {2456 if (IntrinsicID == Intrinsic::convert_to_fp16) {2457 APFloat Val(Op->getValueAPF());2458 2459 bool lost = false;2460 Val.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &lost);2461 2462 return ConstantInt::get(Ty->getContext(), Val.bitcastToAPInt());2463 }2464 2465 APFloat U = Op->getValueAPF();2466 2467 if (IntrinsicID == Intrinsic::wasm_trunc_signed ||2468 IntrinsicID == Intrinsic::wasm_trunc_unsigned) {2469 bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed;2470 2471 if (U.isNaN())2472 return nullptr;2473 2474 unsigned Width = Ty->getIntegerBitWidth();2475 APSInt Int(Width, !Signed);2476 bool IsExact = false;2477 APFloat::opStatus Status =2478 U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);2479 2480 if (Status == APFloat::opOK || Status == APFloat::opInexact)2481 return ConstantInt::get(Ty, Int);2482 2483 return nullptr;2484 }2485 2486 if (IntrinsicID == Intrinsic::fptoui_sat ||2487 IntrinsicID == Intrinsic::fptosi_sat) {2488 // convertToInteger() already has the desired saturation semantics.2489 APSInt Int(Ty->getIntegerBitWidth(),2490 IntrinsicID == Intrinsic::fptoui_sat);2491 bool IsExact;2492 U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);2493 return ConstantInt::get(Ty, Int);2494 }2495 2496 if (IntrinsicID == Intrinsic::canonicalize)2497 return constantFoldCanonicalize(Ty, Call, U);2498 2499#if defined(HAS_IEE754_FLOAT128) && defined(HAS_LOGF128)2500 if (Ty->isFP128Ty()) {2501 if (IntrinsicID == Intrinsic::log) {2502 float128 Result = logf128(Op->getValueAPF().convertToQuad());2503 return GetConstantFoldFPValue128(Result, Ty);2504 }2505 2506 LibFunc Fp128Func = NotLibFunc;2507 if (TLI && TLI->getLibFunc(Name, Fp128Func) && TLI->has(Fp128Func) &&2508 Fp128Func == LibFunc_logl)2509 return ConstantFoldFP128(logf128, Op->getValueAPF(), Ty);2510 }2511#endif2512 2513 if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy() &&2514 !Ty->isIntegerTy())2515 return nullptr;2516 2517 // Use internal versions of these intrinsics.2518 2519 if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {2520 U.roundToIntegral(APFloat::rmNearestTiesToEven);2521 return ConstantFP::get(Ty->getContext(), U);2522 }2523 2524 if (IntrinsicID == Intrinsic::round) {2525 U.roundToIntegral(APFloat::rmNearestTiesToAway);2526 return ConstantFP::get(Ty->getContext(), U);2527 }2528 2529 if (IntrinsicID == Intrinsic::roundeven) {2530 U.roundToIntegral(APFloat::rmNearestTiesToEven);2531 return ConstantFP::get(Ty->getContext(), U);2532 }2533 2534 if (IntrinsicID == Intrinsic::ceil) {2535 U.roundToIntegral(APFloat::rmTowardPositive);2536 return ConstantFP::get(Ty->getContext(), U);2537 }2538 2539 if (IntrinsicID == Intrinsic::floor) {2540 U.roundToIntegral(APFloat::rmTowardNegative);2541 return ConstantFP::get(Ty->getContext(), U);2542 }2543 2544 if (IntrinsicID == Intrinsic::trunc) {2545 U.roundToIntegral(APFloat::rmTowardZero);2546 return ConstantFP::get(Ty->getContext(), U);2547 }2548 2549 if (IntrinsicID == Intrinsic::fabs) {2550 U.clearSign();2551 return ConstantFP::get(Ty->getContext(), U);2552 }2553 2554 if (IntrinsicID == Intrinsic::amdgcn_fract) {2555 // The v_fract instruction behaves like the OpenCL spec, which defines2556 // fract(x) as fmin(x - floor(x), 0x1.fffffep-1f): "The min() operator is2557 // there to prevent fract(-small) from returning 1.0. It returns the2558 // largest positive floating-point number less than 1.0."2559 APFloat FloorU(U);2560 FloorU.roundToIntegral(APFloat::rmTowardNegative);2561 APFloat FractU(U - FloorU);2562 APFloat AlmostOne(U.getSemantics(), 1);2563 AlmostOne.next(/*nextDown*/ true);2564 return ConstantFP::get(Ty->getContext(), minimum(FractU, AlmostOne));2565 }2566 2567 // Rounding operations (floor, trunc, ceil, round and nearbyint) do not2568 // raise FP exceptions, unless the argument is signaling NaN.2569 2570 std::optional<APFloat::roundingMode> RM;2571 switch (IntrinsicID) {2572 default:2573 break;2574 case Intrinsic::experimental_constrained_nearbyint:2575 case Intrinsic::experimental_constrained_rint: {2576 auto CI = cast<ConstrainedFPIntrinsic>(Call);2577 RM = CI->getRoundingMode();2578 if (!RM || *RM == RoundingMode::Dynamic)2579 return nullptr;2580 break;2581 }2582 case Intrinsic::experimental_constrained_round:2583 RM = APFloat::rmNearestTiesToAway;2584 break;2585 case Intrinsic::experimental_constrained_ceil:2586 RM = APFloat::rmTowardPositive;2587 break;2588 case Intrinsic::experimental_constrained_floor:2589 RM = APFloat::rmTowardNegative;2590 break;2591 case Intrinsic::experimental_constrained_trunc:2592 RM = APFloat::rmTowardZero;2593 break;2594 }2595 if (RM) {2596 auto CI = cast<ConstrainedFPIntrinsic>(Call);2597 if (U.isFinite()) {2598 APFloat::opStatus St = U.roundToIntegral(*RM);2599 if (IntrinsicID == Intrinsic::experimental_constrained_rint &&2600 St == APFloat::opInexact) {2601 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();2602 if (EB == fp::ebStrict)2603 return nullptr;2604 }2605 } else if (U.isSignaling()) {2606 std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior();2607 if (EB && *EB != fp::ebIgnore)2608 return nullptr;2609 U = APFloat::getQNaN(U.getSemantics());2610 }2611 return ConstantFP::get(Ty->getContext(), U);2612 }2613 2614 // NVVM float/double to signed/unsigned int32/int64 conversions:2615 switch (IntrinsicID) {2616 // f2i2617 case Intrinsic::nvvm_f2i_rm:2618 case Intrinsic::nvvm_f2i_rn:2619 case Intrinsic::nvvm_f2i_rp:2620 case Intrinsic::nvvm_f2i_rz:2621 case Intrinsic::nvvm_f2i_rm_ftz:2622 case Intrinsic::nvvm_f2i_rn_ftz:2623 case Intrinsic::nvvm_f2i_rp_ftz:2624 case Intrinsic::nvvm_f2i_rz_ftz:2625 // f2ui2626 case Intrinsic::nvvm_f2ui_rm:2627 case Intrinsic::nvvm_f2ui_rn:2628 case Intrinsic::nvvm_f2ui_rp:2629 case Intrinsic::nvvm_f2ui_rz:2630 case Intrinsic::nvvm_f2ui_rm_ftz:2631 case Intrinsic::nvvm_f2ui_rn_ftz:2632 case Intrinsic::nvvm_f2ui_rp_ftz:2633 case Intrinsic::nvvm_f2ui_rz_ftz:2634 // d2i2635 case Intrinsic::nvvm_d2i_rm:2636 case Intrinsic::nvvm_d2i_rn:2637 case Intrinsic::nvvm_d2i_rp:2638 case Intrinsic::nvvm_d2i_rz:2639 // d2ui2640 case Intrinsic::nvvm_d2ui_rm:2641 case Intrinsic::nvvm_d2ui_rn:2642 case Intrinsic::nvvm_d2ui_rp:2643 case Intrinsic::nvvm_d2ui_rz:2644 // f2ll2645 case Intrinsic::nvvm_f2ll_rm:2646 case Intrinsic::nvvm_f2ll_rn:2647 case Intrinsic::nvvm_f2ll_rp:2648 case Intrinsic::nvvm_f2ll_rz:2649 case Intrinsic::nvvm_f2ll_rm_ftz:2650 case Intrinsic::nvvm_f2ll_rn_ftz:2651 case Intrinsic::nvvm_f2ll_rp_ftz:2652 case Intrinsic::nvvm_f2ll_rz_ftz:2653 // f2ull2654 case Intrinsic::nvvm_f2ull_rm:2655 case Intrinsic::nvvm_f2ull_rn:2656 case Intrinsic::nvvm_f2ull_rp:2657 case Intrinsic::nvvm_f2ull_rz:2658 case Intrinsic::nvvm_f2ull_rm_ftz:2659 case Intrinsic::nvvm_f2ull_rn_ftz:2660 case Intrinsic::nvvm_f2ull_rp_ftz:2661 case Intrinsic::nvvm_f2ull_rz_ftz:2662 // d2ll2663 case Intrinsic::nvvm_d2ll_rm:2664 case Intrinsic::nvvm_d2ll_rn:2665 case Intrinsic::nvvm_d2ll_rp:2666 case Intrinsic::nvvm_d2ll_rz:2667 // d2ull2668 case Intrinsic::nvvm_d2ull_rm:2669 case Intrinsic::nvvm_d2ull_rn:2670 case Intrinsic::nvvm_d2ull_rp:2671 case Intrinsic::nvvm_d2ull_rz: {2672 // In float-to-integer conversion, NaN inputs are converted to 0.2673 if (U.isNaN()) {2674 // In float-to-integer conversion, NaN inputs are converted to 02675 // when the source and destination bitwidths are both less than 64.2676 if (nvvm::FPToIntegerIntrinsicNaNZero(IntrinsicID))2677 return ConstantInt::get(Ty, 0);2678 2679 // Otherwise, the most significant bit is set.2680 unsigned BitWidth = Ty->getIntegerBitWidth();2681 uint64_t Val = 1ULL << (BitWidth - 1);2682 return ConstantInt::get(Ty, APInt(BitWidth, Val, /*IsSigned=*/false));2683 }2684 2685 APFloat::roundingMode RMode =2686 nvvm::GetFPToIntegerRoundingMode(IntrinsicID);2687 bool IsFTZ = nvvm::FPToIntegerIntrinsicShouldFTZ(IntrinsicID);2688 bool IsSigned = nvvm::FPToIntegerIntrinsicResultIsSigned(IntrinsicID);2689 2690 APSInt ResInt(Ty->getIntegerBitWidth(), !IsSigned);2691 auto FloatToRound = IsFTZ ? FTZPreserveSign(U) : U;2692 2693 // Return max/min value for integers if the result is +/-inf or2694 // is too large to fit in the result's integer bitwidth.2695 bool IsExact = false;2696 FloatToRound.convertToInteger(ResInt, RMode, &IsExact);2697 return ConstantInt::get(Ty, ResInt);2698 }2699 }2700 2701 /// We only fold functions with finite arguments. Folding NaN and inf is2702 /// likely to be aborted with an exception anyway, and some host libms2703 /// have known errors raising exceptions.2704 if (!U.isFinite())2705 return nullptr;2706 2707 /// Currently APFloat versions of these functions do not exist, so we use2708 /// the host native double versions. Float versions are not called2709 /// directly but for all these it is true (float)(f((double)arg)) ==2710 /// f(arg). Long double not supported yet.2711 const APFloat &APF = Op->getValueAPF();2712 2713 switch (IntrinsicID) {2714 default: break;2715 case Intrinsic::log:2716 return ConstantFoldFP(log, APF, Ty);2717 case Intrinsic::log2:2718 // TODO: What about hosts that lack a C99 library?2719 return ConstantFoldFP(log2, APF, Ty);2720 case Intrinsic::log10:2721 // TODO: What about hosts that lack a C99 library?2722 return ConstantFoldFP(log10, APF, Ty);2723 case Intrinsic::exp:2724 return ConstantFoldFP(exp, APF, Ty);2725 case Intrinsic::exp2:2726 // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.2727 return ConstantFoldBinaryFP(pow, APFloat(2.0), APF, Ty);2728 case Intrinsic::exp10:2729 // Fold exp10(x) as pow(10, x), in case the host lacks a C99 library.2730 return ConstantFoldBinaryFP(pow, APFloat(10.0), APF, Ty);2731 case Intrinsic::sin:2732 return ConstantFoldFP(sin, APF, Ty);2733 case Intrinsic::cos:2734 return ConstantFoldFP(cos, APF, Ty);2735 case Intrinsic::sinh:2736 return ConstantFoldFP(sinh, APF, Ty);2737 case Intrinsic::cosh:2738 return ConstantFoldFP(cosh, APF, Ty);2739 case Intrinsic::atan:2740 // Implement optional behavior from C's Annex F for +/-0.0.2741 if (U.isZero())2742 return ConstantFP::get(Ty->getContext(), U);2743 return ConstantFoldFP(atan, APF, Ty);2744 case Intrinsic::sqrt:2745 return ConstantFoldFP(sqrt, APF, Ty);2746 2747 // NVVM Intrinsics:2748 case Intrinsic::nvvm_ceil_ftz_f:2749 case Intrinsic::nvvm_ceil_f:2750 case Intrinsic::nvvm_ceil_d:2751 return ConstantFoldFP(2752 ceil, APF, Ty,2753 nvvm::GetNVVMDenormMode(2754 nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));2755 2756 case Intrinsic::nvvm_fabs_ftz:2757 case Intrinsic::nvvm_fabs:2758 return ConstantFoldFP(2759 fabs, APF, Ty,2760 nvvm::GetNVVMDenormMode(2761 nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));2762 2763 case Intrinsic::nvvm_floor_ftz_f:2764 case Intrinsic::nvvm_floor_f:2765 case Intrinsic::nvvm_floor_d:2766 return ConstantFoldFP(2767 floor, APF, Ty,2768 nvvm::GetNVVMDenormMode(2769 nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));2770 2771 case Intrinsic::nvvm_rcp_rm_ftz_f:2772 case Intrinsic::nvvm_rcp_rn_ftz_f:2773 case Intrinsic::nvvm_rcp_rp_ftz_f:2774 case Intrinsic::nvvm_rcp_rz_ftz_f:2775 case Intrinsic::nvvm_rcp_rm_d:2776 case Intrinsic::nvvm_rcp_rm_f:2777 case Intrinsic::nvvm_rcp_rn_d:2778 case Intrinsic::nvvm_rcp_rn_f:2779 case Intrinsic::nvvm_rcp_rp_d:2780 case Intrinsic::nvvm_rcp_rp_f:2781 case Intrinsic::nvvm_rcp_rz_d:2782 case Intrinsic::nvvm_rcp_rz_f: {2783 APFloat::roundingMode RoundMode = nvvm::GetRCPRoundingMode(IntrinsicID);2784 bool IsFTZ = nvvm::RCPShouldFTZ(IntrinsicID);2785 2786 auto Denominator = IsFTZ ? FTZPreserveSign(APF) : APF;2787 APFloat Res = APFloat::getOne(APF.getSemantics());2788 APFloat::opStatus Status = Res.divide(Denominator, RoundMode);2789 2790 if (Status == APFloat::opOK || Status == APFloat::opInexact) {2791 if (IsFTZ)2792 Res = FTZPreserveSign(Res);2793 return ConstantFP::get(Ty->getContext(), Res);2794 }2795 return nullptr;2796 }2797 2798 case Intrinsic::nvvm_round_ftz_f:2799 case Intrinsic::nvvm_round_f:2800 case Intrinsic::nvvm_round_d: {2801 // nvvm_round is lowered to PTX cvt.rni, which will round to nearest2802 // integer, choosing even integer if source is equidistant between two2803 // integers, so the semantics are closer to "rint" rather than "round".2804 bool IsFTZ = nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID);2805 auto V = IsFTZ ? FTZPreserveSign(APF) : APF;2806 V.roundToIntegral(APFloat::rmNearestTiesToEven);2807 return ConstantFP::get(Ty->getContext(), V);2808 }2809 2810 case Intrinsic::nvvm_saturate_ftz_f:2811 case Intrinsic::nvvm_saturate_d:2812 case Intrinsic::nvvm_saturate_f: {2813 bool IsFTZ = nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID);2814 auto V = IsFTZ ? FTZPreserveSign(APF) : APF;2815 if (V.isNegative() || V.isZero() || V.isNaN())2816 return ConstantFP::getZero(Ty);2817 APFloat One = APFloat::getOne(APF.getSemantics());2818 if (V > One)2819 return ConstantFP::get(Ty->getContext(), One);2820 return ConstantFP::get(Ty->getContext(), APF);2821 }2822 2823 case Intrinsic::nvvm_sqrt_rn_ftz_f:2824 case Intrinsic::nvvm_sqrt_f:2825 case Intrinsic::nvvm_sqrt_rn_d:2826 case Intrinsic::nvvm_sqrt_rn_f:2827 if (APF.isNegative())2828 return nullptr;2829 return ConstantFoldFP(2830 sqrt, APF, Ty,2831 nvvm::GetNVVMDenormMode(2832 nvvm::UnaryMathIntrinsicShouldFTZ(IntrinsicID)));2833 2834 // AMDGCN Intrinsics:2835 case Intrinsic::amdgcn_cos:2836 case Intrinsic::amdgcn_sin: {2837 double V = getValueAsDouble(Op);2838 if (V < -256.0 || V > 256.0)2839 // The gfx8 and gfx9 architectures handle arguments outside the range2840 // [-256, 256] differently. This should be a rare case so bail out2841 // rather than trying to handle the difference.2842 return nullptr;2843 bool IsCos = IntrinsicID == Intrinsic::amdgcn_cos;2844 double V4 = V * 4.0;2845 if (V4 == floor(V4)) {2846 // Force exact results for quarter-integer inputs.2847 const double SinVals[4] = { 0.0, 1.0, 0.0, -1.0 };2848 V = SinVals[((int)V4 + (IsCos ? 1 : 0)) & 3];2849 } else {2850 if (IsCos)2851 V = cos(V * 2.0 * numbers::pi);2852 else2853 V = sin(V * 2.0 * numbers::pi);2854 }2855 return GetConstantFoldFPValue(V, Ty);2856 }2857 }2858 2859 if (!TLI)2860 return nullptr;2861 2862 LibFunc Func = NotLibFunc;2863 if (!TLI->getLibFunc(Name, Func))2864 return nullptr;2865 2866 switch (Func) {2867 default:2868 break;2869 case LibFunc_acos:2870 case LibFunc_acosf:2871 case LibFunc_acos_finite:2872 case LibFunc_acosf_finite:2873 if (TLI->has(Func))2874 return ConstantFoldFP(acos, APF, Ty);2875 break;2876 case LibFunc_asin:2877 case LibFunc_asinf:2878 case LibFunc_asin_finite:2879 case LibFunc_asinf_finite:2880 if (TLI->has(Func))2881 return ConstantFoldFP(asin, APF, Ty);2882 break;2883 case LibFunc_atan:2884 case LibFunc_atanf:2885 // Implement optional behavior from C's Annex F for +/-0.0.2886 if (U.isZero())2887 return ConstantFP::get(Ty->getContext(), U);2888 if (TLI->has(Func))2889 return ConstantFoldFP(atan, APF, Ty);2890 break;2891 case LibFunc_ceil:2892 case LibFunc_ceilf:2893 if (TLI->has(Func)) {2894 U.roundToIntegral(APFloat::rmTowardPositive);2895 return ConstantFP::get(Ty->getContext(), U);2896 }2897 break;2898 case LibFunc_cos:2899 case LibFunc_cosf:2900 if (TLI->has(Func))2901 return ConstantFoldFP(cos, APF, Ty);2902 break;2903 case LibFunc_cosh:2904 case LibFunc_coshf:2905 case LibFunc_cosh_finite:2906 case LibFunc_coshf_finite:2907 if (TLI->has(Func))2908 return ConstantFoldFP(cosh, APF, Ty);2909 break;2910 case LibFunc_exp:2911 case LibFunc_expf:2912 case LibFunc_exp_finite:2913 case LibFunc_expf_finite:2914 if (TLI->has(Func))2915 return ConstantFoldFP(exp, APF, Ty);2916 break;2917 case LibFunc_exp2:2918 case LibFunc_exp2f:2919 case LibFunc_exp2_finite:2920 case LibFunc_exp2f_finite:2921 if (TLI->has(Func))2922 // Fold exp2(x) as pow(2, x), in case the host lacks a C99 library.2923 return ConstantFoldBinaryFP(pow, APFloat(2.0), APF, Ty);2924 break;2925 case LibFunc_fabs:2926 case LibFunc_fabsf:2927 if (TLI->has(Func)) {2928 U.clearSign();2929 return ConstantFP::get(Ty->getContext(), U);2930 }2931 break;2932 case LibFunc_floor:2933 case LibFunc_floorf:2934 if (TLI->has(Func)) {2935 U.roundToIntegral(APFloat::rmTowardNegative);2936 return ConstantFP::get(Ty->getContext(), U);2937 }2938 break;2939 case LibFunc_log:2940 case LibFunc_logf:2941 case LibFunc_log_finite:2942 case LibFunc_logf_finite:2943 if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))2944 return ConstantFoldFP(log, APF, Ty);2945 break;2946 case LibFunc_log2:2947 case LibFunc_log2f:2948 case LibFunc_log2_finite:2949 case LibFunc_log2f_finite:2950 if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))2951 // TODO: What about hosts that lack a C99 library?2952 return ConstantFoldFP(log2, APF, Ty);2953 break;2954 case LibFunc_log10:2955 case LibFunc_log10f:2956 case LibFunc_log10_finite:2957 case LibFunc_log10f_finite:2958 if (!APF.isNegative() && !APF.isZero() && TLI->has(Func))2959 // TODO: What about hosts that lack a C99 library?2960 return ConstantFoldFP(log10, APF, Ty);2961 break;2962 case LibFunc_ilogb:2963 case LibFunc_ilogbf:2964 if (!APF.isZero() && TLI->has(Func))2965 return ConstantInt::get(Ty, ilogb(APF), true);2966 break;2967 case LibFunc_logb:2968 case LibFunc_logbf:2969 if (!APF.isZero() && TLI->has(Func))2970 return ConstantFoldFP(logb, APF, Ty);2971 break;2972 case LibFunc_log1p:2973 case LibFunc_log1pf:2974 // Implement optional behavior from C's Annex F for +/-0.0.2975 if (U.isZero())2976 return ConstantFP::get(Ty->getContext(), U);2977 if (APF > APFloat::getOne(APF.getSemantics(), true) && TLI->has(Func))2978 return ConstantFoldFP(log1p, APF, Ty);2979 break;2980 case LibFunc_logl:2981 return nullptr;2982 case LibFunc_erf:2983 case LibFunc_erff:2984 if (TLI->has(Func))2985 return ConstantFoldFP(erf, APF, Ty);2986 break;2987 case LibFunc_nearbyint:2988 case LibFunc_nearbyintf:2989 case LibFunc_rint:2990 case LibFunc_rintf:2991 if (TLI->has(Func)) {2992 U.roundToIntegral(APFloat::rmNearestTiesToEven);2993 return ConstantFP::get(Ty->getContext(), U);2994 }2995 break;2996 case LibFunc_round:2997 case LibFunc_roundf:2998 if (TLI->has(Func)) {2999 U.roundToIntegral(APFloat::rmNearestTiesToAway);3000 return ConstantFP::get(Ty->getContext(), U);3001 }3002 break;3003 case LibFunc_sin:3004 case LibFunc_sinf:3005 if (TLI->has(Func))3006 return ConstantFoldFP(sin, APF, Ty);3007 break;3008 case LibFunc_sinh:3009 case LibFunc_sinhf:3010 case LibFunc_sinh_finite:3011 case LibFunc_sinhf_finite:3012 if (TLI->has(Func))3013 return ConstantFoldFP(sinh, APF, Ty);3014 break;3015 case LibFunc_sqrt:3016 case LibFunc_sqrtf:3017 if (!APF.isNegative() && TLI->has(Func))3018 return ConstantFoldFP(sqrt, APF, Ty);3019 break;3020 case LibFunc_tan:3021 case LibFunc_tanf:3022 if (TLI->has(Func))3023 return ConstantFoldFP(tan, APF, Ty);3024 break;3025 case LibFunc_tanh:3026 case LibFunc_tanhf:3027 if (TLI->has(Func))3028 return ConstantFoldFP(tanh, APF, Ty);3029 break;3030 case LibFunc_trunc:3031 case LibFunc_truncf:3032 if (TLI->has(Func)) {3033 U.roundToIntegral(APFloat::rmTowardZero);3034 return ConstantFP::get(Ty->getContext(), U);3035 }3036 break;3037 }3038 return nullptr;3039 }3040 3041 if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {3042 switch (IntrinsicID) {3043 case Intrinsic::bswap:3044 return ConstantInt::get(Ty->getContext(), Op->getValue().byteSwap());3045 case Intrinsic::ctpop:3046 return ConstantInt::get(Ty, Op->getValue().popcount());3047 case Intrinsic::bitreverse:3048 return ConstantInt::get(Ty->getContext(), Op->getValue().reverseBits());3049 case Intrinsic::convert_from_fp16: {3050 APFloat Val(APFloat::IEEEhalf(), Op->getValue());3051 3052 bool lost = false;3053 APFloat::opStatus status = Val.convert(3054 Ty->getFltSemantics(), APFloat::rmNearestTiesToEven, &lost);3055 3056 // Conversion is always precise.3057 (void)status;3058 assert(status != APFloat::opInexact && !lost &&3059 "Precision lost during fp16 constfolding");3060 3061 return ConstantFP::get(Ty->getContext(), Val);3062 }3063 3064 case Intrinsic::amdgcn_s_wqm: {3065 uint64_t Val = Op->getZExtValue();3066 Val |= (Val & 0x5555555555555555ULL) << 1 |3067 ((Val >> 1) & 0x5555555555555555ULL);3068 Val |= (Val & 0x3333333333333333ULL) << 2 |3069 ((Val >> 2) & 0x3333333333333333ULL);3070 return ConstantInt::get(Ty, Val);3071 }3072 3073 case Intrinsic::amdgcn_s_quadmask: {3074 uint64_t Val = Op->getZExtValue();3075 uint64_t QuadMask = 0;3076 for (unsigned I = 0; I < Op->getBitWidth() / 4; ++I, Val >>= 4) {3077 if (!(Val & 0xF))3078 continue;3079 3080 QuadMask |= (1ULL << I);3081 }3082 return ConstantInt::get(Ty, QuadMask);3083 }3084 3085 case Intrinsic::amdgcn_s_bitreplicate: {3086 uint64_t Val = Op->getZExtValue();3087 Val = (Val & 0x000000000000FFFFULL) | (Val & 0x00000000FFFF0000ULL) << 16;3088 Val = (Val & 0x000000FF000000FFULL) | (Val & 0x0000FF000000FF00ULL) << 8;3089 Val = (Val & 0x000F000F000F000FULL) | (Val & 0x00F000F000F000F0ULL) << 4;3090 Val = (Val & 0x0303030303030303ULL) | (Val & 0x0C0C0C0C0C0C0C0CULL) << 2;3091 Val = (Val & 0x1111111111111111ULL) | (Val & 0x2222222222222222ULL) << 1;3092 Val = Val | Val << 1;3093 return ConstantInt::get(Ty, Val);3094 }3095 }3096 }3097 3098 if (Operands[0]->getType()->isVectorTy()) {3099 auto *Op = cast<Constant>(Operands[0]);3100 switch (IntrinsicID) {3101 default: break;3102 case Intrinsic::vector_reduce_add:3103 case Intrinsic::vector_reduce_mul:3104 case Intrinsic::vector_reduce_and:3105 case Intrinsic::vector_reduce_or:3106 case Intrinsic::vector_reduce_xor:3107 case Intrinsic::vector_reduce_smin:3108 case Intrinsic::vector_reduce_smax:3109 case Intrinsic::vector_reduce_umin:3110 case Intrinsic::vector_reduce_umax:3111 if (Constant *C = constantFoldVectorReduce(IntrinsicID, Operands[0]))3112 return C;3113 break;3114 case Intrinsic::x86_sse_cvtss2si:3115 case Intrinsic::x86_sse_cvtss2si64:3116 case Intrinsic::x86_sse2_cvtsd2si:3117 case Intrinsic::x86_sse2_cvtsd2si64:3118 if (ConstantFP *FPOp =3119 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3120 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3121 /*roundTowardZero=*/false, Ty,3122 /*IsSigned*/true);3123 break;3124 case Intrinsic::x86_sse_cvttss2si:3125 case Intrinsic::x86_sse_cvttss2si64:3126 case Intrinsic::x86_sse2_cvttsd2si:3127 case Intrinsic::x86_sse2_cvttsd2si64:3128 if (ConstantFP *FPOp =3129 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3130 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3131 /*roundTowardZero=*/true, Ty,3132 /*IsSigned*/true);3133 break;3134 3135 case Intrinsic::wasm_anytrue:3136 return Op->isZeroValue() ? ConstantInt::get(Ty, 0)3137 : ConstantInt::get(Ty, 1);3138 3139 case Intrinsic::wasm_alltrue:3140 // Check each element individually3141 unsigned E = cast<FixedVectorType>(Op->getType())->getNumElements();3142 for (unsigned I = 0; I != E; ++I) {3143 Constant *Elt = Op->getAggregateElement(I);3144 // Return false as soon as we find a non-true element.3145 if (Elt && Elt->isZeroValue())3146 return ConstantInt::get(Ty, 0);3147 // Bail as soon as we find an element we cannot prove to be true.3148 if (!Elt || !isa<ConstantInt>(Elt))3149 return nullptr;3150 }3151 3152 return ConstantInt::get(Ty, 1);3153 }3154 }3155 3156 return nullptr;3157}3158 3159static Constant *evaluateCompare(const APFloat &Op1, const APFloat &Op2,3160 const ConstrainedFPIntrinsic *Call) {3161 APFloat::opStatus St = APFloat::opOK;3162 auto *FCmp = cast<ConstrainedFPCmpIntrinsic>(Call);3163 FCmpInst::Predicate Cond = FCmp->getPredicate();3164 if (FCmp->isSignaling()) {3165 if (Op1.isNaN() || Op2.isNaN())3166 St = APFloat::opInvalidOp;3167 } else {3168 if (Op1.isSignaling() || Op2.isSignaling())3169 St = APFloat::opInvalidOp;3170 }3171 bool Result = FCmpInst::compare(Op1, Op2, Cond);3172 if (mayFoldConstrained(const_cast<ConstrainedFPCmpIntrinsic *>(FCmp), St))3173 return ConstantInt::get(Call->getType()->getScalarType(), Result);3174 return nullptr;3175}3176 3177static Constant *ConstantFoldLibCall2(StringRef Name, Type *Ty,3178 ArrayRef<Constant *> Operands,3179 const TargetLibraryInfo *TLI) {3180 if (!TLI)3181 return nullptr;3182 3183 LibFunc Func = NotLibFunc;3184 if (!TLI->getLibFunc(Name, Func))3185 return nullptr;3186 3187 const auto *Op1 = dyn_cast<ConstantFP>(Operands[0]);3188 if (!Op1)3189 return nullptr;3190 3191 const auto *Op2 = dyn_cast<ConstantFP>(Operands[1]);3192 if (!Op2)3193 return nullptr;3194 3195 const APFloat &Op1V = Op1->getValueAPF();3196 const APFloat &Op2V = Op2->getValueAPF();3197 3198 switch (Func) {3199 default:3200 break;3201 case LibFunc_pow:3202 case LibFunc_powf:3203 case LibFunc_pow_finite:3204 case LibFunc_powf_finite:3205 if (TLI->has(Func))3206 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);3207 break;3208 case LibFunc_fmod:3209 case LibFunc_fmodf:3210 if (TLI->has(Func)) {3211 APFloat V = Op1->getValueAPF();3212 if (APFloat::opStatus::opOK == V.mod(Op2->getValueAPF()))3213 return ConstantFP::get(Ty->getContext(), V);3214 }3215 break;3216 case LibFunc_remainder:3217 case LibFunc_remainderf:3218 if (TLI->has(Func)) {3219 APFloat V = Op1->getValueAPF();3220 if (APFloat::opStatus::opOK == V.remainder(Op2->getValueAPF()))3221 return ConstantFP::get(Ty->getContext(), V);3222 }3223 break;3224 case LibFunc_atan2:3225 case LibFunc_atan2f:3226 // atan2(+/-0.0, +/-0.0) is known to raise an exception on some libm3227 // (Solaris), so we do not assume a known result for that.3228 if (Op1V.isZero() && Op2V.isZero())3229 return nullptr;3230 [[fallthrough]];3231 case LibFunc_atan2_finite:3232 case LibFunc_atan2f_finite:3233 if (TLI->has(Func))3234 return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);3235 break;3236 }3237 3238 return nullptr;3239}3240 3241static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,3242 ArrayRef<Constant *> Operands,3243 const CallBase *Call) {3244 assert(Operands.size() == 2 && "Wrong number of operands.");3245 3246 if (Ty->isFloatingPointTy()) {3247 // TODO: We should have undef handling for all of the FP intrinsics that3248 // are attempted to be folded in this function.3249 bool IsOp0Undef = isa<UndefValue>(Operands[0]);3250 bool IsOp1Undef = isa<UndefValue>(Operands[1]);3251 switch (IntrinsicID) {3252 case Intrinsic::maxnum:3253 case Intrinsic::minnum:3254 case Intrinsic::maximum:3255 case Intrinsic::minimum:3256 case Intrinsic::maximumnum:3257 case Intrinsic::minimumnum:3258 case Intrinsic::nvvm_fmax_d:3259 case Intrinsic::nvvm_fmin_d:3260 // If one argument is undef, return the other argument.3261 if (IsOp0Undef)3262 return Operands[1];3263 if (IsOp1Undef)3264 return Operands[0];3265 break;3266 3267 case Intrinsic::nvvm_fmax_f:3268 case Intrinsic::nvvm_fmax_ftz_f:3269 case Intrinsic::nvvm_fmax_ftz_nan_f:3270 case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:3271 case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:3272 case Intrinsic::nvvm_fmax_nan_f:3273 case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:3274 case Intrinsic::nvvm_fmax_xorsign_abs_f:3275 3276 case Intrinsic::nvvm_fmin_f:3277 case Intrinsic::nvvm_fmin_ftz_f:3278 case Intrinsic::nvvm_fmin_ftz_nan_f:3279 case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:3280 case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:3281 case Intrinsic::nvvm_fmin_nan_f:3282 case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:3283 case Intrinsic::nvvm_fmin_xorsign_abs_f:3284 // If one arg is undef, the other arg can be returned only if it is3285 // constant, as we may need to flush it to sign-preserving zero or3286 // canonicalize the NaN.3287 if (!IsOp0Undef && !IsOp1Undef)3288 break;3289 if (auto *Op = dyn_cast<ConstantFP>(Operands[IsOp0Undef ? 1 : 0])) {3290 if (Op->isNaN()) {3291 APInt NVCanonicalNaN(32, 0x7fffffff);3292 return ConstantFP::get(3293 Ty, APFloat(Ty->getFltSemantics(), NVCanonicalNaN));3294 }3295 if (nvvm::FMinFMaxShouldFTZ(IntrinsicID))3296 return ConstantFP::get(Ty, FTZPreserveSign(Op->getValueAPF()));3297 else3298 return Op;3299 }3300 break;3301 }3302 }3303 3304 if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {3305 const APFloat &Op1V = Op1->getValueAPF();3306 3307 if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {3308 if (Op2->getType() != Op1->getType())3309 return nullptr;3310 const APFloat &Op2V = Op2->getValueAPF();3311 3312 if (const auto *ConstrIntr =3313 dyn_cast_if_present<ConstrainedFPIntrinsic>(Call)) {3314 RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);3315 APFloat Res = Op1V;3316 APFloat::opStatus St;3317 switch (IntrinsicID) {3318 default:3319 return nullptr;3320 case Intrinsic::experimental_constrained_fadd:3321 St = Res.add(Op2V, RM);3322 break;3323 case Intrinsic::experimental_constrained_fsub:3324 St = Res.subtract(Op2V, RM);3325 break;3326 case Intrinsic::experimental_constrained_fmul:3327 St = Res.multiply(Op2V, RM);3328 break;3329 case Intrinsic::experimental_constrained_fdiv:3330 St = Res.divide(Op2V, RM);3331 break;3332 case Intrinsic::experimental_constrained_frem:3333 St = Res.mod(Op2V);3334 break;3335 case Intrinsic::experimental_constrained_fcmp:3336 case Intrinsic::experimental_constrained_fcmps:3337 return evaluateCompare(Op1V, Op2V, ConstrIntr);3338 }3339 if (mayFoldConstrained(const_cast<ConstrainedFPIntrinsic *>(ConstrIntr),3340 St))3341 return ConstantFP::get(Ty->getContext(), Res);3342 return nullptr;3343 }3344 3345 switch (IntrinsicID) {3346 default:3347 break;3348 case Intrinsic::copysign:3349 return ConstantFP::get(Ty->getContext(), APFloat::copySign(Op1V, Op2V));3350 case Intrinsic::minnum:3351 return ConstantFP::get(Ty->getContext(), minnum(Op1V, Op2V));3352 case Intrinsic::maxnum:3353 return ConstantFP::get(Ty->getContext(), maxnum(Op1V, Op2V));3354 case Intrinsic::minimum:3355 return ConstantFP::get(Ty->getContext(), minimum(Op1V, Op2V));3356 case Intrinsic::maximum:3357 return ConstantFP::get(Ty->getContext(), maximum(Op1V, Op2V));3358 case Intrinsic::minimumnum:3359 return ConstantFP::get(Ty->getContext(), minimumnum(Op1V, Op2V));3360 case Intrinsic::maximumnum:3361 return ConstantFP::get(Ty->getContext(), maximumnum(Op1V, Op2V));3362 3363 case Intrinsic::nvvm_fmax_d:3364 case Intrinsic::nvvm_fmax_f:3365 case Intrinsic::nvvm_fmax_ftz_f:3366 case Intrinsic::nvvm_fmax_ftz_nan_f:3367 case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:3368 case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:3369 case Intrinsic::nvvm_fmax_nan_f:3370 case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:3371 case Intrinsic::nvvm_fmax_xorsign_abs_f:3372 3373 case Intrinsic::nvvm_fmin_d:3374 case Intrinsic::nvvm_fmin_f:3375 case Intrinsic::nvvm_fmin_ftz_f:3376 case Intrinsic::nvvm_fmin_ftz_nan_f:3377 case Intrinsic::nvvm_fmin_ftz_nan_xorsign_abs_f:3378 case Intrinsic::nvvm_fmin_ftz_xorsign_abs_f:3379 case Intrinsic::nvvm_fmin_nan_f:3380 case Intrinsic::nvvm_fmin_nan_xorsign_abs_f:3381 case Intrinsic::nvvm_fmin_xorsign_abs_f: {3382 3383 bool ShouldCanonicalizeNaNs = !(IntrinsicID == Intrinsic::nvvm_fmax_d ||3384 IntrinsicID == Intrinsic::nvvm_fmin_d);3385 bool IsFTZ = nvvm::FMinFMaxShouldFTZ(IntrinsicID);3386 bool IsNaNPropagating = nvvm::FMinFMaxPropagatesNaNs(IntrinsicID);3387 bool IsXorSignAbs = nvvm::FMinFMaxIsXorSignAbs(IntrinsicID);3388 3389 APFloat A = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;3390 APFloat B = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;3391 3392 bool XorSign = false;3393 if (IsXorSignAbs) {3394 XorSign = A.isNegative() ^ B.isNegative();3395 A = abs(A);3396 B = abs(B);3397 }3398 3399 bool IsFMax = false;3400 switch (IntrinsicID) {3401 case Intrinsic::nvvm_fmax_d:3402 case Intrinsic::nvvm_fmax_f:3403 case Intrinsic::nvvm_fmax_ftz_f:3404 case Intrinsic::nvvm_fmax_ftz_nan_f:3405 case Intrinsic::nvvm_fmax_ftz_nan_xorsign_abs_f:3406 case Intrinsic::nvvm_fmax_ftz_xorsign_abs_f:3407 case Intrinsic::nvvm_fmax_nan_f:3408 case Intrinsic::nvvm_fmax_nan_xorsign_abs_f:3409 case Intrinsic::nvvm_fmax_xorsign_abs_f:3410 IsFMax = true;3411 break;3412 }3413 APFloat Res = IsFMax ? maximum(A, B) : minimum(A, B);3414 3415 if (ShouldCanonicalizeNaNs) {3416 APFloat NVCanonicalNaN(Res.getSemantics(), APInt(32, 0x7fffffff));3417 if (A.isNaN() && B.isNaN())3418 return ConstantFP::get(Ty, NVCanonicalNaN);3419 else if (IsNaNPropagating && (A.isNaN() || B.isNaN()))3420 return ConstantFP::get(Ty, NVCanonicalNaN);3421 }3422 3423 if (A.isNaN() && B.isNaN())3424 return Operands[1];3425 else if (A.isNaN())3426 Res = B;3427 else if (B.isNaN())3428 Res = A;3429 3430 if (IsXorSignAbs && XorSign != Res.isNegative())3431 Res.changeSign();3432 3433 return ConstantFP::get(Ty->getContext(), Res);3434 }3435 3436 case Intrinsic::nvvm_add_rm_f:3437 case Intrinsic::nvvm_add_rn_f:3438 case Intrinsic::nvvm_add_rp_f:3439 case Intrinsic::nvvm_add_rz_f:3440 case Intrinsic::nvvm_add_rm_d:3441 case Intrinsic::nvvm_add_rn_d:3442 case Intrinsic::nvvm_add_rp_d:3443 case Intrinsic::nvvm_add_rz_d:3444 case Intrinsic::nvvm_add_rm_ftz_f:3445 case Intrinsic::nvvm_add_rn_ftz_f:3446 case Intrinsic::nvvm_add_rp_ftz_f:3447 case Intrinsic::nvvm_add_rz_ftz_f: {3448 3449 bool IsFTZ = nvvm::FAddShouldFTZ(IntrinsicID);3450 APFloat A = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;3451 APFloat B = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;3452 3453 APFloat::roundingMode RoundMode =3454 nvvm::GetFAddRoundingMode(IntrinsicID);3455 3456 APFloat Res = A;3457 APFloat::opStatus Status = Res.add(B, RoundMode);3458 3459 if (!Res.isNaN() &&3460 (Status == APFloat::opOK || Status == APFloat::opInexact)) {3461 Res = IsFTZ ? FTZPreserveSign(Res) : Res;3462 return ConstantFP::get(Ty->getContext(), Res);3463 }3464 return nullptr;3465 }3466 3467 case Intrinsic::nvvm_mul_rm_f:3468 case Intrinsic::nvvm_mul_rn_f:3469 case Intrinsic::nvvm_mul_rp_f:3470 case Intrinsic::nvvm_mul_rz_f:3471 case Intrinsic::nvvm_mul_rm_d:3472 case Intrinsic::nvvm_mul_rn_d:3473 case Intrinsic::nvvm_mul_rp_d:3474 case Intrinsic::nvvm_mul_rz_d:3475 case Intrinsic::nvvm_mul_rm_ftz_f:3476 case Intrinsic::nvvm_mul_rn_ftz_f:3477 case Intrinsic::nvvm_mul_rp_ftz_f:3478 case Intrinsic::nvvm_mul_rz_ftz_f: {3479 3480 bool IsFTZ = nvvm::FMulShouldFTZ(IntrinsicID);3481 APFloat A = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;3482 APFloat B = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;3483 3484 APFloat::roundingMode RoundMode =3485 nvvm::GetFMulRoundingMode(IntrinsicID);3486 3487 APFloat Res = A;3488 APFloat::opStatus Status = Res.multiply(B, RoundMode);3489 3490 if (!Res.isNaN() &&3491 (Status == APFloat::opOK || Status == APFloat::opInexact)) {3492 Res = IsFTZ ? FTZPreserveSign(Res) : Res;3493 return ConstantFP::get(Ty->getContext(), Res);3494 }3495 return nullptr;3496 }3497 3498 case Intrinsic::nvvm_div_rm_f:3499 case Intrinsic::nvvm_div_rn_f:3500 case Intrinsic::nvvm_div_rp_f:3501 case Intrinsic::nvvm_div_rz_f:3502 case Intrinsic::nvvm_div_rm_d:3503 case Intrinsic::nvvm_div_rn_d:3504 case Intrinsic::nvvm_div_rp_d:3505 case Intrinsic::nvvm_div_rz_d:3506 case Intrinsic::nvvm_div_rm_ftz_f:3507 case Intrinsic::nvvm_div_rn_ftz_f:3508 case Intrinsic::nvvm_div_rp_ftz_f:3509 case Intrinsic::nvvm_div_rz_ftz_f: {3510 bool IsFTZ = nvvm::FDivShouldFTZ(IntrinsicID);3511 APFloat A = IsFTZ ? FTZPreserveSign(Op1V) : Op1V;3512 APFloat B = IsFTZ ? FTZPreserveSign(Op2V) : Op2V;3513 APFloat::roundingMode RoundMode =3514 nvvm::GetFDivRoundingMode(IntrinsicID);3515 3516 APFloat Res = A;3517 APFloat::opStatus Status = Res.divide(B, RoundMode);3518 if (!Res.isNaN() &&3519 (Status == APFloat::opOK || Status == APFloat::opInexact)) {3520 Res = IsFTZ ? FTZPreserveSign(Res) : Res;3521 return ConstantFP::get(Ty->getContext(), Res);3522 }3523 return nullptr;3524 }3525 }3526 3527 if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())3528 return nullptr;3529 3530 switch (IntrinsicID) {3531 default:3532 break;3533 case Intrinsic::pow:3534 return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);3535 case Intrinsic::amdgcn_fmul_legacy:3536 // The legacy behaviour is that multiplying +/- 0.0 by anything, even3537 // NaN or infinity, gives +0.0.3538 if (Op1V.isZero() || Op2V.isZero())3539 return ConstantFP::getZero(Ty);3540 return ConstantFP::get(Ty->getContext(), Op1V * Op2V);3541 }3542 3543 } else if (auto *Op2C = dyn_cast<ConstantInt>(Operands[1])) {3544 switch (IntrinsicID) {3545 case Intrinsic::ldexp: {3546 return ConstantFP::get(3547 Ty->getContext(),3548 scalbn(Op1V, Op2C->getSExtValue(), APFloat::rmNearestTiesToEven));3549 }3550 case Intrinsic::is_fpclass: {3551 FPClassTest Mask = static_cast<FPClassTest>(Op2C->getZExtValue());3552 bool Result =3553 ((Mask & fcSNan) && Op1V.isNaN() && Op1V.isSignaling()) ||3554 ((Mask & fcQNan) && Op1V.isNaN() && !Op1V.isSignaling()) ||3555 ((Mask & fcNegInf) && Op1V.isNegInfinity()) ||3556 ((Mask & fcNegNormal) && Op1V.isNormal() && Op1V.isNegative()) ||3557 ((Mask & fcNegSubnormal) && Op1V.isDenormal() && Op1V.isNegative()) ||3558 ((Mask & fcNegZero) && Op1V.isZero() && Op1V.isNegative()) ||3559 ((Mask & fcPosZero) && Op1V.isZero() && !Op1V.isNegative()) ||3560 ((Mask & fcPosSubnormal) && Op1V.isDenormal() && !Op1V.isNegative()) ||3561 ((Mask & fcPosNormal) && Op1V.isNormal() && !Op1V.isNegative()) ||3562 ((Mask & fcPosInf) && Op1V.isPosInfinity());3563 return ConstantInt::get(Ty, Result);3564 }3565 case Intrinsic::powi: {3566 int Exp = static_cast<int>(Op2C->getSExtValue());3567 switch (Ty->getTypeID()) {3568 case Type::HalfTyID:3569 case Type::FloatTyID: {3570 APFloat Res(static_cast<float>(std::pow(Op1V.convertToFloat(), Exp)));3571 if (Ty->isHalfTy()) {3572 bool Unused;3573 Res.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,3574 &Unused);3575 }3576 return ConstantFP::get(Ty->getContext(), Res);3577 }3578 case Type::DoubleTyID:3579 return ConstantFP::get(Ty, std::pow(Op1V.convertToDouble(), Exp));3580 default:3581 return nullptr;3582 }3583 }3584 default:3585 break;3586 }3587 }3588 return nullptr;3589 }3590 3591 if (Operands[0]->getType()->isIntegerTy() &&3592 Operands[1]->getType()->isIntegerTy()) {3593 const APInt *C0, *C1;3594 if (!getConstIntOrUndef(Operands[0], C0) ||3595 !getConstIntOrUndef(Operands[1], C1))3596 return nullptr;3597 3598 switch (IntrinsicID) {3599 default: break;3600 case Intrinsic::smax:3601 case Intrinsic::smin:3602 case Intrinsic::umax:3603 case Intrinsic::umin:3604 if (!C0 && !C1)3605 return UndefValue::get(Ty);3606 if (!C0 || !C1)3607 return MinMaxIntrinsic::getSaturationPoint(IntrinsicID, Ty);3608 return ConstantInt::get(3609 Ty, ICmpInst::compare(*C0, *C1,3610 MinMaxIntrinsic::getPredicate(IntrinsicID))3611 ? *C03612 : *C1);3613 3614 case Intrinsic::scmp:3615 case Intrinsic::ucmp:3616 if (!C0 || !C1)3617 return ConstantInt::get(Ty, 0);3618 3619 int Res;3620 if (IntrinsicID == Intrinsic::scmp)3621 Res = C0->sgt(*C1) ? 1 : C0->slt(*C1) ? -1 : 0;3622 else3623 Res = C0->ugt(*C1) ? 1 : C0->ult(*C1) ? -1 : 0;3624 return ConstantInt::get(Ty, Res, /*IsSigned=*/true);3625 3626 case Intrinsic::usub_with_overflow:3627 case Intrinsic::ssub_with_overflow:3628 // X - undef -> { 0, false }3629 // undef - X -> { 0, false }3630 if (!C0 || !C1)3631 return Constant::getNullValue(Ty);3632 [[fallthrough]];3633 case Intrinsic::uadd_with_overflow:3634 case Intrinsic::sadd_with_overflow:3635 // X + undef -> { -1, false }3636 // undef + x -> { -1, false }3637 if (!C0 || !C1) {3638 return ConstantStruct::get(3639 cast<StructType>(Ty),3640 {Constant::getAllOnesValue(Ty->getStructElementType(0)),3641 Constant::getNullValue(Ty->getStructElementType(1))});3642 }3643 [[fallthrough]];3644 case Intrinsic::smul_with_overflow:3645 case Intrinsic::umul_with_overflow: {3646 // undef * X -> { 0, false }3647 // X * undef -> { 0, false }3648 if (!C0 || !C1)3649 return Constant::getNullValue(Ty);3650 3651 APInt Res;3652 bool Overflow;3653 switch (IntrinsicID) {3654 default: llvm_unreachable("Invalid case");3655 case Intrinsic::sadd_with_overflow:3656 Res = C0->sadd_ov(*C1, Overflow);3657 break;3658 case Intrinsic::uadd_with_overflow:3659 Res = C0->uadd_ov(*C1, Overflow);3660 break;3661 case Intrinsic::ssub_with_overflow:3662 Res = C0->ssub_ov(*C1, Overflow);3663 break;3664 case Intrinsic::usub_with_overflow:3665 Res = C0->usub_ov(*C1, Overflow);3666 break;3667 case Intrinsic::smul_with_overflow:3668 Res = C0->smul_ov(*C1, Overflow);3669 break;3670 case Intrinsic::umul_with_overflow:3671 Res = C0->umul_ov(*C1, Overflow);3672 break;3673 }3674 Constant *Ops[] = {3675 ConstantInt::get(Ty->getContext(), Res),3676 ConstantInt::get(Type::getInt1Ty(Ty->getContext()), Overflow)3677 };3678 return ConstantStruct::get(cast<StructType>(Ty), Ops);3679 }3680 case Intrinsic::uadd_sat:3681 case Intrinsic::sadd_sat:3682 if (!C0 && !C1)3683 return UndefValue::get(Ty);3684 if (!C0 || !C1)3685 return Constant::getAllOnesValue(Ty);3686 if (IntrinsicID == Intrinsic::uadd_sat)3687 return ConstantInt::get(Ty, C0->uadd_sat(*C1));3688 else3689 return ConstantInt::get(Ty, C0->sadd_sat(*C1));3690 case Intrinsic::usub_sat:3691 case Intrinsic::ssub_sat:3692 if (!C0 && !C1)3693 return UndefValue::get(Ty);3694 if (!C0 || !C1)3695 return Constant::getNullValue(Ty);3696 if (IntrinsicID == Intrinsic::usub_sat)3697 return ConstantInt::get(Ty, C0->usub_sat(*C1));3698 else3699 return ConstantInt::get(Ty, C0->ssub_sat(*C1));3700 case Intrinsic::cttz:3701 case Intrinsic::ctlz:3702 assert(C1 && "Must be constant int");3703 3704 // cttz(0, 1) and ctlz(0, 1) are poison.3705 if (C1->isOne() && (!C0 || C0->isZero()))3706 return PoisonValue::get(Ty);3707 if (!C0)3708 return Constant::getNullValue(Ty);3709 if (IntrinsicID == Intrinsic::cttz)3710 return ConstantInt::get(Ty, C0->countr_zero());3711 else3712 return ConstantInt::get(Ty, C0->countl_zero());3713 3714 case Intrinsic::abs:3715 assert(C1 && "Must be constant int");3716 assert((C1->isOne() || C1->isZero()) && "Must be 0 or 1");3717 3718 // Undef or minimum val operand with poison min --> poison3719 if (C1->isOne() && (!C0 || C0->isMinSignedValue()))3720 return PoisonValue::get(Ty);3721 3722 // Undef operand with no poison min --> 0 (sign bit must be clear)3723 if (!C0)3724 return Constant::getNullValue(Ty);3725 3726 return ConstantInt::get(Ty, C0->abs());3727 case Intrinsic::amdgcn_wave_reduce_umin:3728 case Intrinsic::amdgcn_wave_reduce_umax:3729 case Intrinsic::amdgcn_wave_reduce_max:3730 case Intrinsic::amdgcn_wave_reduce_min:3731 case Intrinsic::amdgcn_wave_reduce_add:3732 case Intrinsic::amdgcn_wave_reduce_sub:3733 case Intrinsic::amdgcn_wave_reduce_and:3734 case Intrinsic::amdgcn_wave_reduce_or:3735 case Intrinsic::amdgcn_wave_reduce_xor:3736 return dyn_cast<Constant>(Operands[0]);3737 }3738 3739 return nullptr;3740 }3741 3742 // Support ConstantVector in case we have an Undef in the top.3743 if ((isa<ConstantVector>(Operands[0]) ||3744 isa<ConstantDataVector>(Operands[0])) &&3745 // Check for default rounding mode.3746 // FIXME: Support other rounding modes?3747 isa<ConstantInt>(Operands[1]) &&3748 cast<ConstantInt>(Operands[1])->getValue() == 4) {3749 auto *Op = cast<Constant>(Operands[0]);3750 switch (IntrinsicID) {3751 default: break;3752 case Intrinsic::x86_avx512_vcvtss2si32:3753 case Intrinsic::x86_avx512_vcvtss2si64:3754 case Intrinsic::x86_avx512_vcvtsd2si32:3755 case Intrinsic::x86_avx512_vcvtsd2si64:3756 if (ConstantFP *FPOp =3757 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3758 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3759 /*roundTowardZero=*/false, Ty,3760 /*IsSigned*/true);3761 break;3762 case Intrinsic::x86_avx512_vcvtss2usi32:3763 case Intrinsic::x86_avx512_vcvtss2usi64:3764 case Intrinsic::x86_avx512_vcvtsd2usi32:3765 case Intrinsic::x86_avx512_vcvtsd2usi64:3766 if (ConstantFP *FPOp =3767 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3768 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3769 /*roundTowardZero=*/false, Ty,3770 /*IsSigned*/false);3771 break;3772 case Intrinsic::x86_avx512_cvttss2si:3773 case Intrinsic::x86_avx512_cvttss2si64:3774 case Intrinsic::x86_avx512_cvttsd2si:3775 case Intrinsic::x86_avx512_cvttsd2si64:3776 if (ConstantFP *FPOp =3777 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3778 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3779 /*roundTowardZero=*/true, Ty,3780 /*IsSigned*/true);3781 break;3782 case Intrinsic::x86_avx512_cvttss2usi:3783 case Intrinsic::x86_avx512_cvttss2usi64:3784 case Intrinsic::x86_avx512_cvttsd2usi:3785 case Intrinsic::x86_avx512_cvttsd2usi64:3786 if (ConstantFP *FPOp =3787 dyn_cast_or_null<ConstantFP>(Op->getAggregateElement(0U)))3788 return ConstantFoldSSEConvertToInt(FPOp->getValueAPF(),3789 /*roundTowardZero=*/true, Ty,3790 /*IsSigned*/false);3791 break;3792 }3793 }3794 return nullptr;3795}3796 3797static APFloat ConstantFoldAMDGCNCubeIntrinsic(Intrinsic::ID IntrinsicID,3798 const APFloat &S0,3799 const APFloat &S1,3800 const APFloat &S2) {3801 unsigned ID;3802 const fltSemantics &Sem = S0.getSemantics();3803 APFloat MA(Sem), SC(Sem), TC(Sem);3804 if (abs(S2) >= abs(S0) && abs(S2) >= abs(S1)) {3805 if (S2.isNegative() && S2.isNonZero() && !S2.isNaN()) {3806 // S2 < 03807 ID = 5;3808 SC = -S0;3809 } else {3810 ID = 4;3811 SC = S0;3812 }3813 MA = S2;3814 TC = -S1;3815 } else if (abs(S1) >= abs(S0)) {3816 if (S1.isNegative() && S1.isNonZero() && !S1.isNaN()) {3817 // S1 < 03818 ID = 3;3819 TC = -S2;3820 } else {3821 ID = 2;3822 TC = S2;3823 }3824 MA = S1;3825 SC = S0;3826 } else {3827 if (S0.isNegative() && S0.isNonZero() && !S0.isNaN()) {3828 // S0 < 03829 ID = 1;3830 SC = S2;3831 } else {3832 ID = 0;3833 SC = -S2;3834 }3835 MA = S0;3836 TC = -S1;3837 }3838 switch (IntrinsicID) {3839 default:3840 llvm_unreachable("unhandled amdgcn cube intrinsic");3841 case Intrinsic::amdgcn_cubeid:3842 return APFloat(Sem, ID);3843 case Intrinsic::amdgcn_cubema:3844 return MA + MA;3845 case Intrinsic::amdgcn_cubesc:3846 return SC;3847 case Intrinsic::amdgcn_cubetc:3848 return TC;3849 }3850}3851 3852static Constant *ConstantFoldAMDGCNPermIntrinsic(ArrayRef<Constant *> Operands,3853 Type *Ty) {3854 const APInt *C0, *C1, *C2;3855 if (!getConstIntOrUndef(Operands[0], C0) ||3856 !getConstIntOrUndef(Operands[1], C1) ||3857 !getConstIntOrUndef(Operands[2], C2))3858 return nullptr;3859 3860 if (!C2)3861 return UndefValue::get(Ty);3862 3863 APInt Val(32, 0);3864 unsigned NumUndefBytes = 0;3865 for (unsigned I = 0; I < 32; I += 8) {3866 unsigned Sel = C2->extractBitsAsZExtValue(8, I);3867 unsigned B = 0;3868 3869 if (Sel >= 13)3870 B = 0xff;3871 else if (Sel == 12)3872 B = 0x00;3873 else {3874 const APInt *Src = ((Sel & 10) == 10 || (Sel & 12) == 4) ? C0 : C1;3875 if (!Src)3876 ++NumUndefBytes;3877 else if (Sel < 8)3878 B = Src->extractBitsAsZExtValue(8, (Sel & 3) * 8);3879 else3880 B = Src->extractBitsAsZExtValue(1, (Sel & 1) ? 31 : 15) * 0xff;3881 }3882 3883 Val.insertBits(B, I, 8);3884 }3885 3886 if (NumUndefBytes == 4)3887 return UndefValue::get(Ty);3888 3889 return ConstantInt::get(Ty, Val);3890}3891 3892static Constant *ConstantFoldScalarCall3(StringRef Name,3893 Intrinsic::ID IntrinsicID,3894 Type *Ty,3895 ArrayRef<Constant *> Operands,3896 const TargetLibraryInfo *TLI,3897 const CallBase *Call) {3898 assert(Operands.size() == 3 && "Wrong number of operands.");3899 3900 if (const auto *Op1 = dyn_cast<ConstantFP>(Operands[0])) {3901 if (const auto *Op2 = dyn_cast<ConstantFP>(Operands[1])) {3902 if (const auto *Op3 = dyn_cast<ConstantFP>(Operands[2])) {3903 const APFloat &C1 = Op1->getValueAPF();3904 const APFloat &C2 = Op2->getValueAPF();3905 const APFloat &C3 = Op3->getValueAPF();3906 3907 if (const auto *ConstrIntr = dyn_cast<ConstrainedFPIntrinsic>(Call)) {3908 RoundingMode RM = getEvaluationRoundingMode(ConstrIntr);3909 APFloat Res = C1;3910 APFloat::opStatus St;3911 switch (IntrinsicID) {3912 default:3913 return nullptr;3914 case Intrinsic::experimental_constrained_fma:3915 case Intrinsic::experimental_constrained_fmuladd:3916 St = Res.fusedMultiplyAdd(C2, C3, RM);3917 break;3918 }3919 if (mayFoldConstrained(3920 const_cast<ConstrainedFPIntrinsic *>(ConstrIntr), St))3921 return ConstantFP::get(Ty->getContext(), Res);3922 return nullptr;3923 }3924 3925 switch (IntrinsicID) {3926 default: break;3927 case Intrinsic::amdgcn_fma_legacy: {3928 // The legacy behaviour is that multiplying +/- 0.0 by anything, even3929 // NaN or infinity, gives +0.0.3930 if (C1.isZero() || C2.isZero()) {3931 // It's tempting to just return C3 here, but that would give the3932 // wrong result if C3 was -0.0.3933 return ConstantFP::get(Ty->getContext(), APFloat(0.0f) + C3);3934 }3935 [[fallthrough]];3936 }3937 case Intrinsic::fma:3938 case Intrinsic::fmuladd: {3939 APFloat V = C1;3940 V.fusedMultiplyAdd(C2, C3, APFloat::rmNearestTiesToEven);3941 return ConstantFP::get(Ty->getContext(), V);3942 }3943 3944 case Intrinsic::nvvm_fma_rm_f:3945 case Intrinsic::nvvm_fma_rn_f:3946 case Intrinsic::nvvm_fma_rp_f:3947 case Intrinsic::nvvm_fma_rz_f:3948 case Intrinsic::nvvm_fma_rm_d:3949 case Intrinsic::nvvm_fma_rn_d:3950 case Intrinsic::nvvm_fma_rp_d:3951 case Intrinsic::nvvm_fma_rz_d:3952 case Intrinsic::nvvm_fma_rm_ftz_f:3953 case Intrinsic::nvvm_fma_rn_ftz_f:3954 case Intrinsic::nvvm_fma_rp_ftz_f:3955 case Intrinsic::nvvm_fma_rz_ftz_f: {3956 bool IsFTZ = nvvm::FMAShouldFTZ(IntrinsicID);3957 APFloat A = IsFTZ ? FTZPreserveSign(C1) : C1;3958 APFloat B = IsFTZ ? FTZPreserveSign(C2) : C2;3959 APFloat C = IsFTZ ? FTZPreserveSign(C3) : C3;3960 3961 APFloat::roundingMode RoundMode =3962 nvvm::GetFMARoundingMode(IntrinsicID);3963 3964 APFloat Res = A;3965 APFloat::opStatus Status = Res.fusedMultiplyAdd(B, C, RoundMode);3966 3967 if (!Res.isNaN() &&3968 (Status == APFloat::opOK || Status == APFloat::opInexact)) {3969 Res = IsFTZ ? FTZPreserveSign(Res) : Res;3970 return ConstantFP::get(Ty->getContext(), Res);3971 }3972 return nullptr;3973 }3974 3975 case Intrinsic::amdgcn_cubeid:3976 case Intrinsic::amdgcn_cubema:3977 case Intrinsic::amdgcn_cubesc:3978 case Intrinsic::amdgcn_cubetc: {3979 APFloat V = ConstantFoldAMDGCNCubeIntrinsic(IntrinsicID, C1, C2, C3);3980 return ConstantFP::get(Ty->getContext(), V);3981 }3982 }3983 }3984 }3985 }3986 3987 if (IntrinsicID == Intrinsic::smul_fix ||3988 IntrinsicID == Intrinsic::smul_fix_sat) {3989 const APInt *C0, *C1;3990 if (!getConstIntOrUndef(Operands[0], C0) ||3991 !getConstIntOrUndef(Operands[1], C1))3992 return nullptr;3993 3994 // undef * C -> 03995 // C * undef -> 03996 if (!C0 || !C1)3997 return Constant::getNullValue(Ty);3998 3999 // This code performs rounding towards negative infinity in case the result4000 // cannot be represented exactly for the given scale. Targets that do care4001 // about rounding should use a target hook for specifying how rounding4002 // should be done, and provide their own folding to be consistent with4003 // rounding. This is the same approach as used by4004 // DAGTypeLegalizer::ExpandIntRes_MULFIX.4005 unsigned Scale = cast<ConstantInt>(Operands[2])->getZExtValue();4006 unsigned Width = C0->getBitWidth();4007 assert(Scale < Width && "Illegal scale.");4008 unsigned ExtendedWidth = Width * 2;4009 APInt Product =4010 (C0->sext(ExtendedWidth) * C1->sext(ExtendedWidth)).ashr(Scale);4011 if (IntrinsicID == Intrinsic::smul_fix_sat) {4012 APInt Max = APInt::getSignedMaxValue(Width).sext(ExtendedWidth);4013 APInt Min = APInt::getSignedMinValue(Width).sext(ExtendedWidth);4014 Product = APIntOps::smin(Product, Max);4015 Product = APIntOps::smax(Product, Min);4016 }4017 return ConstantInt::get(Ty->getContext(), Product.sextOrTrunc(Width));4018 }4019 4020 if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {4021 const APInt *C0, *C1, *C2;4022 if (!getConstIntOrUndef(Operands[0], C0) ||4023 !getConstIntOrUndef(Operands[1], C1) ||4024 !getConstIntOrUndef(Operands[2], C2))4025 return nullptr;4026 4027 bool IsRight = IntrinsicID == Intrinsic::fshr;4028 if (!C2)4029 return Operands[IsRight ? 1 : 0];4030 if (!C0 && !C1)4031 return UndefValue::get(Ty);4032 4033 // The shift amount is interpreted as modulo the bitwidth. If the shift4034 // amount is effectively 0, avoid UB due to oversized inverse shift below.4035 unsigned BitWidth = C2->getBitWidth();4036 unsigned ShAmt = C2->urem(BitWidth);4037 if (!ShAmt)4038 return Operands[IsRight ? 1 : 0];4039 4040 // (C0 << ShlAmt) | (C1 >> LshrAmt)4041 unsigned LshrAmt = IsRight ? ShAmt : BitWidth - ShAmt;4042 unsigned ShlAmt = !IsRight ? ShAmt : BitWidth - ShAmt;4043 if (!C0)4044 return ConstantInt::get(Ty, C1->lshr(LshrAmt));4045 if (!C1)4046 return ConstantInt::get(Ty, C0->shl(ShlAmt));4047 return ConstantInt::get(Ty, C0->shl(ShlAmt) | C1->lshr(LshrAmt));4048 }4049 4050 if (IntrinsicID == Intrinsic::amdgcn_perm)4051 return ConstantFoldAMDGCNPermIntrinsic(Operands, Ty);4052 4053 return nullptr;4054}4055 4056static Constant *ConstantFoldScalarCall(StringRef Name,4057 Intrinsic::ID IntrinsicID,4058 Type *Ty,4059 ArrayRef<Constant *> Operands,4060 const TargetLibraryInfo *TLI,4061 const CallBase *Call) {4062 if (IntrinsicID != Intrinsic::not_intrinsic &&4063 any_of(Operands, IsaPred<PoisonValue>) &&4064 intrinsicPropagatesPoison(IntrinsicID))4065 return PoisonValue::get(Ty);4066 4067 if (Operands.size() == 1)4068 return ConstantFoldScalarCall1(Name, IntrinsicID, Ty, Operands, TLI, Call);4069 4070 if (Operands.size() == 2) {4071 if (Constant *FoldedLibCall =4072 ConstantFoldLibCall2(Name, Ty, Operands, TLI)) {4073 return FoldedLibCall;4074 }4075 return ConstantFoldIntrinsicCall2(IntrinsicID, Ty, Operands, Call);4076 }4077 4078 if (Operands.size() == 3)4079 return ConstantFoldScalarCall3(Name, IntrinsicID, Ty, Operands, TLI, Call);4080 4081 return nullptr;4082}4083 4084static Constant *ConstantFoldFixedVectorCall(4085 StringRef Name, Intrinsic::ID IntrinsicID, FixedVectorType *FVTy,4086 ArrayRef<Constant *> Operands, const DataLayout &DL,4087 const TargetLibraryInfo *TLI, const CallBase *Call) {4088 SmallVector<Constant *, 4> Result(FVTy->getNumElements());4089 SmallVector<Constant *, 4> Lane(Operands.size());4090 Type *Ty = FVTy->getElementType();4091 4092 switch (IntrinsicID) {4093 case Intrinsic::masked_load: {4094 auto *SrcPtr = Operands[0];4095 auto *Mask = Operands[1];4096 auto *Passthru = Operands[2];4097 4098 Constant *VecData = ConstantFoldLoadFromConstPtr(SrcPtr, FVTy, DL);4099 4100 SmallVector<Constant *, 32> NewElements;4101 for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {4102 auto *MaskElt = Mask->getAggregateElement(I);4103 if (!MaskElt)4104 break;4105 auto *PassthruElt = Passthru->getAggregateElement(I);4106 auto *VecElt = VecData ? VecData->getAggregateElement(I) : nullptr;4107 if (isa<UndefValue>(MaskElt)) {4108 if (PassthruElt)4109 NewElements.push_back(PassthruElt);4110 else if (VecElt)4111 NewElements.push_back(VecElt);4112 else4113 return nullptr;4114 }4115 if (MaskElt->isNullValue()) {4116 if (!PassthruElt)4117 return nullptr;4118 NewElements.push_back(PassthruElt);4119 } else if (MaskElt->isOneValue()) {4120 if (!VecElt)4121 return nullptr;4122 NewElements.push_back(VecElt);4123 } else {4124 return nullptr;4125 }4126 }4127 if (NewElements.size() != FVTy->getNumElements())4128 return nullptr;4129 return ConstantVector::get(NewElements);4130 }4131 case Intrinsic::arm_mve_vctp8:4132 case Intrinsic::arm_mve_vctp16:4133 case Intrinsic::arm_mve_vctp32:4134 case Intrinsic::arm_mve_vctp64: {4135 if (auto *Op = dyn_cast<ConstantInt>(Operands[0])) {4136 unsigned Lanes = FVTy->getNumElements();4137 uint64_t Limit = Op->getZExtValue();4138 4139 SmallVector<Constant *, 16> NCs;4140 for (unsigned i = 0; i < Lanes; i++) {4141 if (i < Limit)4142 NCs.push_back(ConstantInt::getTrue(Ty));4143 else4144 NCs.push_back(ConstantInt::getFalse(Ty));4145 }4146 return ConstantVector::get(NCs);4147 }4148 return nullptr;4149 }4150 case Intrinsic::get_active_lane_mask: {4151 auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);4152 auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);4153 if (Op0 && Op1) {4154 unsigned Lanes = FVTy->getNumElements();4155 uint64_t Base = Op0->getZExtValue();4156 uint64_t Limit = Op1->getZExtValue();4157 4158 SmallVector<Constant *, 16> NCs;4159 for (unsigned i = 0; i < Lanes; i++) {4160 if (Base + i < Limit)4161 NCs.push_back(ConstantInt::getTrue(Ty));4162 else4163 NCs.push_back(ConstantInt::getFalse(Ty));4164 }4165 return ConstantVector::get(NCs);4166 }4167 return nullptr;4168 }4169 case Intrinsic::vector_extract: {4170 auto *Idx = dyn_cast<ConstantInt>(Operands[1]);4171 Constant *Vec = Operands[0];4172 if (!Idx || !isa<FixedVectorType>(Vec->getType()))4173 return nullptr;4174 4175 unsigned NumElements = FVTy->getNumElements();4176 unsigned VecNumElements =4177 cast<FixedVectorType>(Vec->getType())->getNumElements();4178 unsigned StartingIndex = Idx->getZExtValue();4179 4180 // Extracting entire vector is nop4181 if (NumElements == VecNumElements && StartingIndex == 0)4182 return Vec;4183 4184 for (unsigned I = StartingIndex, E = StartingIndex + NumElements; I < E;4185 ++I) {4186 Constant *Elt = Vec->getAggregateElement(I);4187 if (!Elt)4188 return nullptr;4189 Result[I - StartingIndex] = Elt;4190 }4191 4192 return ConstantVector::get(Result);4193 }4194 case Intrinsic::vector_insert: {4195 Constant *Vec = Operands[0];4196 Constant *SubVec = Operands[1];4197 auto *Idx = dyn_cast<ConstantInt>(Operands[2]);4198 if (!Idx || !isa<FixedVectorType>(Vec->getType()))4199 return nullptr;4200 4201 unsigned SubVecNumElements =4202 cast<FixedVectorType>(SubVec->getType())->getNumElements();4203 unsigned VecNumElements =4204 cast<FixedVectorType>(Vec->getType())->getNumElements();4205 unsigned IdxN = Idx->getZExtValue();4206 // Replacing entire vector with a subvec is nop4207 if (SubVecNumElements == VecNumElements && IdxN == 0)4208 return SubVec;4209 4210 for (unsigned I = 0; I < VecNumElements; ++I) {4211 Constant *Elt;4212 if (I < IdxN + SubVecNumElements)4213 Elt = SubVec->getAggregateElement(I - IdxN);4214 else4215 Elt = Vec->getAggregateElement(I);4216 if (!Elt)4217 return nullptr;4218 Result[I] = Elt;4219 }4220 return ConstantVector::get(Result);4221 }4222 case Intrinsic::vector_interleave2:4223 case Intrinsic::vector_interleave3:4224 case Intrinsic::vector_interleave4:4225 case Intrinsic::vector_interleave5:4226 case Intrinsic::vector_interleave6:4227 case Intrinsic::vector_interleave7:4228 case Intrinsic::vector_interleave8: {4229 unsigned NumElements =4230 cast<FixedVectorType>(Operands[0]->getType())->getNumElements();4231 unsigned NumOperands = Operands.size();4232 for (unsigned I = 0; I < NumElements; ++I) {4233 for (unsigned J = 0; J < NumOperands; ++J) {4234 Constant *Elt = Operands[J]->getAggregateElement(I);4235 if (!Elt)4236 return nullptr;4237 Result[NumOperands * I + J] = Elt;4238 }4239 }4240 return ConstantVector::get(Result);4241 }4242 case Intrinsic::wasm_dot: {4243 unsigned NumElements =4244 cast<FixedVectorType>(Operands[0]->getType())->getNumElements();4245 4246 assert(NumElements == 8 && Result.size() == 4 &&4247 "wasm dot takes i16x8 and produces i32x4");4248 assert(Ty->isIntegerTy());4249 int32_t MulVector[8];4250 4251 for (unsigned I = 0; I < NumElements; ++I) {4252 ConstantInt *Elt0 =4253 cast<ConstantInt>(Operands[0]->getAggregateElement(I));4254 ConstantInt *Elt1 =4255 cast<ConstantInt>(Operands[1]->getAggregateElement(I));4256 4257 MulVector[I] = Elt0->getSExtValue() * Elt1->getSExtValue();4258 }4259 for (unsigned I = 0; I < Result.size(); I++) {4260 int64_t IAdd = (int64_t)MulVector[I * 2] + (int64_t)MulVector[I * 2 + 1];4261 Result[I] = ConstantInt::get(Ty, IAdd);4262 }4263 4264 return ConstantVector::get(Result);4265 }4266 default:4267 break;4268 }4269 4270 for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {4271 // Gather a column of constants.4272 for (unsigned J = 0, JE = Operands.size(); J != JE; ++J) {4273 // Some intrinsics use a scalar type for certain arguments.4274 if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, J, /*TTI=*/nullptr)) {4275 Lane[J] = Operands[J];4276 continue;4277 }4278 4279 Constant *Agg = Operands[J]->getAggregateElement(I);4280 if (!Agg)4281 return nullptr;4282 4283 Lane[J] = Agg;4284 }4285 4286 // Use the regular scalar folding to simplify this column.4287 Constant *Folded =4288 ConstantFoldScalarCall(Name, IntrinsicID, Ty, Lane, TLI, Call);4289 if (!Folded)4290 return nullptr;4291 Result[I] = Folded;4292 }4293 4294 return ConstantVector::get(Result);4295}4296 4297static Constant *ConstantFoldScalableVectorCall(4298 StringRef Name, Intrinsic::ID IntrinsicID, ScalableVectorType *SVTy,4299 ArrayRef<Constant *> Operands, const DataLayout &DL,4300 const TargetLibraryInfo *TLI, const CallBase *Call) {4301 switch (IntrinsicID) {4302 case Intrinsic::aarch64_sve_convert_from_svbool: {4303 auto *Src = dyn_cast<Constant>(Operands[0]);4304 if (!Src || !Src->isNullValue())4305 break;4306 4307 return ConstantInt::getFalse(SVTy);4308 }4309 case Intrinsic::get_active_lane_mask: {4310 auto *Op0 = dyn_cast<ConstantInt>(Operands[0]);4311 auto *Op1 = dyn_cast<ConstantInt>(Operands[1]);4312 if (Op0 && Op1 && Op0->getValue().uge(Op1->getValue()))4313 return ConstantVector::getNullValue(SVTy);4314 break;4315 }4316 case Intrinsic::vector_interleave2:4317 case Intrinsic::vector_interleave3:4318 case Intrinsic::vector_interleave4:4319 case Intrinsic::vector_interleave5:4320 case Intrinsic::vector_interleave6:4321 case Intrinsic::vector_interleave7:4322 case Intrinsic::vector_interleave8: {4323 Constant *SplatVal = Operands[0]->getSplatValue();4324 if (!SplatVal)4325 return nullptr;4326 4327 if (!llvm::all_equal(Operands))4328 return nullptr;4329 4330 return ConstantVector::getSplat(SVTy->getElementCount(), SplatVal);4331 }4332 default:4333 break;4334 }4335 4336 // If trivially vectorizable, try folding it via the scalar call if all4337 // operands are splats.4338 4339 // TODO: ConstantFoldFixedVectorCall should probably check this too?4340 if (!isTriviallyVectorizable(IntrinsicID))4341 return nullptr;4342 4343 SmallVector<Constant *, 4> SplatOps;4344 for (auto [I, Op] : enumerate(Operands)) {4345 if (isVectorIntrinsicWithScalarOpAtArg(IntrinsicID, I, /*TTI=*/nullptr)) {4346 SplatOps.push_back(Op);4347 continue;4348 }4349 Constant *Splat = Op->getSplatValue();4350 if (!Splat)4351 return nullptr;4352 SplatOps.push_back(Splat);4353 }4354 Constant *Folded = ConstantFoldScalarCall(4355 Name, IntrinsicID, SVTy->getElementType(), SplatOps, TLI, Call);4356 if (!Folded)4357 return nullptr;4358 return ConstantVector::getSplat(SVTy->getElementCount(), Folded);4359}4360 4361static std::pair<Constant *, Constant *>4362ConstantFoldScalarFrexpCall(Constant *Op, Type *IntTy) {4363 if (isa<PoisonValue>(Op))4364 return {Op, PoisonValue::get(IntTy)};4365 4366 auto *ConstFP = dyn_cast<ConstantFP>(Op);4367 if (!ConstFP)4368 return {};4369 4370 const APFloat &U = ConstFP->getValueAPF();4371 int FrexpExp;4372 APFloat FrexpMant = frexp(U, FrexpExp, APFloat::rmNearestTiesToEven);4373 Constant *Result0 = ConstantFP::get(ConstFP->getType(), FrexpMant);4374 4375 // The exponent is an "unspecified value" for inf/nan. We use zero to avoid4376 // using undef.4377 Constant *Result1 = FrexpMant.isFinite()4378 ? ConstantInt::getSigned(IntTy, FrexpExp)4379 : ConstantInt::getNullValue(IntTy);4380 return {Result0, Result1};4381}4382 4383/// Handle intrinsics that return tuples, which may be tuples of vectors.4384static Constant *4385ConstantFoldStructCall(StringRef Name, Intrinsic::ID IntrinsicID,4386 StructType *StTy, ArrayRef<Constant *> Operands,4387 const DataLayout &DL, const TargetLibraryInfo *TLI,4388 const CallBase *Call) {4389 4390 switch (IntrinsicID) {4391 case Intrinsic::frexp: {4392 Type *Ty0 = StTy->getContainedType(0);4393 Type *Ty1 = StTy->getContainedType(1)->getScalarType();4394 4395 if (auto *FVTy0 = dyn_cast<FixedVectorType>(Ty0)) {4396 SmallVector<Constant *, 4> Results0(FVTy0->getNumElements());4397 SmallVector<Constant *, 4> Results1(FVTy0->getNumElements());4398 4399 for (unsigned I = 0, E = FVTy0->getNumElements(); I != E; ++I) {4400 Constant *Lane = Operands[0]->getAggregateElement(I);4401 std::tie(Results0[I], Results1[I]) =4402 ConstantFoldScalarFrexpCall(Lane, Ty1);4403 if (!Results0[I])4404 return nullptr;4405 }4406 4407 return ConstantStruct::get(StTy, ConstantVector::get(Results0),4408 ConstantVector::get(Results1));4409 }4410 4411 auto [Result0, Result1] = ConstantFoldScalarFrexpCall(Operands[0], Ty1);4412 if (!Result0)4413 return nullptr;4414 return ConstantStruct::get(StTy, Result0, Result1);4415 }4416 case Intrinsic::sincos: {4417 Type *Ty = StTy->getContainedType(0);4418 Type *TyScalar = Ty->getScalarType();4419 4420 auto ConstantFoldScalarSincosCall =4421 [&](Constant *Op) -> std::pair<Constant *, Constant *> {4422 Constant *SinResult =4423 ConstantFoldScalarCall(Name, Intrinsic::sin, TyScalar, Op, TLI, Call);4424 Constant *CosResult =4425 ConstantFoldScalarCall(Name, Intrinsic::cos, TyScalar, Op, TLI, Call);4426 return std::make_pair(SinResult, CosResult);4427 };4428 4429 if (auto *FVTy = dyn_cast<FixedVectorType>(Ty)) {4430 SmallVector<Constant *> SinResults(FVTy->getNumElements());4431 SmallVector<Constant *> CosResults(FVTy->getNumElements());4432 4433 for (unsigned I = 0, E = FVTy->getNumElements(); I != E; ++I) {4434 Constant *Lane = Operands[0]->getAggregateElement(I);4435 std::tie(SinResults[I], CosResults[I]) =4436 ConstantFoldScalarSincosCall(Lane);4437 if (!SinResults[I] || !CosResults[I])4438 return nullptr;4439 }4440 4441 return ConstantStruct::get(StTy, ConstantVector::get(SinResults),4442 ConstantVector::get(CosResults));4443 }4444 4445 auto [SinResult, CosResult] = ConstantFoldScalarSincosCall(Operands[0]);4446 if (!SinResult || !CosResult)4447 return nullptr;4448 return ConstantStruct::get(StTy, SinResult, CosResult);4449 }4450 case Intrinsic::vector_deinterleave2:4451 case Intrinsic::vector_deinterleave3:4452 case Intrinsic::vector_deinterleave4:4453 case Intrinsic::vector_deinterleave5:4454 case Intrinsic::vector_deinterleave6:4455 case Intrinsic::vector_deinterleave7:4456 case Intrinsic::vector_deinterleave8: {4457 unsigned NumResults = StTy->getNumElements();4458 auto *Vec = Operands[0];4459 auto *VecTy = cast<VectorType>(Vec->getType());4460 4461 ElementCount ResultEC =4462 VecTy->getElementCount().divideCoefficientBy(NumResults);4463 4464 if (auto *EltC = Vec->getSplatValue()) {4465 auto *ResultVec = ConstantVector::getSplat(ResultEC, EltC);4466 SmallVector<Constant *, 8> Results(NumResults, ResultVec);4467 return ConstantStruct::get(StTy, Results);4468 }4469 4470 if (!ResultEC.isFixed())4471 return nullptr;4472 4473 unsigned NumElements = ResultEC.getFixedValue();4474 SmallVector<Constant *, 8> Results(NumResults);4475 SmallVector<Constant *> Elements(NumElements);4476 for (unsigned I = 0; I != NumResults; ++I) {4477 for (unsigned J = 0; J != NumElements; ++J) {4478 Constant *Elt = Vec->getAggregateElement(J * NumResults + I);4479 if (!Elt)4480 return nullptr;4481 Elements[J] = Elt;4482 }4483 Results[I] = ConstantVector::get(Elements);4484 }4485 return ConstantStruct::get(StTy, Results);4486 }4487 default:4488 // TODO: Constant folding of vector intrinsics that fall through here does4489 // not work (e.g. overflow intrinsics)4490 return ConstantFoldScalarCall(Name, IntrinsicID, StTy, Operands, TLI, Call);4491 }4492 4493 return nullptr;4494}4495 4496} // end anonymous namespace4497 4498Constant *llvm::ConstantFoldBinaryIntrinsic(Intrinsic::ID ID, Constant *LHS,4499 Constant *RHS, Type *Ty,4500 Instruction *FMFSource) {4501 auto *Call = dyn_cast_if_present<CallBase>(FMFSource);4502 // Ensure we check flags like StrictFP that might prevent this from getting4503 // folded before generating a result.4504 if (Call && !canConstantFoldCallTo(Call, Call->getCalledFunction()))4505 return nullptr;4506 return ConstantFoldIntrinsicCall2(ID, Ty, {LHS, RHS}, Call);4507}4508 4509Constant *llvm::ConstantFoldCall(const CallBase *Call, Function *F,4510 ArrayRef<Constant *> Operands,4511 const TargetLibraryInfo *TLI,4512 bool AllowNonDeterministic) {4513 if (Call->isNoBuiltin())4514 return nullptr;4515 if (!F->hasName())4516 return nullptr;4517 4518 // If this is not an intrinsic and not recognized as a library call, bail out.4519 Intrinsic::ID IID = F->getIntrinsicID();4520 if (IID == Intrinsic::not_intrinsic) {4521 if (!TLI)4522 return nullptr;4523 LibFunc LibF;4524 if (!TLI->getLibFunc(*F, LibF))4525 return nullptr;4526 }4527 4528 // Conservatively assume that floating-point libcalls may be4529 // non-deterministic.4530 Type *Ty = F->getReturnType();4531 if (!AllowNonDeterministic && Ty->isFPOrFPVectorTy())4532 return nullptr;4533 4534 StringRef Name = F->getName();4535 if (auto *FVTy = dyn_cast<FixedVectorType>(Ty))4536 return ConstantFoldFixedVectorCall(4537 Name, IID, FVTy, Operands, F->getDataLayout(), TLI, Call);4538 4539 if (auto *SVTy = dyn_cast<ScalableVectorType>(Ty))4540 return ConstantFoldScalableVectorCall(4541 Name, IID, SVTy, Operands, F->getDataLayout(), TLI, Call);4542 4543 if (auto *StTy = dyn_cast<StructType>(Ty))4544 return ConstantFoldStructCall(Name, IID, StTy, Operands,4545 F->getDataLayout(), TLI, Call);4546 4547 // TODO: If this is a library function, we already discovered that above,4548 // so we should pass the LibFunc, not the name (and it might be better4549 // still to separate intrinsic handling from libcalls).4550 return ConstantFoldScalarCall(Name, IID, Ty, Operands, TLI, Call);4551}4552 4553bool llvm::isMathLibCallNoop(const CallBase *Call,4554 const TargetLibraryInfo *TLI) {4555 // FIXME: Refactor this code; this duplicates logic in LibCallsShrinkWrap4556 // (and to some extent ConstantFoldScalarCall).4557 if (Call->isNoBuiltin() || Call->isStrictFP())4558 return false;4559 Function *F = Call->getCalledFunction();4560 if (!F)4561 return false;4562 4563 LibFunc Func;4564 if (!TLI || !TLI->getLibFunc(*F, Func))4565 return false;4566 4567 if (Call->arg_size() == 1) {4568 if (ConstantFP *OpC = dyn_cast<ConstantFP>(Call->getArgOperand(0))) {4569 const APFloat &Op = OpC->getValueAPF();4570 switch (Func) {4571 case LibFunc_logl:4572 case LibFunc_log:4573 case LibFunc_logf:4574 case LibFunc_log2l:4575 case LibFunc_log2:4576 case LibFunc_log2f:4577 case LibFunc_log10l:4578 case LibFunc_log10:4579 case LibFunc_log10f:4580 return Op.isNaN() || (!Op.isZero() && !Op.isNegative());4581 4582 case LibFunc_ilogb:4583 return !Op.isNaN() && !Op.isZero() && !Op.isInfinity();4584 4585 case LibFunc_expl:4586 case LibFunc_exp:4587 case LibFunc_expf:4588 // FIXME: These boundaries are slightly conservative.4589 if (OpC->getType()->isDoubleTy())4590 return !(Op < APFloat(-745.0) || Op > APFloat(709.0));4591 if (OpC->getType()->isFloatTy())4592 return !(Op < APFloat(-103.0f) || Op > APFloat(88.0f));4593 break;4594 4595 case LibFunc_exp2l:4596 case LibFunc_exp2:4597 case LibFunc_exp2f:4598 // FIXME: These boundaries are slightly conservative.4599 if (OpC->getType()->isDoubleTy())4600 return !(Op < APFloat(-1074.0) || Op > APFloat(1023.0));4601 if (OpC->getType()->isFloatTy())4602 return !(Op < APFloat(-149.0f) || Op > APFloat(127.0f));4603 break;4604 4605 case LibFunc_sinl:4606 case LibFunc_sin:4607 case LibFunc_sinf:4608 case LibFunc_cosl:4609 case LibFunc_cos:4610 case LibFunc_cosf:4611 return !Op.isInfinity();4612 4613 case LibFunc_tanl:4614 case LibFunc_tan:4615 case LibFunc_tanf: {4616 // FIXME: Stop using the host math library.4617 // FIXME: The computation isn't done in the right precision.4618 Type *Ty = OpC->getType();4619 if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy())4620 return ConstantFoldFP(tan, OpC->getValueAPF(), Ty) != nullptr;4621 break;4622 }4623 4624 case LibFunc_atan:4625 case LibFunc_atanf:4626 case LibFunc_atanl:4627 // Per POSIX, this MAY fail if Op is denormal. We choose not failing.4628 return true;4629 4630 case LibFunc_asinl:4631 case LibFunc_asin:4632 case LibFunc_asinf:4633 case LibFunc_acosl:4634 case LibFunc_acos:4635 case LibFunc_acosf:4636 return !(Op < APFloat::getOne(Op.getSemantics(), true) ||4637 Op > APFloat::getOne(Op.getSemantics()));4638 4639 case LibFunc_sinh:4640 case LibFunc_cosh:4641 case LibFunc_sinhf:4642 case LibFunc_coshf:4643 case LibFunc_sinhl:4644 case LibFunc_coshl:4645 // FIXME: These boundaries are slightly conservative.4646 if (OpC->getType()->isDoubleTy())4647 return !(Op < APFloat(-710.0) || Op > APFloat(710.0));4648 if (OpC->getType()->isFloatTy())4649 return !(Op < APFloat(-89.0f) || Op > APFloat(89.0f));4650 break;4651 4652 case LibFunc_sqrtl:4653 case LibFunc_sqrt:4654 case LibFunc_sqrtf:4655 return Op.isNaN() || Op.isZero() || !Op.isNegative();4656 4657 // FIXME: Add more functions: sqrt_finite, atanh, expm1, log1p,4658 // maybe others?4659 default:4660 break;4661 }4662 }4663 }4664 4665 if (Call->arg_size() == 2) {4666 ConstantFP *Op0C = dyn_cast<ConstantFP>(Call->getArgOperand(0));4667 ConstantFP *Op1C = dyn_cast<ConstantFP>(Call->getArgOperand(1));4668 if (Op0C && Op1C) {4669 const APFloat &Op0 = Op0C->getValueAPF();4670 const APFloat &Op1 = Op1C->getValueAPF();4671 4672 switch (Func) {4673 case LibFunc_powl:4674 case LibFunc_pow:4675 case LibFunc_powf: {4676 // FIXME: Stop using the host math library.4677 // FIXME: The computation isn't done in the right precision.4678 Type *Ty = Op0C->getType();4679 if (Ty->isDoubleTy() || Ty->isFloatTy() || Ty->isHalfTy()) {4680 if (Ty == Op1C->getType())4681 return ConstantFoldBinaryFP(pow, Op0, Op1, Ty) != nullptr;4682 }4683 break;4684 }4685 4686 case LibFunc_fmodl:4687 case LibFunc_fmod:4688 case LibFunc_fmodf:4689 case LibFunc_remainderl:4690 case LibFunc_remainder:4691 case LibFunc_remainderf:4692 return Op0.isNaN() || Op1.isNaN() ||4693 (!Op0.isInfinity() && !Op1.isZero());4694 4695 case LibFunc_atan2:4696 case LibFunc_atan2f:4697 case LibFunc_atan2l:4698 // Although IEEE-754 says atan2(+/-0.0, +/-0.0) are well-defined, and4699 // GLIBC and MSVC do not appear to raise an error on those, we4700 // cannot rely on that behavior. POSIX and C11 say that a domain error4701 // may occur, so allow for that possibility.4702 return !Op0.isZero() || !Op1.isZero();4703 4704 default:4705 break;4706 }4707 }4708 }4709 4710 return false;4711}4712 4713Constant *llvm::getLosslessInvCast(Constant *C, Type *InvCastTo,4714 unsigned CastOp, const DataLayout &DL,4715 PreservedCastFlags *Flags) {4716 switch (CastOp) {4717 case Instruction::BitCast:4718 // Bitcast is always lossless.4719 return ConstantFoldCastOperand(Instruction::BitCast, C, InvCastTo, DL);4720 case Instruction::Trunc: {4721 auto *ZExtC = ConstantFoldCastOperand(Instruction::ZExt, C, InvCastTo, DL);4722 if (Flags) {4723 // Truncation back on ZExt value is always NUW.4724 Flags->NUW = true;4725 // Test positivity of C.4726 auto *SExtC =4727 ConstantFoldCastOperand(Instruction::SExt, C, InvCastTo, DL);4728 Flags->NSW = ZExtC == SExtC;4729 }4730 return ZExtC;4731 }4732 case Instruction::SExt:4733 case Instruction::ZExt: {4734 auto *InvC = ConstantExpr::getTrunc(C, InvCastTo);4735 auto *CastInvC = ConstantFoldCastOperand(CastOp, InvC, C->getType(), DL);4736 // Must satisfy CastOp(InvC) == C.4737 if (!CastInvC || CastInvC != C)4738 return nullptr;4739 if (Flags && CastOp == Instruction::ZExt) {4740 auto *SExtInvC =4741 ConstantFoldCastOperand(Instruction::SExt, InvC, C->getType(), DL);4742 // Test positivity of InvC.4743 Flags->NNeg = CastInvC == SExtInvC;4744 }4745 return InvC;4746 }4747 default:4748 return nullptr;4749 }4750}4751 4752Constant *llvm::getLosslessUnsignedTrunc(Constant *C, Type *DestTy,4753 const DataLayout &DL,4754 PreservedCastFlags *Flags) {4755 return getLosslessInvCast(C, DestTy, Instruction::ZExt, DL, Flags);4756}4757 4758Constant *llvm::getLosslessSignedTrunc(Constant *C, Type *DestTy,4759 const DataLayout &DL,4760 PreservedCastFlags *Flags) {4761 return getLosslessInvCast(C, DestTy, Instruction::SExt, DL, Flags);4762}4763 4764void TargetFolder::anchor() {}4765