Age | Commit message (Collapse) | Author | Files | Lines |
|
isEliminableCastPair() currently tries to support elimination of
ptrtoint/inttoptr cast pairs by assuming that the maximum possible
pointer size is 64 bits. Of course, this is no longer the case nowadays.
This PR changes isEliminableCastPair() to accept an optional DataLayout
argument, which is required to eliminate pointer casts.
This means that we no longer eliminate these cast pairs during ConstExpr
construction, and instead only do it during DL-aware constant folding.
This had a lot of annoying fallout on tests, most of which I've
addressed in advance of this change.
|
|
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
|
|
|
|
Closes https://github.com/llvm/llvm-project/issues/142447.
|
|
ConstantFoldCastInstruction (#133207)
Previously only fixed vector splats were handled. This adds supports for
scalable vectors too by allowing ConstantExpr splats.
We need to add the extra V->getType()->isVectorTy() check because a
ConstantExpr might be a scalar to vector bitcast.
By allowing ConstantExprs this also allow fixed vector ConstantExprs to
be folded, which causes the diffs in
llvm/test/Analysis/ValueTracking/known-bits-from-operator-constexpr.ll
and llvm/test/Transforms/InstSimplify/ConstProp/cast-vector.ll. I can
remove them from this PR if reviewers would prefer.
Fixes #132922
|
|
ConstantInt/FP::get(LLVMContext... (#119912)
This extends the constant folds to support vector ConstantInt/FP.
|
|
ConstantInt/FP. (#116787)
This fixes the code quality issue reported in
https://github.com/llvm/llvm-project/pull/111149.
|
|
(#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
|
|
Identified with misc-include-cleaner.
|
|
to InstCombine (#114280)
Previously we fold `div/rem X, C` into `poison` if any element of the
constant divisor `C` is zero or undef. However, it is incorrect when
threading udiv over an vector select:
https://alive2.llvm.org/ce/z/3Ninx5
```
define <2 x i32> @vec_select_udiv_poison(<2 x i1> %x) {
%sel = select <2 x i1> %x, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 0, i32 1>
%div = udiv <2 x i32> <i32 42, i32 -7>, %sel
ret <2 x i32> %div
}
```
In this case, `threadBinOpOverSelect` folds `udiv <i32 42, i32 -7>, <i32
-1, i32 -1>` and `udiv <i32 42, i32 -7>, <i32 0, i32 1>` into
`zeroinitializer` and `poison`, respectively. One solution is to
introduce a new flag indicating that we are threading over a vector
select. But it requires to modify both `InstSimplify` and
`ConstantFold`.
However, this optimization doesn't provide benefits to real-world
programs:
https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/IR/ConstantFold.cpp.html#L908
https://dtcxzyw.github.io/llvm-opt-benchmark/coverage/data/zyw/opt-ci/actions-runner/_work/llvm-opt-benchmark/llvm-opt-benchmark/llvm/llvm-project/llvm/lib/Analysis/InstructionSimplify.cpp.html#L1107
This patch moves the fold into InstCombine to avoid breaking numerous
existing tests.
Fixes #114191 and #113866 (only poison-safety issue).
|
|
types (#112465)
The two folding operations are causing a cycle for the following case
with
scalable vector types:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%1 = select <vscale x 2 x i1> %cond, <vscale x 2 x double>
zeroinitializer, <vscale x 2 x double> %b
%2 = fneg fast <vscale x 2 x double> %1
ret <vscale x 2 x double> %2
}
1) fold fneg: -(Cond ? C : Y) -> Cond ? -C : -Y
2) fold select: (Cond ? -X : -Y) -> -(Cond ? X : Y)
1) results in the following since '<vscale x 2 x double>
zeroinitializer' passes
the check for the immediate constant:
%.neg = fneg fast <vscale x 2 x double> zeroinitializer
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double> %.neg,
<vscale x 2 x double> %b.neg
and so we end up going back and forth between 1) and 2).
Attempt to fold scalable vector constants, so that we end up with a
splat instead:
define <vscale x 2 x double> @test_fneg_select_abs(<vscale x 2 x i1>
%cond, <vscale x 2 x double> %b) {
%b.neg = fneg fast <vscale x 2 x double> %b
%1 = select fast <vscale x 2 x i1> %cond, <vscale x 2 x double>
shufflevector (<vscale x 2 x double> insertelement (<vscale x 2 x
double> poison, double -0.000000e+00, i64 0), <vscale x 2 x double>
poison, <vscale x 2 x i32> zeroinitializer), <vscale x 2 x double>
%b.neg
ret <vscale x 2 x double> %1
}
|
|
bitcast transformation. (#111149)
It was previously safe to assume isa<Constant{Int,FP}> meant a scalar
value. This is not true when use-constant-##-for-###-splat are enabled.
|
|
Add a AllowLHSConstant parameter in getBinOpAbsorber function for
supporting more binary operators.
|
|
It is now translated to `<1 x i64>`, which allows the removal of a bunch
of special casing.
This _incompatibly_ changes the ABI of any LLVM IR function with
`x86_mmx` arguments or returns: instead of passing in mmx registers,
they will now be passed via integer registers. However, the real-world
incompatibility caused by this is expected to be minimal, because Clang
never uses the x86_mmx type -- it lowers `__m64` to either `<1 x i64>`
or `double`, depending on ABI.
This change does _not_ eliminate the SelectionDAG `MVT::x86mmx` type.
That type simply no longer corresponds to an IR type, and is used only
by MMX intrinsics and inline-asm operands.
Because SelectionDAGBuilder only knows how to generate the
operands/results of intrinsics based on the IR type, it thus now
generates the intrinsics with the type MVT::v1i64, instead of
MVT::x86mmx. We need to fix this before the DAG LegalizeTypes, and thus
have the X86 backend fix them up in DAGCombine. (This may be a
short-lived hack, if all the MMX intrinsics can be removed in upcoming
changes.)
Works towards issue #98272.
|
|
Remove support for shl constant expressions, as part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
|
|
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.
|
|
This reverts commit 3b3b839c66dc49674fd6646650525a2173030690.
This broke the flang+openmp+offload buildbot, as reported in
https://github.com/llvm/llvm-project/pull/95126#issuecomment-2162424019.
|
|
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.
|
|
Reapply after https://github.com/llvm/llvm-project/pull/93956, which
changed clang array initialization codegen to avoid size regressions
for unoptimized builds.
-----
This fold is subtly incorrect, because DL-unaware constant folding does
not know the correct index type to use, and just performs the addition
in the type that happens to already be there. This is incorrect, since
sext(X)+sext(Y) is generally not the same as sext(X+Y). See the
`@constexpr_gep_of_gep_with_narrow_type()` for a miscompile with the
current implementation.
One could try to restrict the fold to cases where no overflow occurs,
but I'm not bothering with that here, because the DL-aware constant
folding will take care of this anyway. I've only kept the
straightforward zero-index case, where we just concatenate two GEPs.
|
|
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.
|
|
This reverts commit e1cc9e4eaddcc295b4e775512e33b947b1514c17.
This causes some non-trivial text size increases in unoptimized
builds for Bullet. Revert while I investigate.
|
|
This fold is subtly incorrect, because DL-unaware constant folding does
not know the correct index type to use, and just performs the addition
in the type that happens to already be there. This is incorrect, since
sext(X)+sext(Y) is generally not the same as sext(X+Y). See the
`@constexpr_gep_of_gep_with_narrow_type()` for a miscompile with the
current implementation.
One could try to restrict the fold to cases where no overflow occurs,
but I'm not bothering with that here, because the DL-aware constant
folding will take care of this anyway. I've only kept the
straightforward zero-index case, where we just concatenate two GEPs.
|
|
Reapply after https://github.com/llvm/llvm-project/pull/93548,
which should address the lldb failure on macos.
-----
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.
Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
|
|
The data-layout independent constant folding currently has some rather
gnarly code for canonicalizing GEP indices to reduce "notional
overindexing", and then infers inbounds based on that canonicalization.
Now that we canonicalize to i8 GEPs, this canonicalization is
essentially useless, as we'll discard it as soon as the GEP hits the
data-layout aware constant folder anyway. As such, I'd like to remove
this code entirely.
This shouldn't have any impact on optimization capabilities.
|
|
gep inbounds of undef can only be folded to poison if we know
that the offset is non-zero. I don't think precise handling here
is important, so just drop the inbounds special case. This matches
what InstSimplify does.
|
|
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.
|
|
Reverts llvm/llvm-project#92885 due to LLDB CI breakages.
|
|
Do not create icmp/fcmp constant expressions in IRBuilder etc anymore,
i.e. treat them as "undesirable". This is in preparation for removing
them entirely.
Part of:
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179
|
|
Also marks AliasSetTracker::size() as const.
|
|
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.
|
|
This code was assuming that the LHS would always be one of
GlobalVariable, BlockAddress or ConstantExpr. However, it can
also be a special constant like dso_local_equivalent or no_cfi.
Make sure this is handled gracefully.
|
|
Resolve the two FIXMEs: Perform the binop identitiy fold with
AllowRHSConstant, and remove redundant folds later in the code.
|
|
getIntegerType(). (#75217)
The specialisation will not be valid when ConstantInt gains native
support for vector types.
This is largely a mechanical change but with extra attention paid to constant
folding, InstCombineVectorOps.cpp, LoopFlatten.cpp and Verifier.cpp to
remove the need to call `getIntegerType()`.
Co-authored-by: Nikita Popov <github@npopov.com>
|
|
/llvm-project/llvm/lib/IR/ConstantFold.cpp:137:12: error: unused variable 'CSize' [-Werror,-Wunused-variable]
unsigned CSize = cast<IntegerType>(C->getType())->getBitWidth()/8;
^
1 error generated.
|
|
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.
|
|
We already handle the more general case of zero index GEPs above,
so we don't need to also handle GEPs with null based and zero
indices. (Strictly speaking, this code could handle the special
case of an inrange gep with null base and zero indices, but that
has no practical relevance.)
|
|
This code excludes vector/scalar and FP bitcasts. All other
integer/pointer bitcasts are no-op bitcasts and will be removed
entirely.
|
|
This is already handled in evaluateICmpRelation().
|
|
If a pointer isn't a constant expression, global or block address,
it's not guaranteed to be a null pointer. It can also be a no_cfi
or dso_local_equivalent constant.
|
|
Clarify that most of this only works on pointer icmps, and remove
the unnecessary isSigned parameter, as well as the ConstantInt
fallback.
Also perform complexity sorting upfront, so we don't need to deal
with swapped cases in the individual branches.
|
|
This only handles the case where the bitcast result is an integer
or pointer, and the input is not FP. This means that the input
can only be a vector. However, converting a comparison of the
whole vector into an element-wise comparison is generally not
correct.
I assume that this code was originally intended to handle the case
where a pointer bitcast is compared to a null pointer, which is
no longer relevant with opaque pointers.
Given the complete lack of test coverage, and the risk of
miscompiles if this code actually did something, I'm opting to
remove it entirely.
|
|
The bitcast will be folded away in this case, no need to handle it
explicitly.
|
|
This is folding an icmp, so fptrunc, fpext, uitofp, sitofp cannot
appear here at all. Also drop the explicit checks for trunc, fptoui,
fptosi, which can appear, but are just some random subset of opcodes
that are not handled by this code.
|
|
The only thing this actually handles is if the operands are the
same, in which case ueq is returned.
Given that nearly all FP constant expressions have already been
removed, I think it's safe to say that we aren't going to extend
this code in a way that makes use of the more general structure.
|
|
ConstantFoldCastInstruction() has generic handling for null values
at the top. No need to repeat it for inttoptr and ptrtoint.
|
|
ConstantFoldCastInstruction() already has generic code to perform
lane-wise casts for vectors. There is no need to repeate it
specifically for bitcasts.
However, we do need to keep the special case for vectors of -1,
which is not handled elsewhere.
|
|
This reverts commit 2182561b7ba675ca87356c02474eecb6ecfaa23f.
The all-ones special case in this case isn't redundant. Will redo
the change while preserving it.
|
|
Zero GEPs will be optimized away entirely, except in the cases
which this transform also excludes (splat, inrange).
|
|
These are no-op casts, which are already handled earlier.
|
|
ConstantFoldCastInstruction() already has generic code to perform
lane-wise casts for vectors. There is no need to repeate it
specifically for bitcasts.
|