Commit Graph

867 Commits

Author SHA1 Message Date
Kazu Hirata 3b7c3a654c Revert "Don't use Optional::hasValue (NFC)"
This reverts commit aa8feeefd3.
2022-06-25 11:56:50 -07:00
Kazu Hirata aa8feeefd3 Don't use Optional::hasValue (NFC) 2022-06-25 11:55:57 -07:00
David Candler d3919a8cc5 [ConstantFolding] Respect denormal handling mode attributes when folding instructions
Depending on the environment, a floating point instruction should
treat denormal inputs as zero, and/or flush a denormal output to zero.
Denormals are not currently accounted for when an instruction gets
folded to a constant, which can lead to differences in output between
a folded and a unfolded instruction when running on the target. The
denormal handling mode can be set by the function level attribute
denormal-fp-math, which this patch uses to determine whether any
denormal inputs to or outputs from folding should be zero, and that
the sign is set appropriately.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D116952
2022-06-20 16:41:46 +01:00
Kazu Hirata 129b531c9c [llvm] Use value_or instead of getValueOr (NFC) 2022-06-18 23:07:11 -07:00
Nikita Popov 7e64a29e58 [InstSimplify][IR] Handle trapping constant aggregate (PR49839)
Unfortunately, it's not just constant expressions that can trap,
we might also have a trapping constant expression nested inside
a constant aggregate.

Perform the check during phi folding on Constant rather than
ConstantExpr, and extend the Constant::mayTrap() implementation
to also recursive into ConstantAggregates, not just ConstantExprs.

Fixes https://github.com/llvm/llvm-project/issues/49839.
2022-06-13 12:35:17 +02:00
Simon Moll b8c2781ff6 [NFC] format InstructionSimplify & lowerCaseFunctionNames
Clang-format InstructionSimplify and convert all "FunctionName"s to
"functionName".  This patch does touch a lot of files but gets done with
the cleanup of InstructionSimplify in one commit.

This is the alternative to the less invasive clang-format only patch: D126783

Reviewed By: spatel, rengolin

