aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Constants.cpp
AgeCommit message (Collapse)AuthorFilesLines
27 hours[Constants] Handle ptrtoaddr in getRelocationInfo()Nikita Popov1-2/+5
Treat it the same way as ptrtoint.
2025-09-20[IR] Fix a few implicit conversions from TypeSize to uint64_t. NFC (#159894)Craig Topper1-1/+1
2025-08-08[IR] Introduce the `ptrtoaddr` instructionAlexander Richardson1-0/+20
This introduces a new `ptrtoaddr` instruction which is similar to `ptrtoint` but has two differences: 1) Unlike `ptrtoint`, `ptrtoaddr` does not capture provenance 2) `ptrtoaddr` only extracts (and then extends/truncates) the low index-width bits of the pointer For most architectures, difference 2) does not matter since index (address) width and pointer representation width are the same, but this does make a difference for architectures that have pointers that aren't just plain integer addresses such as AMDGPU fat pointers or CHERI capabilities. This commit introduces textual and bitcode IR support as well as basic code generation, but optimization passes do not handle the new instruction yet so it may result in worse code than using ptrtoint. Follow-up changes will update capture tracking, etc. for the new instruction. RFC: https://discourse.llvm.org/t/clarifiying-the-semantics-of-ptrtoint/83987/54 Reviewed By: nikic Pull Request: https://github.com/llvm/llvm-project/pull/139357
2025-05-29[Constant] Make Constant::getSplatValue return poison on poison (#141870)Luke Lau1-0/+2
This is a follow up from #141845. TargetTransformInfo::getOperandInfo needs to be updated to check for undef values as otherwise a splat is considered a constant, and some RISC-V cost model tests will start adding a cost to materialize the constant.
2025-05-28[ConstantFolding] Fold intrinsics of scalable vectors with splatted operands ↵Luke Lau1-1/+3
(#141845) As noted in https://github.com/llvm/llvm-project/pull/141821#issuecomment-2917328924, whilst we currently constant fold intrinsics of fixed-length vectors via their scalar counterpart, we don't do the same for scalable vectors. This handles the scalable vector case when the operands are splats. One weird snag in ConstantVector::getSplat was that it produced a undef if passed in poison, so this also contains a fix by checking for PoisonValue before UndefValue.
2025-05-26[llvm] Value-initialize values with *Map::try_emplace (NFC) (#141522)Kazu Hirata1-3/+1
try_emplace value-initializes values, so we do not need to pass nullptr to try_emplace when the value types are raw pointers or std::unique_ptr<T>.
2025-05-02[IR] Replace blockaddress refcount with single flag (#138239)Nikita Popov1-4/+4
BasicBlock currently has a blockaddress refcount. However, blockaddresses are uniqued, which means that there can only be a single blockaddress for a given BasicBlock. Prior to #137958 there were some edge case exceptions to this, but now it always holds. As such, replace the refcount with a single flag. As we're now just tracking two bits, I've dropped the BasicBlockBits structure, as I found it more annoying than useful (esp with the weird AIX workarounds). Instead handle the subclass data the same way we do in Operators.
2025-05-02[IR] Do not store Function inside BlockAddress (#137958)Nikita Popov1-36/+20
Currently BlockAddresses store both the Function and the BasicBlock they reference, and the BlockAddress is part of the use list of both the Function and BasicBlock. This is quite awkward, because this is not really a use of the function itself (and walks of function uses generally skip block addresses for that reason). This also has weird implications on function RAUW (as that will replace the function in block addresses in a way that generally doesn't make sense), and causes other peculiar issues, like the ability to have multiple block addresses for one block (with different functions). Instead, I believe it makes more sense to specify only the basic block and let the function be implied by the BB parent. This does mean that we may have block addresses without a function (if the BB is not inserted), but this should only happen during IR construction.
2025-03-21[llvm:ir] Add support for constant data exceeding 4GiB (#126481)pzzp1-13/+10
The test file is over 4GiB, which is too big, so I didn’t submit it.
2025-03-12[LLVM][ConstantFold] Undefined values are not constant (#130713)Kees Cook1-0/+2
llvm.is.constant (and therefore Clang's __builtin_constant_p()) need to report undefined values as non-constant or future DCE choices end up making no sense. This was encountered while building the Linux kernel which uses __builtin_constant_p() while trying to evaluate if it is safe to use a compile-time constant resolution for string lengths or if it must kick over to a full runtime call to strlen(). Obviously an undefined variable cannot be known at compile-time, so __builtin_constant_p() needs to return false. This change will also mean that Clang will match GCC's behavior under the same conditions. Fixes #130649
2025-02-14[IR] Remove mul constant expression (#127046)Nikita Popov1-8/+1
Remove support for the mul constant expression, which has previously already been marked as undesirable. This removes the APIs to create mul expressions and updates tests to stop using mul expressions. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2025-02-13[IR] Mark mul constant expression as undesirableNikita Popov1-1/+1
This is a (very belated) reland of 0a362f12ec60a49a054befec8620a8e69523af54, which I originally reverted due to flang test failures. This marks mul constant expressions as undesirable, which means that we will no longer create them by default, but they can still be created explicitly. Part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2025-01-23[IR] Replace of PointerType::getUnqual(Type) with opaque version (NFC) (#123909)Mats Jun Larsen1-1/+2
Follow up to https://github.com/llvm/llvm-project/issues/123569
2024-12-18[LLVM][AsmPrinter] Add vector ConstantInt/FP support to ↵Paul Walker1-0/+7
emitGlobalConstantImpl. (#120077) The fixes a failure path for fixed length vector globals when ConstantInt/FP is used to represent splats instead of ConstantDataVector.
2024-12-16[LLVM][ConstantFold] Remove remaining uses of ↵Paul Walker1-0/+3
ConstantInt/FP::get(LLVMContext... (#119912) This extends the constant folds to support vector ConstantInt/FP.
2024-11-21[LLVM][IR] Teach extractelement folds about constant ConstantInt/FP. (#116793)Paul Walker1-0/+4
2024-11-13[LLVM][IR] Teach constant integer binop folds about vector ConstantInts. ↵Paul Walker1-0/+7
(#115739) The existing logic mostly works with the main changes being: * Use getScalarSizeInBits instead of IntegerType::getBitWidth * Use ConstantInt::get(Type* instead of ConstantInt::get(LLVMContext
2024-10-17[APInt] Fix APInt constructions where value does not fit bitwidth (NFCI) ↵Nikita Popov1-1/+4
(#80309) This fixes all the places that hit the new assertion added in https://github.com/llvm/llvm-project/pull/106524 in tests. That is, cases where the value passed to the APInt constructor is not an N-bit signed/unsigned integer, where N is the bit width and signedness is determined by the isSigned flag. The fixes either set the correct value for isSigned, set the implicitTrunc flag, or perform more calculations inside APInt. Note that the assertion is currently still disabled by default, so this patch is mostly NFC.
2024-10-01[ConstantFold][RFC] Add AllowLHSConstant parameter in getBinOpAbsorber (#109736)eric-xtang10081-6/+23
Add a AllowLHSConstant parameter in getBinOpAbsorber function for supporting more binary operators.
2024-09-19[LLVM] Use {} instead of std::nullopt to initialize empty ArrayRef (#109133)Jay Foad1-1/+1
It is almost always simpler to use {} instead of std::nullopt to initialize an empty ArrayRef. This patch changes all occurrences I could find in LLVM itself. In future the ArrayRef(std::nullopt_t) constructor could be deprecated or removed.
2024-09-11Don't rely on undefined behavior to store how a `User` object's allocation ↵Daniel Paoliello1-18/+18
is laid out (#105714) In `User::operator new` a single allocation is created to store the `User` object itself, "intrusive" operands or a pointer for "hung off" operands, and the descriptor. After allocation, details about the layout (number of operands, how the operands are stored, if there is a descriptor) are stored in the `User` object by settings its fields. The `Value` and `User` constructors are then very careful not to initialize these fields so that the values set during allocation can be subsequently read. However, when the `User` object is returned from `operator new` [its value is technically "indeterminate" and so reading a field without first initializing it is undefined behavior (and will be erroneous in C++26)](https://en.cppreference.com/w/cpp/language/default_initialization#Indeterminate_and_erroneous_values). We discovered this issue when trying to build LLVM using MSVC's [`/sdl` flag](https://learn.microsoft.com/en-us/cpp/build/reference/sdl-enable-additional-security-checks?view=msvc-170) which clears class fields after allocation (the docs say that this feature shouldn't be turned on for custom allocators and should only clear pointers, but that doesn't seem to match the implementation). MSVC's behavior both with and without the `/sdl` flag is standards conforming since a program is supposed to initialize storage before reading from it, thus the compiler implementation changing any values will never be observed in a well-formed program. The standard also provides no provisions for making storage bytes not indeterminate by setting them during allocation or `operator new`. The fix for this is to create a set of types that encode the layout and provide these to both `operator new` and the constructor: * The `AllocMarker` types are used to select which `operator new` to use. * `AllocMarker` can then be implicitly converted to a `AllocInfo` which tells the constructor how the type was laid out.
2024-08-23[IR] Use a range-based for loop (NFC) (#105826)Kazu Hirata1-3/+2
2024-08-06[PAC][AArch64] Support init/fini array signing (#96478)Daniil Kovalev1-0/+12
If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`). Additionally, if `-fptrauth-init-fini-address-discrimination` is passed, address discrimination is used for signing (otherwise, just constant discriminator is used). For address discrimination, we use it's special form since uses of `llvm.global_{c|d}tors` are disallowed (see `Verifier::visitGlobalVariable`) and we can't emit `getelementptr` expressions referencing these special arrays. A signed ctor/dtor pointer with special address discrimination applied looks like the following: ``` ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr)) ```
2024-07-05[IR] Add Constant::toConstantRange() (NFC)Nikita Popov1-0/+38
The logic in llvm::getVectorConstantRange() can be a bit inconvenient to use in some cases because of the need to handle the scalar case separately. Generalize it to handle all constants, and move it to live directly on Constant.
2024-06-20[IR] Remove support for shl constant expressions (#96037)Nikita Popov1-14/+1
Remove support for shl constant expressions, as part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
2024-06-19[IR] Mark shl constant expression as undesirable (#95940)Nikita Popov1-1/+1
Mark shl constant expressions undesirable, so that they are no longer automatically created by IRBuilder, constant folding, etc. This is in preparation for removing them entirely.
2024-06-13Reapply [ConstantFold] Drop gep of gep fold entirely (#95126)Nikita Popov1-2/+1
Reapplying without changes. The flang+openmp buildbot failure should be addressed by https://github.com/llvm/llvm-project/pull/94541. ----- This is a followup to https://github.com/llvm/llvm-project/pull/93823 and drops the DataLayout-unaware GEP of GEP fold entirely. All cases are now left to the DataLayout-aware constant folder, which will fold everything to a single i8 GEP. We didn't have any test coverage for this fold in LLVM, but some Clang tests change.
2024-06-12Revert "[ConstantFold] Drop gep of gep fold entirely (#95126)"Nikita Popov1-1/+2
This reverts commit 3b3b839c66dc49674fd6646650525a2173030690. This broke the flang+openmp+offload buildbot, as reported in https://github.com/llvm/llvm-project/pull/95126#issuecomment-2162424019.
2024-06-12[ConstantFold] Drop gep of gep fold entirely (#95126)Nikita Popov1-2/+1
This is a followup to https://github.com/llvm/llvm-project/pull/93823 and drops the DataLayout-unaware GEP of GEP fold entirely. All cases are now left to the DataLayout-aware constant folder, which will fold everything to a single i8 GEP. We didn't have any test coverage for this fold in LLVM, but some Clang tests change.
2024-06-04[IR] Accept GEPNoWrapFlags in creation APIsNikita Popov1-4/+1
Add overloads of GetElementPtrInst::Create() that accept GEPNoWrapFlags, and switch the bool parameters in IRBuilder to accept it instead as well. As a sample use, switch GEP i8 canonicalization in InstCombine to preserve the original flags.
2024-06-04[IR] Remove support for icmp and fcmp constant expressions (#93038)Nikita Popov1-103/+10
Remove support for the icmp and fcmp constant expressions. This is part of: https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179 As usual, many of the updated tests will no longer test what they were originally intended to -- this is hard to preserve when constant expressions get removed, and in many cases just impossible as the existence of a specific kind of constant expression was the cause of the issue in the first place.
2024-05-31[IR] Remove handling for removed ConstantExprs (NFC)Nikita Popov1-8/+0
2024-05-28[IR][AArch64][PAC] Add "ptrauth(...)" Constant to represent signed pointers. ↵Ahmed Bougacha1-0/+121
(#85738) This defines a new kind of IR Constant that represents a ptrauth signed pointer, as used in AArch64 PAuth. It allows representing most kinds of signed pointer constants used thus far in the llvm ptrauth implementations, notably those used in the Darwin and ELF ABIs being implemented for c/c++. These signed pointer constants are then lowered to ELF/MachO relocations. These can be simply thought of as a constant `llvm.ptrauth.sign`, with the interesting addition of discriminator computation: the `ptrauth` constant can also represent a combined blend, when both address and integer discriminator operands are used. Both operands are otherwise optional, with default values 0/null.
2024-05-27[IR] Add getelementptr nusw and nuw flags (#90824)Nikita Popov1-6/+6
This implements the `nusw` and `nuw` flags for `getelementptr` as proposed at https://discourse.llvm.org/t/rfc-add-nusw-and-nuw-flags-for-getelementptr/78672. The three possible flags are encapsulated in the new `GEPNoWrapFlags` class. Currently this class has a ctor from bool, interpreted as the InBounds flag. This ctor should be removed in the future, as code gets migrated to handle all flags. There are a few places annotated with `TODO(gep_nowrap)`, where I've had to touch code but opted to not infer or precisely preserve the new flags, so as to keep this as NFC as possible and make sure any changes of that kind get test coverage when they are made.
2024-05-09Replace uses of ConstantExpr::getCompare. (#91558)Eli Friedman1-2/+2
Use ICmpInst::compare() where possible, ConstantFoldCompareInstOperands in other places. This only changes places where the either the fold is guaranteed to succeed, or the code doesn't use the resulting compare if we fail to fold.
2024-04-18[IR][PatternMatch] Only accept poison in getSplatValue() (#89159)Nikita Popov1-7/+7
In #88217 a large set of matchers was changed to only accept poison values in splats, but not undef values. This is because we now use poison for non-demanded vector elements, and allowing undef can cause correctness issues. This patch covers the remaining matchers by changing the AllowUndef parameter of getSplatValue() to AllowPoison instead. We also carry out corresponding renames in matchers. As a followup, we may want to change the default for things like m_APInt to m_APIntAllowPoison (as this is much less risky when only allowing poison), but this change doesn't do that. There is one caveat here: We have a single place (X86FixupVectorConstants) which does require handling of vector splats with undefs. This is because this works on backend constant pool entries, which currently still use undef instead of poison for non-demanded elements (because SDAG as a whole does not have an explicit poison representation). As it's just the single use, I've open-coded a getSplatValueAllowUndef() helper there, to discourage use in any other places.
2024-04-17[PatternMatch] Do not accept undef elements in m_AllOnes() and friends (#88217)Nikita Popov1-1/+1
Change all the cstval_pred_ty based PatternMatch helpers (things like m_AllOnes and m_Zero) to only allow poison elements inside vector splats, not undef elements. Historically, we used to represent non-demanded elements in vectors using undef. Nowadays, we use poison instead. As such, I believe that support for undef in vector splats is no longer useful. At the same time, while poison splat elements are pretty much always safe to ignore, this is not generally the case for undef elements. We have existing miscompiles in our tests due to this (see the masked-merge-*.ll tests changed here) and it's easy to miss such cases in the future, now that we write tests using poison instead of undef elements. I think overall, keeping support for undef elements no longer makes sense, and we should drop it. Once this is done consistently, I think we may also consider allowing poison in m_APInt by default, as doing that change is much less risky than doing the same with undef. This change involves a substantial amount of test changes. For most tests, I've just replaced undef with poison, as I don't think there is value in retaining both. For some tests (where the distinction between undef and poison is important), I've duplicated tests.
2024-03-26[LLVM] Remove nuw neg (#86295)Yingwei Zheng1-2/+2
This patch removes APIs that creating NUW neg. It is a trivial case because `sub nuw 0, X` always gets simplified into zero. I believe there is no optimization opportunities in the real-world applications that we can take advantage of the nuw flag. Motivated by https://github.com/llvm/llvm-project/pull/84792#discussion_r1524891134. Compile-time improvement: https://llvm-compile-time-tracker.com/compare.php?from=d1f182c895728d89c5c3d198b133e212a5d9d4a3&to=da7b7478b7cbb32c09d760f6b8d0e67901e0d533&stat=instructions:u
2024-03-20[IR] Change representation of getelementptr inrange (#84341)Nikita Popov1-12/+16
As part of the migration to ptradd (https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699), we need to change the representation of the `inrange` attribute, which is used for vtable splitting. Currently, inrange is specified as follows: ``` getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, inrange i32 1, i64 2) ``` The `inrange` is placed on a GEP index, and all accesses must be "in range" of that index. The new representation is as follows: ``` getelementptr inbounds inrange(-16, 16) ({ [4 x ptr], [4 x ptr] }, ptr @vt, i64 0, i32 1, i64 2) ``` This specifies which offsets are "in range" of the GEP result. The new representation will continue working when canonicalizing to ptradd representation: ``` getelementptr inbounds inrange(-16, 16) (i8, ptr @vt, i64 48) ``` The inrange offsets are relative to the return value of the GEP. An alternative design could make them relative to the source pointer instead. The result-relative format was chosen on the off-chance that we want to extend support to non-constant GEPs in the future, in which case this variant is more expressive. This implementation "upgrades" the old inrange representation in bitcode by simply dropping it. This is a very niche feature, and I don't think trying to upgrade it is worthwhile. Let me know if you disagree.
2024-03-19Reapply "[NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not ↵Stephen Tozer1-11/+10
insert (#84737)" Fixes a build error caused by an unupdated getAsInstruction callsite in clang. This reverts commit ab851f7fe946e7eed700ef9d82082eb721860189.
2024-03-19Revert "[NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not insert ↵Stephen Tozer1-10/+11
(#84737)" Reverted due to buildbot failures: https://lab.llvm.org/buildbot/#/builders/139/builds/61717/ This reverts commit 7ef433f62c199c414bffdcac1c8ee3159b29c5f5.
2024-03-19[NFC][RemoveDIs] Switch ConstantExpr::getAsInstruction to not insert (#84737)Jeremy Morse1-11/+10
Because the RemoveDIs work is putting a debug-info bit into BasicBlock::iterator and iterators are needed for insertion, the getAsInstruction method declaration would need to use a fully defined instruction-iterator, which leads to a complicated header-inclusion-order problem. Much simpler to instead just not insert, and make it the callers problem to insert. This is proportionate because there are only four call-sites to getAsInstruction -- it would suck if we did this everywhere. --------- Merged by: Stephen Tozer <stephen.tozer@sony.com>
2024-02-22[LLVM][IR] Add native vector support to ConstantInt & ConstantFP. (#74502)Paul Walker1-5/+89
NOTE: For brevity the following talks about ConstantInt but everything extends to cover ConstantFP as well. Whilst ConstantInt::get() supports the creation of vectors whereby each lane has the same value, it achieves this via other constants: * ConstantVector for fixed-length vectors * ConstantExprs for scalable vectors However, ConstantExprs are being deprecated and ConstantVector is not space efficient for larger vector types. By extending ConstantInt we can represent vector splats by only storing the underlying scalar value. More specifically: * ConstantInt gains an ElementCount variant of get(). * LLVMContext is extended to map <EC,APInt>->ConstantInt. * BitcodeReader/Writer support is extended to allow vector types. Whilst this patch adds the base support, more work is required before it's production ready. For example, there's likely to be many places where isa<ConstantInt> assumes a scalar type. Accordingly the default behaviour of ConstantInt::get() remains unchanged but a set of flags are added to allow wider testing and thus help with the migration: --use-constant-int-for-fixed-length-splat --use-constant-fp-for-fixed-length-splat --use-constant-int-for-scalable-splat --use-constant-fp-for-scalable-splat NOTE: No change is required to the bitcode format because types and values are handled separately. NOTE: For similar reasons as above, code generation doesn't work out-the-box.
2023-12-04[IR][TRE] Support associative intrinsics (#74226)Joshua Cao1-0/+26
There is support for intrinsics in Instruction::isCommunative, but there is no equivalent implementation for isAssociative. This patch builds support for associative intrinsics with TRE as an application. TRE can now have associative intrinsics as an accumulator. For example: ``` struct Node { Node *next; unsigned val; } unsigned maxval(struct Node *n) { if (!n) return 0; return std::max(n->val, maxval(n->next)); } ``` Can be transformed into: ``` unsigned maxval(struct Node *n) { struct Node *head = n; unsigned max = 0; // Identity of unsigned std::max while (true) { if (!head) return max; max = std::max(max, head->val); head = head->next; } return max; } ``` This example results in about 5x speedup in local runs. We conservatively only consider min/max and as associative for this patch to limit testing scope. There are probably other intrinsics that could be considered associative. There are a few consumers of isAssociative() that could be impacted. Testing has only required to Reassociate pass be updated.
2023-11-14[IR] Remove support for lshr/ashr constant expressions (#71955)Nikita Popov1-12/+2
Remove support for the lshr and ashr constant expressions. All places creating them have been removed beforehand, so this just removes the APIs and uses of these constant expressions in tests. This is part of https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
2023-11-10Revert "Revert "[IR] Mark lshr and ashr constant expressions as undesirable""Shoaib Meenai1-2/+2
This reverts commit 8ee07a4be7f7d8654ecf25e7ce0a680975649544. The revert is breaking AMDGPU backend tests (which I didn't have enabled), and I don't want to risk breakages over the weekend, so just revert for now.
2023-11-10Revert "[IR] Mark lshr and ashr constant expressions as undesirable"Shoaib Meenai1-2/+2
This reverts commit 82f68a992b9f89036042d57a5f6345cb2925b2c1. cd7ba9f3d090afb5d3b15b0dcf379d15d1e11e33 needs to be reverted to fix test failures on builds without assertions, and this one needs to be reverted first for that.
2023-11-10[IR] Mark lshr and ashr constant expressions as undesirableNikita Popov1-2/+2
These will no longer be created by default during constant folding.
2023-11-07Revert "[IR] Mark mul and ashr const exprs as undesirable"Nikita Popov1-2/+2
This reverts commit 0a362f12ec60a49a054befec8620a8e69523af54. This causes test failures in flang.
2023-11-07[IR] Mark mul and ashr const exprs as undesirableNikita Popov1-2/+2
These will no longer be created by default, but can still be created explicitly.