This was supposed to be an NFC refactoring that will eventually allow
eliminating the isFast() predicate, but there's a rare possibility
that we would pessimize the code as shown in the test case because
we failed to check 'hasOneUse()' properly. This version also removes
an inefficiency of the old code; we would look for:
(X * C) * C1 --> X * (C * C1)
...but that pattern is always handled by
SimplifyAssociativeOrCommutative().
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327404 91177308-0d34-0410-b5e6-96231b3b80d8
Put the simplest non-FMF folds first, so it's easier to
see what's left to fix/group/add with the FMF folds.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326632 91177308-0d34-0410-b5e6-96231b3b80d8
The code was checking that all of the instructions in the
sequence are 'fast', but that's not necessary. The final
multiply is all that we need to check (tests adjusted).
The fmul doesn't need to be fully 'fast' either, but that
can be another patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326608 91177308-0d34-0410-b5e6-96231b3b80d8
This is a retry of r326502 with updates to the reassociate
test file that I missed the first time.
@test15_reassoc in the supposed -reassociate test file
(except that it tests 2 other passes too...) shows that
there's no clear responsiblity for reassociation transforms.
Instcombine now gets that case, but only because the
constant values are identical. Otherwise, it would still
miss that pattern.
Reassociate doesn't get that case because it hasn't been
updated to use less than 'fast' FMF.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326513 91177308-0d34-0410-b5e6-96231b3b80d8
I forgot that I added tests for 'reassoc' to -reassociate, but
suprisingly that file calls -instcombine too, so it is affected.
I'll update that file and try again.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326510 91177308-0d34-0410-b5e6-96231b3b80d8
Also, rename 'foldOpWithConstantIntoOperand' because that's annoyingly
vague. The constant check is redundant in some cases, but it allows
removing duplication for most of the calls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326329 91177308-0d34-0410-b5e6-96231b3b80d8
Note: gcc appears to allow this fold with -freciprocal-math alone,
but clang/llvm require more than that with this patch. The wording
in the definitions seems fuzzy enough that it could go either way,
but we'll err on the conservative side of FMF interpretation.
This patch also changes the newly created fmul to have FMF propagated
by the last fdiv rather than intersecting the FMF of the fdivs. This
matches the behavior of other folds near here. The new fmul is only
used to produce an intermediate op for the final fdiv result, so it
shouldn't be any stricter than that result. The previous behavior
could result in dropping FMF via other folds in instcombine or CSE.
Differential Revision: https://reviews.llvm.org/D43398
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326098 91177308-0d34-0410-b5e6-96231b3b80d8
The existing code was inefficiently looking for 'nsz' variants.
That's unnecessary because we canonicalize those to the expected
form with -0.0.
We may also want to adjust or remove the fold that sinks negation.
We don't do that for fdiv (or integer ops?). That should be uniform?
It may also lead to missed optimization as in PR21914:
https://bugs.llvm.org/show_bug.cgi?id=21914
...or we just have to fix other passes to avoid that problem.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325924 91177308-0d34-0410-b5e6-96231b3b80d8
We already do this in DAGCombiner, but it should
also be good to eliminate the fsub use in IR.
This is similar to rL325648.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325649 91177308-0d34-0410-b5e6-96231b3b80d8
FMul is commutative, so complexity-based canonicalization should always
take care of the swap via SimplifyAssociativeOrCommutative().
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325628 91177308-0d34-0410-b5e6-96231b3b80d8
These are fdiv-with-constant-divisor, so they already become
reciprocal multiplies. The last gap for vector ops should be
closed with rL325590.
It's possible that we're missing folds for some edge cases
with denormal intermediate constants after deleting these,
but there are no tests for those patterns, and it would be
better to handle denormals more consistently (and less
conservatively) as noted in TODO comments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325595 91177308-0d34-0410-b5e6-96231b3b80d8
It's possible that we could allow this either 'arcp' or 'reassoc' alone, but this
should be conservatively better than what we have right now. GCC allows this with
only -freciprocal-math.
The last test is changed to show a case that is expected to fold, but we need D43398.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325533 91177308-0d34-0410-b5e6-96231b3b80d8
The last fold that used to be here was not necessary. That's a
combination of 2 folds (and there's a regression test to show that).
The transforms are guarded by isFast(), but that should be loosened.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325531 91177308-0d34-0410-b5e6-96231b3b80d8
...and delete the equivalent local functiona from InstCombine.
These might be useful to other InstCombine files or other passes
and makes FP queries more similar to integer constant queries.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325398 91177308-0d34-0410-b5e6-96231b3b80d8
The variable name 'AllowReassociate' is a lie at this point because
it's set to 'isFast()' which is more than the 'reassoc' FMF after
rL317488.
In D41286, we showed that this transform may be valid even with strict
math by brute force checking every 32-bit float result.
There's a potential problem here because we're replacing with a tan()
libcall rather than a hypothetical LLVM tan intrinsic. So we might
set errno when we should be guaranteed not to do that. But that's
independent of this change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325247 91177308-0d34-0410-b5e6-96231b3b80d8
This keeps with our current usage of 'match' and is easier to see that
the optional NSW only applies in the non-constant operand case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325140 91177308-0d34-0410-b5e6-96231b3b80d8
This replaces the bit-tracking based fold that did the same thing,
but it only worked for scalars and not directly.
There is no evidence in existing regression tests that the greater
power of bit-tracking was needed here, but we should be aware of
this potential loss of optimization.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325062 91177308-0d34-0410-b5e6-96231b3b80d8
This is both a functional improvement for vectors and an
efficiency improvement for scalars. The existing code below
the new folds does the same thing for scalars, but in an
indirect and expensive way.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325048 91177308-0d34-0410-b5e6-96231b3b80d8
This is similar to the instsimplify fold added with D42385
( rL323716 )
...but this can't be in instsimplify because we're creating/morphing
a different instruction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324927 91177308-0d34-0410-b5e6-96231b3b80d8
Allows us to add non-uniform constant vector support for "X urem C -> X < C ? X : X - C, where C >= signbit."
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324631 91177308-0d34-0410-b5e6-96231b3b80d8