Differential Revision: https://reviews.llvm.org/D126889
2022-06-09 16:10:08 +02:00
Sanjay Patel e8c20d995b [IR] add and use pattern match specialization for sqrt intrinsic; NFC
This was included in D126190 originally, but it's
independent and a useful change for readability.
2022-05-23 14:16:30 -04:00
Craig Topper f2df53b750 [InstructionSimplify] Remove multiple 'break' after 'return'. NFC 2022-05-20 10:23:57 -07:00
Nikita Popov ddfee07519 [InstSimplify] Fold and/or using implied conditions
This adds two conjugated folds:

 * A | B -> B if A implies B (https://alive2.llvm.org/ce/z/R6GU4j)
 * A & B -> A if A implies B (https://alive2.llvm.org/ce/z/EGMqyy)

If A and B are icmps themselves, we will usually fold this through
other logic already (though the tests show a couple additional cases
we previously missed). However, isImpliedCond() also supports A
being of the form X & Y, which allows us to handle cases like
(X & Y) | B where X implies B. This addresses the regression from
D125398.

Something that notably doesn't work yet is the (X | Y) & B case.
This is due to an asymmetry in the isImpliedCondition()
implementation that will have to be addressed separately.

Differential Revision: https://reviews.llvm.org/D125530
2022-05-13 15:09:14 +02:00
Nikita Popov c077510bb1 [InstSimplify] Handle unknown function context in pointer icmp fold (PR54615)
This issue reproduces in the context of LoopDeletion, because the
bitcast does not get simplified away there. For a plain -inst-simplify
run the bitcast would get folded away first.

Fixes https://github.com/llvm/llvm-project/issues/54615.
2022-05-10 11:48:43 +02:00
Serge Pavlov eb28da89a6 [InstCombine] Remove side effect of replaced constrained intrinsics
If a constrained intrinsic call was replaced by some value, it was not
removed in some cases. The dangling instruction resulted in useless
instructions executed in runtime. It happened because constrained
intrinsics usually have side effect, it is used to model the interaction
with floating-point environment. In some cases side effect is actually
absent or can be ignored.

This change adds specific treatment of constrained intrinsics so that
their side effect can be removed if it actually absents.

Differential Revision: https://reviews.llvm.org/D118426
2022-05-07 19:04:11 +07:00
Kevin P. Neal d43d9e1d5c [FPEnv][InstSimplify] Fold fsub -0.0, -X ==> X
Currently the fsub optimizations in InstSimplify don't know how to fold
-0.0 - (-X) to X when the constrained intrinsics are used. This adds partial
support. The rest of the support will come later with work on the IR
matchers.

This review is split out from D107285.

Differential Revision: https://reviews.llvm.org/D123396
2022-04-14 11:48:54 -04:00
Nikita Popov 1d530b914e [InstSimplify] Don't fold phi of poison and trapping const expr (PR49839)
Folding this case would result in the constant expression being
executed unconditionally, which may introduce a new trap.

Fixes https://github.com/llvm/llvm-project/issues/49839.
2022-04-12 17:32:25 +02:00
Hirochika Matsumoto 447a4485c5 [InstSimplify] Fold (ctpop(X) == N) || (X != 0) into X != 0 where N > 0
(ctpop(X) == N) || (X != 0) --> (X != 0) https://alive2.llvm.org/ce/z/udgUVV
(ctpop(X) != N) && (X == 0) --> (X == 0) https://alive2.llvm.org/ce/z/9dq-cR

Differential Revision: https://reviews.llvm.org/D122757
2022-04-04 23:23:34 +09:00
Nikita Popov 02c2106002 [InstSimplify] Handle vector GEP when simplifying zero indices
If the base is a scalar and the index is a vector, we can't
simplify, as this is effectively a splat operation.
2022-03-11 10:56:44 +01:00
serge-sans-paille 71c3a5519d Cleanup includes: LLVMAnalysis
Number of lines output by preprocessor:
before: 1065940348
after:  1065307662

Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D120659
2022-03-01 18:01:54 +01:00
Sanjay Patel fc3b34c508 [InstSimplify] remove shift that is redundant with part of funnel shift
In D111530, I suggested that we add some relatively basic pattern-matching
folds for shifts and funnel shifts and avoid a more specialized solution
if possible.

We can start by implementing at least one of these in IR because it's
easier to write the code and verify with Alive2:
https://alive2.llvm.org/ce/z/qHpmNn

This will need to be adapted/extended for SDAG to handle the motivating
bug ( #49541 ) because the patterns only appear later with that example
(added some tests: bb850d422b)

This can be extended within InstSimplify to handle cases where we 'and'
with a shift too (in that case, kill the funnel shift).
We could also handle patterns where the shift and funnel shift directions
are inverted, but I think it's better to canonicalize that instead to
avoid pattern-match case explosion.

Differential Revision: https://reviews.llvm.org/D120253
2022-02-23 09:10:01 -05:00
Philip Reames 34a9642af8 Revert "[instsimplify] Simplify HaveNonOverlappingStorage per review suggestion on D120133 [NFC]"
This reverts commit 3a6be124cc.  This appears to have caused a stage2 build failure: https://lab.llvm.org/buildbot/#/builders/168/builds/4813

Will investigate further on Monday and recommit.
2022-02-18 15:36:15 -08:00
Philip Reames 3a6be124cc [instsimplify] Simplify HaveNonOverlappingStorage per review suggestion on D120133 [NFC] 2022-02-18 11:33:15 -08:00
Philip Reames ff2e4c04c4 [instsimplify] Assume storage for byval args doesn't overlap allocas, globals, or other byval args
This allows us to discharge many pointer comparisons based on byval arguments.

Differential Revision: https://reviews.llvm.org/D120133
2022-02-18 11:08:01 -08:00
Philip Reames bf296ea6bb [instsimplify] Clarify assumptions about disjoint memory regions [NFC] 2022-02-18 08:51:18 -08:00
Philip Reames 5ecf218eca [instsimplify] Add a comment hinting how compares involving two globals are handled [NFC] 2022-02-18 08:41:30 -08:00
Philip Reames f6510e6d6f [instsimplify] Factor out a helper for alloca bounds checking [NFC]
At the moment, this just groups comments with a reasonably named predicate, but I plan to add other cases to this in the near future.
2022-02-18 07:40:22 -08:00
Philip Reames cf5e88864b [instsimplify] When compare allocas, consider their minimal size
The code was using exact sizing only, but since what we really need is just to make sure the offsets are in bounds, a minimum bound on the object size is sufficient.

To demonstrate the difference, support computing minimum sizes from obects of scalable vector type.
2022-02-17 09:53:24 -08:00
Philip Reames 2404313d80 [instsimplify] Fix a miscompile with zero sized allocas
Remove some code which tried to handle the case of comparing two allocas where an object size could not be precisely computed.  This code had zero coverage in tree, and at least one nasty bug.

The bug comes from the fact that the code uses the size of the result pointer as a proxy for whether the alloca can be of size zero.  Since the result of an alloca is *always* a pointer type, and a pointer type can *never* be empty, this check was a nop.  As a result, we blindly consider a zero offset from two allocas to never be equal.  They can in fact be equal when one or more of the allocas is zero sized.

This is particularly ugly because instcombine contains the exact opposite rule.  If instcombine reaches the allocas first, it combines them into one (making them equal).  If instsimplify reaches the compare first, it would consider them not equal.  This creates all kinds of fun scenarios for order of optimization reaching different and contradictory conclusions.
2022-02-17 09:27:34 -08:00
Nikita Popov c3c5280b0e [InstSimplify] Delay creation of constants for offsets (NFC)
Return APInt from stripAndComputeConstantOffsets(), and only
create corresponding Constants later, if we actually need them.
2022-02-17 09:56:32 +01:00
Kevin P. Neal 8290f2535b [FPEnv][FMF] Move helper function to header, move fast math flags to new include file.
In a prior review I was asked to move the helper function canIgnoreSNaN()
out to FPEnv.h. This wasn't possible at the time because that function
needs the fast math flags, and including them includes lots of other stuff
that isn't needed.

This patch moves the fast math flags out into a new FMF.h file unchanged,
and moves the helper function out to FPEnv.h also unchanged. This ticket
only moves code around.

Differential Revision: https://reviews.llvm.org/D119752
2022-02-16 12:34:53 -05:00
Kevin P. Neal c7400892ca [FPEnv][InstSimplify] Fold fsub X, -0 ==> X, when we know X is not -0
Currently the fsub optimizations in InstSimplify don't know how to fold
X - -0.0 to X when we know X is not zero and the constrained intrinsics
are used. This adds the support.

This review is split out from D107285.

Differential Revision: https://reviews.llvm.org/D119746
2022-02-16 10:10:13 -05:00
Nikita Popov f35af77573 [InstSimplify] Strip offsets once in computePointerICmp()
Instead of doing an inbounds strip first and another non-inbounds
strip afterward for equality comparisons, directly do a single
inbounds or non-inbounds strip based on whether we have an equality
predicate or not.

This is NFC-ish in that the alloca equality codepath is the only
part that sees additional non-inbounds offsets now, and for that
codepath it doesn't matter whether or not the GEP is inbounds, as
it does a stronger check itself. InstCombine would infer inbounds
for such GEPs.
2022-02-15 12:04:24 +01:00
Kevin P. Neal 22bd65fbe7 [FPEnv][InstSimplify] Fold fsub X, +0 ==> X
Currently the fsub optimizations in InstSimplify don't know how to fold X
- +0.0 to X when using the constrained intrinsics. This adds the support.

This review is split out from D107285.

Differential Revision: https://reviews.llvm.org/D118928
2022-02-14 11:56:45 -05:00
Nikita Popov 87a0b1bd23 [InstSimplify] Remove zero-index opaque pointer GEP
With opaque pointers, a zero-index GEP is a no-op. It does not
need to be retained for the pointer element type change it may
perform.
2022-02-10 16:01:56 +01:00
Nuno Lopes 0dc20e321c [InstSimplify] fold 'xor X, poison' and 'div/rem X, poison' to poison 2022-01-30 10:46:54 +00:00
Florian Hahn 1ef9bfa013
[InstSimplify] Pass pointer and indices separately to SimplifyGEPInst.
This doesn't require callers to put the pointer operand and the indices
in a container like a vector when calling the function. This is not
really an issue with the existing callers. But when using it from
IRBuilder the inputs are available as separate pointer value and indices
ArrayRef.

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D117038
2022-01-14 09:59:52 +00:00
Sanjay Patel 6bd127b079 [InstSimplify] use knownbits to fold more udiv/urem
We could use knownbits on both operands for even more folds (and there are
already tests in place for that), but this is enough to recover the example
from:
https://github.com/llvm/llvm-project/issues/51934
(the tests are derived from the code in that example)

I am assuming no noticeable compile-time impact from this because udiv/urem
are rare opcodes.

Differential Revision: https://reviews.llvm.org/D116616
2022-01-12 14:59:43 -05:00
Florian Hahn f0ef1ea6dd
[IRBuilder] Introduce folder using inst-simplify, use for Or fold.
Alternative to D116817.

This introduces a new value-based folding interface for Or (FoldOr),
which takes 2 values and returns an existing Value or a constant if the
Or can be simplified. Otherwise nullptr is returned. This replaces the
more restrictive CreateOr which takes 2 constants.

This is the used to implement a folder that uses InstructionSimplify.
The logic to simplify `Or` instructions is moved there. Subsequent
patches are going to transition other CreateXXX to the more general
FoldXXX interface.

Reviewed By: nikic, lebedev.ri

Differential Revision: https://reviews.llvm.org/D116935
2022-01-11 17:30:48 +00:00
Philip Reames 8f553da492 [instsimplify] Add a comment and test for a highly confusing case 2022-01-11 09:24:10 -08:00
Florian Hahn 8a469e2050
[InstSimplify] Fold inbounds GEP to poison if base is undef.
D92270 updated constant expression folding to fold inbounds GEP to
poison if the base is undef. Apply the same logic to SimplifyGEPInst.

The justification is that we can choose an out-of-bounds pointer as base
pointer.

Reviewed By: nikic, lebedev.ri

Differential Revision: https://reviews.llvm.org/D117015
2022-01-11 16:11:22 +00:00
Roman Lebedev a5a6960d1c
[NFCI][IR] MinMaxIntrinsic: add some more helper methods, and use them 2022-01-07 13:02:11 +03:00
Sanjay Patel c054402170 [InstSimplify] fold or-nand-xor
~(A & B) | (A ^ B) --> ~(A & B)

https://alive2.llvm.org/ce/z/hXQucg
2021-12-31 15:11:13 -05:00
Nuno Lopes 64af9f61c3 [InstSimplify] add 'x + poison -> poison' (needed for NewGVN) 2021-12-30 11:52:42 +00:00
Sanjay Patel 0edf99950e [Analysis] allow caller to choose signed/unsigned when computing constant range
We should not lose analysis precision if an 'add' has both no-wrap
flags (nsw and nuw) compared to just one or the other.

This patch is modeled on a similar construct that was added with
D59386.

I don't think it is possible to expose a problem with an unsigned
compare because of the way this was coded (nuw is handled first).

InstCombine has an assert that fires with the example from:
https://github.com/llvm/llvm-project/issues/52884
...because it was expecting InstSimplify to handle this kind of
pattern with an smax.

Fixes #52884

Differential Revision: https://reviews.llvm.org/D116322
2021-12-28 09:45:37 -05:00
Mehrnoosh Heidarpour 0ff20f2f44 [InstSimplify] Fold logic AND to zero
Adding following fold opportunity:
((A | B) ^ A) & ((A | B) ^ B) --> 0

Reviewed By: spatel, rampitec

Differential Revision: https://reviews.llvm.org/D115755
2021-12-23 10:06:26 -05:00
Hasyimi Bahrudin c1cd698a52 [InstSimplify] Simplify bool icmp with not in LHS
Refer to https://llvm.org/PR52546.

Simplifies the following cases:
    not(X) == 0 -> X != 0 -> X
    not(X) <=u 0 -> X >u 0 -> X
    not(X) >=s 0 -> X <s 0 -> X
    not(X) != 1 -> X == 1 -> X
    not(X) <=u 1 -> X >=u 1 -> X
    not(X) >s 1 -> X <=s -1 -> X

Differential Revision: https://reviews.llvm.org/D114666
2021-12-09 16:26:46 -05:00
Sanjay Patel 8a69b04478 [InstSimplify] add logic fold for 'or' with 'xor'+'and'
This replaces the 'or' from 4b30076f16 with an 'and'.
We have to guard against propagating undef elements from
vector 'not' values:
https://alive2.llvm.org/ce/z/irMwRc
2021-12-07 11:08:26 -05:00
Cullen Rhodes 0395e01583 [IR] Split vscale_range interface
Interface is split from:

  std::pair<unsigned, unsigned> getVScaleRangeArgs()

into separate functions for min/max:

  unsigned getVScaleRangeMin();
  Optional<unsigned> getVScaleRangeMax();

Reviewed By: sdesmalen, paulwalker-arm

Differential Revision: https://reviews.llvm.org/D114075
2021-12-07 10:38:26 +00:00
Sanjay Patel c65e651e60 [InstSimplify] fix logic fold of 'or' for vectors
Reduce code duplication for commutative pattern matching
and fix a miscompile.

We can't safely propagate an undef element in this transform:
https://alive2.llvm.org/ce/z/s5xy55
2021-12-05 09:57:07 -05:00
Mehrnoosh Heidarpour e94134052f [InstSimplify] Add logic 'or' fold to -1
Adding the following folding opportunity:
(~A | B) | (A ^ B) --> -1

https://alive2.llvm.org/ce/z/PMtdYB

Differential revision: https://reviews.llvm.org/D114996
2021-12-04 15:04:18 -05:00
Sanjay Patel 97e921c81f [PatternMatch] create and use matcher for 'not' that excludes undef elements
We needed a stricter version of m_Not for D114462, but I wasn't
sure if that was going to be required anywhere else, so I didn't bother
to make that reusable.

It turns out we have one more existing simplification that needs
this (currently miscompiles):
https://alive2.llvm.org/ce/z/9-nTKi

And there's at least one more fold in that family that we could add.

Differential Revision: https://reviews.llvm.org/D114882
2021-12-02 08:51:13 -05:00
Sanjay Patel 4b30076f16 [InstSimplify] add logic fold for 'or'
https://alive2.llvm.org/ce/z/4PaPDy

There's a related fold where the inner 'or' is replaced by 'and',
but that needs to be more careful about matching a 'not'.
2021-11-30 14:08:54 -05:00
Sanjay Patel c49ef1448d [InstSimplify] reduce code duplication for 'or' logic folds; NFC 2021-11-30 14:08:54 -05:00