Per LangRef:
> The offsets are then added to the low bits of the base address up to
the index type width, with silently-wrapping two’s complement
arithmetic. If the pointer size is larger than the index size, this
means that the bits outside the index type width will not be affected.
The transform as implemented was doubly wrong, because it just truncated
the original base pointer to the index width, losing the top bits
entirely. Make sure we preserve the bits and use wrapping arithmetic
within the low bits.
In https://github.com/llvm/llvm-project/pull/97762, we assume the
minimum possible value of X is NaN implies X is NaN. But it doesn't hold
for x86_fp80 format. If the knownbits of X are
`?'011111111111110'????????????????????????????????????????????????????????????????`,
the minimum possible value of X is NaN/unnormal. However, it can be a
normal value.
Closes https://github.com/llvm/llvm-project/issues/130408.
Add constant-folding support for the NVVM intrinsics for converting
float/double to signed/unsigned int32/int64 types, including all
rounding-modes and ftz modifiers.
If x is NaN, then fmul (x, 1) may produce a different NaN value.
Our float semantics explicitly permit folding fmul (x, 1) to x, but we
can't do this when we're replacing a select input, as selects are
supposed to preserve the exact bitwise value.
Fixes
https://github.com/llvm/llvm-project/pull/115152#issuecomment-2545773114.
This calls into the existing constant folding for `llvm.sin` and
`llvm.cos`, which currently does not fold for any non-finite values, so
most tests are negative tests at the moment.
Note: The constant folding does not consider the `afn` fast-math flag
and will produce the same result regardless of if the flag is set.
This is a reland of #114527 that updates the syntax of one of the tests
from: `<float 1.000000e+00, float 1.000000e+00>` to `splat (float
1.000000e+00)`.
This calls into the existing constant folding for `llvm.sin` and
`llvm.cos`, which currently does not fold for any non-finite values, so
most tests are negative tests at the moment.
Note: The constant folding does not consider the `afn` fast-math flag
and will produce the same result regardless of if the flag is set.
Calls to `@llvm.abs(undef, i1 true)` and `@llvm.abs(INT_MIN, i1 true)`
can be optimized to `poison` instead of `undef`.
[Alive2](https://alive2.llvm.org/ce/z/Hg-2ug)
InstSimplify currently folds patterns like `(x | y) uge x` and `(x & y)
ule x` to true. However, it cannot handle combinations of such
situations, such as `(x | y) uge (x & z)` etc.
To support this, recursively collect operands of monotonic instructions
(that preserve either a greater-or-equal or less-or-equal relationship)
and then check whether any of them match.
Fixes https://github.com/llvm/llvm-project/issues/69333.
Since cd16b07 (IR: introduce CmpInst::isEquivalence), there is now an
isEquivalence routine in CmpInst that we can use to determine
equivalence in simplifySelectWithICmpEq. Implement this, extending the
code from integer-equalities to integer and floating-point equivalences.
InstSimplify currently folds alloc1 == alloc2 to false, even if one of
them is a zero-size allocation. A zero-size allocation may have the same
address as another allocation.
This also disables the fold for the case where we're comparing a
zero-size alloc with the middle of another allocation. It's possible
that this case is legal to fold depending on our precise zero-size
allocation semantics, but LangRef currently doesn't specify this either
way, so we shouldn't make assumptions here.
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
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
}
Reuse llvm::isTriviallyVectorizable in llvm::isNotCrossLaneOperation, in
order to get it to handle more intrinsics.
Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/XSV_GT
Factor out and unify common code from InstSimplify and InstCombine that
partially guard against cross-lane vector operations into
llvm::isNotCrossLaneOperation in ValueTracking.
Alive2 proofs for changed tests: https://alive2.llvm.org/ce/z/68H4ka
We were missing the signed flag on the negative value, so the
range was incorrectly interpreted for integers larger than 64-bit.
Split out from https://github.com/llvm/llvm-project/pull/80309.