884 Commits

Author SHA1 Message Date
Nikita Popov
72ec2c007e [InstCombine] Fix handling of irreducible loops (PR64259)
Fixes a regression introduced by D75362 for irreducible control
flow. In that case, we may visit the predecessor that renders
the current block live only later, and incorrectly determine
that a block is dead.

Instead, switch to using the same DeadEdges based implementation
we also use during the main InstCombine iteration.

This temporarily regresses some cases that need replacement of
dead phi operands with poison, which is currently only done during
the main run, but not worklist population. This will be addressed
in a followup, to keep it separate from the correctness fix here.

Fixes https://github.com/llvm/llvm-project/issues/64259.
2023-07-31 16:20:22 +02:00
Nikita Popov
09156b36c6 [InstCombine] Move worklist preparation into InstCombinerImpl (NFC) 2023-07-31 15:18:12 +02:00
Nikita Popov
41895843b5 [InstCombine] Only perform one iteration
InstCombine is a worklist-driven algorithm, which works roughly
as follows:

* All instructions are initially pushed to the worklist.
  The initial order is in RPO program order.
* All newly inserted instructions get added to the worklist.
* When an instruction is folded, its users get added back to the
  worklist.
* When the use-count of an instruction decreases, it gets added
  back to the worklist.
* And a few of other heuristics on when we should revisit
  instructions.

On top of the worklist algorithm, InstCombine layers an additional
fix-point iteration: If any fold was performed in the previous
iteration, then InstCombine will re-populate the worklist from
scratch and fold the entire function again. This continues until
a fix-point is reached.

In the vast majority of cases, InstCombine will reach a fix-point
within a single iteration: However, a second iteration is performed
to verify that this is indeed the fixpoint. We can see this in the
statistics for llvm-test-suite:

    "instcombine.NumOneIteration": 411380,
    "instcombine.NumTwoIterations": 117921,
    "instcombine.NumThreeIterations": 236,
    "instcombine.NumFourOrMoreIterations": 2,

The way to read these numbers is that in 411380 cases, InstCombine
performs no folds. In 117921 cases it performs a fold and reaches
the fix-point within one iteration (the second iteration verifies
the fixpoint). In the remaining 238 cases, more than one iteration
is needed to reach the fixpoint.

In other words, only in 0.04% of cases are additional iterations
needed to reach a fixpoint. Conversely, in 22.3% of cases InstCombine
performs a completely useless extra iteration to verify the fix point.

This patch removes the fixpoint iteration from InstCombine, and always
only perform a single iteration. This results in a major compile-time
improvement of around 4% at negligible codegen impact.

This explicitly does accept that we will not reach a fixpoint in all
cases. However, this is mitigated by two factors: First, the data
suggests that this happens very rarely in practice. Second,
InstCombine runs many times during the optimization pipeline
(8 times even without LTO), so there are many chances to recover
such cases.

In order to prevent accidental optimization regressions in the
future, this implements a verify-fixpoint option, which is enabled
by default when instcombine is specified in -passes and disabled
when InstCombinePass() is constructed from C++. This means that
test cases need to explicitly use the no-verify-fixpoint option
if they fail to reach a fixed point (for a well understand reason
we cannot / do not want to avoid).

Differential Revision: https://reviews.llvm.org/D154579
2023-07-31 10:56:49 +02:00
Nikita Popov
ad7f02010f [InstCombine] Process blocks in RPO
InstComine currently processes blocks in an arbitrary
depth-first order. This can break the usual invariant that the
operands of an instruction should be simplified before the
instruction itself, if uses across basic blocks (particularly
inside phi nodes) are involved.

This patch switches the initial worklist population to use RPO
instead, which will ensure that predecessors are visited before
successors (back-edges notwithstanding).

This allows us to fold more cases within a single InstCombine
iteration, in preparation for D154579. This change by itself
is a minor compile-time regression of about 0.1%, which will
be more than recovered by switching to single-iteration InstCombine.

Differential Revision: https://reviews.llvm.org/D75362
2023-07-30 18:38:45 +02:00
Nikita Popov
70aca7b122 [InstCombine] Explicitly track dead edges
This allows us to handle dead blocks with multiple incoming edges,
where we can determine that all of those edges are dead (or cycles).

This allows InstCombine to handle certain dead code patterns that
can be produced by LoopVectorize in a single iteration.

This is in preparation for D154579.
2023-07-27 16:41:03 +02:00
Antonio Frighetto
ac3f6899f4 [InstCombine] Do not assume scalar types in select/zext
Do not assume scalar types when folding binops of `select`
operations and `zext`/`sext` of their condition.

Reported-by: Benjins, dyung

Proofs: https://alive2.llvm.org/ce/z/GmDLns
2023-07-23 11:07:13 +00:00
Antonio Frighetto
f12a5561b2 [InstCombine] Fold binop of select and cast of select condition
Simplify binary operations, whose operands involve a `select`
instruction and a cast of the `select` condition. Specifically,
the binop is canonicalized into a `select` with folded arguments
as follows:

(Binop (zext C), (select C, T, F))
  -> (select C, (binop 1, T), (binop 0, F))

(Binop (sext C), (select C, T, F))
  -> (select C, (binop -1, T), (binop 0, F))

Proofs: https://alive2.llvm.org/ce/z/c_JwwM

Differential Revision: https://reviews.llvm.org/D153963
2023-07-20 19:42:58 +00:00
Nikita Popov
632594fcb1 [InstCombine] Avoid ConstantExpr::get()
Use ConstantFoldBinaryOpOperands() instead of ConstantExpr::get().
This will continue working with binary operands that are not
supported as constant expressions.
2023-07-20 15:24:02 +02:00
Nikita Popov
bc49103015 [InstCombine] Don't handle constants in de morgan folds (PR63791)
If the and/or operand is an immediate constant, it will get folded
away anyway. Don't try to freely invert those operands.

A particularly degenerate case of this arises when both operands
are constant and the result is a constant, in which case we try
to invert users of a constant, resulting in an assertion failure.

Fixes https://github.com/llvm/llvm-project/issues/63791.
2023-07-11 15:18:53 +02:00
Nikita Popov
143a869cf2 [InstCombine] Handle unreachable edge when branching to loop
The successor is unreachable if either this is the only edge, or
this is an edge into a loop, in which case other predecessors
don't matter. This is exactly what the edge dominance check does.
2023-07-07 16:07:18 +02:00
Arthur Eubanks
457dc72fdd Reland [InstCombine] Infer inbounds for more GEPs of dereferenceable pointers
Use Value::getPointerDereferenceableBytes() instead of hardcoding dereferenceable only for allocas. Allows us to infer inbounds GEPs for other Values like CallInsts and Arguments.

Fixed clang test broken in initial land.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D153815
2023-06-27 09:31:20 -07:00
Arthur Eubanks
0f9df062ec Revert "[InstCombine] Infer inbounds for more GEPs of dereferenceable pointers"
This reverts commit cd43b19c0127d80f3543803359db0f03e363e893.

Breaks clang/test/CodeGenOpenCL/builtins-amdgcn.cl.
2023-06-27 09:27:15 -07:00
Arthur Eubanks
cd43b19c01 [InstCombine] Infer inbounds for more GEPs of dereferenceable pointers
Use Value::getPointerDereferenceableBytes() instead of hardcoding dereferenceable only for allocas. Allows us to infer inbounds GEPs for other Values like CallInsts and Arguments.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D153815
2023-06-27 09:13:00 -07:00
Nikita Popov
8762f4c748 [InstCombine] Track inserted instructions when lowering objectsize
The inserted instructions can usually be simplified. Make sure this
happens in the same InstCombine iteration by adding them to the
worklist.

We happen to get some better optimization in two cases, but this is
just a lucky accident. https://github.com/llvm/llvm-project/issues/63472
tracks implementing a fold for that case.

This doesn't track all inserted instructions yet, for that we would
also have to include those created by ObjectSizeOffsetEvaluator.
2023-06-23 15:36:23 +02:00
Nikita Popov
252d1c48c4 [InstCombine] Remove instructions before non-terminator unreachable
Treat non-terminator unreachable the same as unreachable, and
remove guaranteed-to-transfer instructions before it.
2023-06-22 16:33:53 +02:00
Nikita Popov
10451ded6d [InstCombine] Remove code after non-terminator unreachable
Instruction after a non-terminator unreachable are ... unreachable,
so remove them. Reuse the same logic we use for removing
instructions from dead blocks.
2023-06-22 15:59:10 +02:00
Noah Goldstein
91cdffcb2f [InstCombine] Transform (binop1 (binop2 (lshift X,Amt),Mask),(lshift Y,Amt))
If `Mask` and `Amt` are not constants and `binop1` and `binop2` are
the same we can transform to:
`(binop (lshift (binop X, Y), Amt), Mask)`

If `binop` is `add`, `lshift` must be `shl`.

If `Mask` and `Amt` are constants `C` and `C1` respectively.
We can transform to:
`(lshift1 (binop1 (binop2 X, (inv_lshift1 C, C1), Y)), C1)`

Saving an instruction IFF:
`lshift1` is same opcode as `lshift2`
Either `bitwise1` and/or `bitwise2` is `and`.

Proofs(1/2): https://alive2.llvm.org/ce/z/BjN-m_
Proofs(2/2): https://alive2.llvm.org/ce/z/bZn5QB

This is to help fix the regression caused in D151807

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D152568
2023-06-13 20:08:35 -05:00
Kazu Hirata
ef09abfcf4 [InstCombine] Remove unused function createInstructionCombiningPass
The last use was removed by:

  commit 934c82d31801e65aa3bbe99a0e64f903621c2e04
  Author: Florian Hahn <flo@fhahn.com>
  Date:   Fri Feb 24 13:39:32 2023 +0100

Once I remove createInstructionCombiningPass, then:

InstructionCombiningPass::InstructionCombiningPass(unsigned MaxIterations)

becomes unused.  Once I remove that:

InstructionCombiningPass::MaxIterations is always initialized with
InstCombineDefaultMaxIterations, so this patch does the constant
propagation and removes InstructionCombiningPass::MaxIterations as
well.

Differential Revision: https://reviews.llvm.org/D152641
2023-06-11 07:56:37 -07:00
Nikita Popov
cde681c865 [InstCombine] Replace phi operands in successors of unreachable block
Set these operands to poison, which might allow folding the phi node,
or reduce the use count of an instruction.
2023-06-09 12:31:07 +02:00
Nikita Popov
e4a589ba5d [InstCombine] Add stats for number of iterations (NFC) 2023-06-06 15:17:47 +02:00
Jie Fu
d0a4dcf52f [InstCombine] Remove unused function 'isMustTailCall' (NFC)
/data/llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:2467:13: error: unused function 'isMustTailCall' [-Werror,-Wunused-function]
static bool isMustTailCall(Value *V) {
            ^
1 error generated.
2023-05-30 18:30:44 +08:00
Nikita Popov
f1106ef6c9 [InstCombine] Remove computeKnownBits() fold for returns
We try to fold constant computeKnownBits() with context for return
instructions only. Otherwise, we rely on SimplifyDemandedBits() to
fold instructions with constant known bits.

The presence of this special fold for returns is dangerous, because
it makes our tests lie about what works and what doesn't. Tests are
usually written by returning the result we're interested in, but
will go through this separate code path that is not used for anything
else. This patch removes the special fold.

This primarily regresses patterns of the style "assume(x); return x".
The responsibility of handling such patterns lies with passes like
EarlyCSE/GVN anyway, which will do this reliably, and not just for
returns.

Differential Revision: https://reviews.llvm.org/D151099
2023-05-30 12:16:51 +02:00
Nikita Popov
ca18e21951 [InstCombine] Remove instructions in dead blocks during combining
We already do this during initial worklist population. Doing this
as part of primary combining allows us to remove instructions in
blocks that were rendered dead by condition folding within the
same instcombine iteration.
2023-05-26 16:43:34 +02:00
Nikita Popov
1fc425380e [InstCombine] Handle undef when pruning unreachable code
If the branch condition is undef, then behavior is undefined and
neither of the successors are live.

This is to ensure that optimization quality does not decrease
when a constant gets replaced with undef/poison in this context.
2023-05-26 15:55:28 +02:00
Nikita Popov
18a5bd7a95 [InstCombine] Add droppable users back to worklist (NFCI)
When sinking and users are dropped, add the using instructions
to the worklist, as they can likely be removed as well.

This should be NFC apart from worklist order effects.
2023-05-23 17:01:23 +02:00
eopXD
c8eb535aed [1/11][IR] Permit load/store/alloca for struct of the same scalable vector type
This patch-set aims to simplify the existing RVV segment load/store
intrinsics to use a type that represents a tuple of vectors instead.

To achieve this, first we need to relax the current limitation for an
aggregate type to be a target of load/store/alloca when the aggregate
type contains homogeneous scalable vector types. Then to adjust the
prolog of an LLVM function during lowering to clang. Finally we
re-define the RVV segment load/store intrinsics to use the tuple types.

The pull request under the RVV intrinsic specification is
riscv-non-isa/rvv-intrinsic-doc#198

---

This is the 1st patch of the patch-set. This patch is originated from
D98169.

This patch allows aggregate type (StructType) that contains homogeneous
scalable vector types to be a target of load/store/alloca. The RFC of
this patch was posted in LLVM Discourse.

https://discourse.llvm.org/t/rfc-ir-permit-load-store-alloca-for-struct-of-the-same-scalable-vector-type/69527

The main changes in this patch are:

Extend `StructLayout::StructSize` from `uint64_t` to `TypeSize` to
accommodate an expression of scalable size.

Allow `StructType:isSized` to also return true for homogeneous
scalable vector types.

Let `Type::isScalableTy` return true when `Type` is `StructType`
and contains scalable vectors

Extra description is added in the LLVM Language Reference Manual on the
relaxation of this patch.

Authored-by: Hsiangkai Wang <kai.wang@sifive.com>
Co-Authored-by: eop Chen <eop.chen@sifive.com>

Reviewed By: craig.topper, nikic

Differential Revision: https://reviews.llvm.org/D146872
2023-05-19 09:39:36 -07:00
Nikita Popov
3d53587901 [InstCombine] Don't create bitcast when simplifying round-trip
The bitcast was not being added to the worklist. I could switch
this to use the IRBuilder instead, but this bitcast is not relevant
with opaque pointers anyway, so just drop it entirely.
2023-05-17 15:51:09 +02:00
Kazu Hirata
053d2471f8 [InstCombine] Remove Descale
The last use of Descale was removed on Apr 6, 2023 in commit
db6b30b1831095c216378a9df215b7c0ae6b959f.

Differential Revision: https://reviews.llvm.org/D150045
2023-05-06 18:20:19 -07:00
Noah Goldstein
6cdc229a64 [InstCombine] Fix bug in FoldOpIntoSelect where we would incorrectly fold undef as constant
D146349 Introduced the ability to use the information from the
`select` condition to deduce constants as we folded a binop into
select. I.e if the `select` cond was `icmp eq %A, 10`, then in the
true-arm of `select`, we would be able to replace usage of `A` with
`10`.

This is broken for vectors that contain `undef` elements. I.e with
`icmp eq %A, <10, undef>`, subsituting `<10, undef>` for `A` can
result in creating a more undefined result than we otherwise would
have.

We fix the issue with simply checking if the candidate constant for
substituting may contain `undef` elements and don't do it in that
case.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D149592
2023-05-01 17:23:54 -05:00
Yingwei Zheng
6d667d4b26
[InstCombine] Combine const GEP chains
This patch reverts rGae739aefd7473517d3f08b5c8d08a66c7f469198 to address performance regressions reported by our [CI](https://github.com/dtcxzyw/llvm-ci/issues/137) after rG2ec1d0f427c7822540352c0c14d057e7bfe4f77b.

For example:
```
define ptr @const_gep_chain(ptr %p, i64 %a) {
    %p1 = getelementptr inbounds i8, ptr %p, i64 %a
    %p2 = getelementptr inbounds i8, ptr %p1, i64 1
    %p3 = getelementptr inbounds i8, ptr %p2, i64 2
    %p4 = getelementptr inbounds i8, ptr %p3, i64 3
    ret ptr %p4
}
```
The last three GEPs will not be folded since rG2ec1d0f427c7822540352c0c14d057e7bfe4f77b.

I think it is appropriate to remove this code because there is no compile-time regression reported in our benchmarks.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D149240
2023-05-02 00:28:39 +08:00
ManuelJBrito
d22edb9794 [IR][NFC] Change UndefMaskElem to PoisonMaskElem
Following the change in shufflevector semantics,
poison will be used to represent undefined elements in shufflevector masks.

Differential Revision: https://reviews.llvm.org/D149256
2023-04-27 18:01:54 +01:00
OCHyams
bd1109307a [DebugInfo][InstCombine] Fix missing source and variable locations after foldOpIntoPhi
Reviewed By: fdeazeve

Differential Revision: https://reviews.llvm.org/D149335
2023-04-27 13:56:09 +01:00
Nikita Popov
2ec1d0f427 [InstCombine] Don't reassociate GEPs for loop invariance
Since D146813, LICM will reassociate GEPs to expose hoisting
opportunities itself. Don't perform this transform in InstCombine,
where it is fragile because it depends on an optional LoopInfo
analysis.
2023-04-18 12:17:07 +02:00
Noah Goldstein
82f0827613 [InstCombine] Make FoldOpIntoSelect handle non-constants and use condition to deduce constants.
Make the fold use the information present in the condition for deducing constants i.e:
```
%c = icmp eq i8 %x, 10
%s = select i1 %c, i8 3, i8 2
%r = mul i8 %x, %s
```

If we fold the `mul` into the select, on the true side we insert `10` for `%x` in the `mul`.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D146349
2023-04-14 13:14:32 -05:00
Nikita Popov
62ef97e063 [llvm-c] Remove PassRegistry and initialization APIs
Remove C APIs for interacting with PassRegistry and pass
initialization. These are legacy PM concepts, and are no longer
relevant for the new pass manager.

Calls to these initialization functions can simply be dropped.

Differential Revision: https://reviews.llvm.org/D145043
2023-04-14 12:12:48 +02:00
Bjorn Pettersson
410775ecfd [Transforms][LTO] Remove some redundant includes. NFC
No need to include CallGraphSCCPass.h from the IPO/Inliner.

Also removed the include of LegacyPassManager.h in a couple of files
that do not really depend on that header file.

Differential Revision: https://reviews.llvm.org/D148083
2023-04-13 10:12:00 +02:00
Michael Liao
72fc08a541 [InstCombine] Teach alloca replacement to handle addrspacecast
- As the address space cast may not be valid on a specific target,
  `addrspacecast` is not handled when an `alloca` is able to be replaced
  with the source of memcpy/memmove. This patch addresses that by
  querying a target hook on whether that address space cast is valid.
  For example, on most GPU targets, the cast from a global pointer to a
  generic pointer is valid.
- If that cast is allowedd (by querying `isValidAddrSpaceCast`), the
  replacement is enhanced to handle that `addrspacecast` as well.

Reviewed By: yaxunl

Differential Revision: https://reviews.llvm.org/D147025
2023-04-11 11:47:37 -04:00
Nikita Popov
a162ddf7f2 [InstCombine] Remove various checks for opaque pointers (NFC)
All pointers are opaque now, so these are no longer necessary.
2023-04-06 09:45:51 +02:00
Nikita Popov
db6b30b183 [InstCombine] Remove GEP of bitcast folds (NFC)
These only support typed pointers, and as such are no longer
relevant.
2023-04-06 09:15:33 +02:00
Nikita Popov
cf9f1a8203 [InstCombine] Remove visitGEPOfBitcast() fold (NFC)
This does not apply to opaque pointers, and as such is no longer
necessary.
2023-04-06 09:04:31 +02:00
Nikita Popov
53280dba83 [InstCombine] Use CreateGEP() API (NFC)
Use the IRBuilder API that accepts inbounds as a boolean parameter,
rather than using a ternary.
2023-04-05 15:02:45 +02:00
Nikita Popov
6261adfa51 [InstCombine] Fold more intrinsics over selects
Move this handling to a centralized place and extend it to handle
saturating add/sub intrinsics.

I originally wanted to make this fully generic rather than
whitelist based, because this is legal and likely profitable for all
speculatable intrinsics. The caveat is that for vector selects,
the intrinsic can't perform cross-lane operations like a shuffle
or reduction, which we don't really expose as a generic property
right now. So for now I'm just extending the list.
2023-03-31 16:32:21 +02:00
Nikita Popov
cbca9ce91c [InstCombine] Remove min/max special case when folding into select
Now that we canonicalize to min/max intrinsics, we no longer need
to guard against this here.

In fact, it seems like the issue from PR46271 was the final push
for introducing the intrinsics in the first place...
2023-03-31 13:48:21 +02:00
Nikita Popov
d0de2c51c9 [InstCombine] Simplify foldOperationIntoSelectOperand() (NFCI)
Rather than handling all instruction types separately, clone the
original instruction and replace the select operand.
2023-03-21 10:02:29 +01:00
luxufan
6beb371e4c [InstCombine] Combine binary operator of two phi node
Combine binary operator of two phi node if there is at least one
specific constant value in phi0 and phi1's incoming values for each
same incoming block and this specific constant value can be used
to do optimization for specific binary operator.
For example:
```
%phi0 = phi i32 [0, %bb0], [%i, %bb1]
%phi1 = phi i32 [%j, %bb0], [0, %bb1]
%add = add i32 %phi0, %phi1
==>
%add = phi i32 [%j, %bb0], [%i, %bb1]
```

Fixes: https://github.com/llvm/llvm-project/issues/61137

Differential Revision: https://reviews.llvm.org/D145223
2023-03-21 15:24:17 +08:00
Sanjay Patel
ef6f23535d Revert "[InstCombine] use loop info when running the pass after loop vectorization"
This reverts commit 43ae4b62b2671cf73e691c0b53324cd39405cd51.

This was intended to be practically NFC in terms of the overall
opt pipeline, but there is experimental data showing that code
changes occurred here:
https://llvm-compile-time-tracker.com/compare.php?from=772aa05452f8ff90a47168e6801cda2acb5a1873&to=43ae4b62b2671cf73e691c0b53324cd39405cd51&stat=size-text
2023-03-11 17:28:56 -05:00
Sanjay Patel
43ae4b62b2 [InstCombine] use loop info when running the pass after loop vectorization
This is the follow-up to D144199 and suggestion from D144045.
We make use of loop info explicit via InstCombine pass parameter
rather than semi-arbitrary via caching.

The only InstCombine transform that uses LoopInfo currently is a
GEP fold in visitGEPOfGEP(), so that shows up as a failure in the
dedicated test for the fold as well as several LoopVectorizer tests
that run extra passes.

I don't see any pass manager regression tests that actually check
for pass options, but this is intended to be NFC for the pass
pipeline behavior - we only try to use loop info where it would
have been used before via caching .

Differential Revision: https://reviews.llvm.org/D144274
2023-03-11 14:20:30 -05:00
Nikita Popov
f7ca013332 [llvm-c] Remove bindings for creating legacy passes
Legacy passes are only supported for codegen, and I don't believe
it's possible to write backends using the C API, so we should drop
all of those. Reduces the number of places that need to be modified
when removing legacy passes.

Differential Revision: https://reviews.llvm.org/D144970
2023-03-02 09:53:50 +01:00
Nikita Popov
ee2f9d6dfb Reapply [InstCombine] Remove early constant fold
The reported compile-time regression has been address in
47f9109dff80a1abbe2705ee71dc0882b1d62274.

Additionally, this contains a change to immediately fold zext
with constant operand, even if it's used in a trunc. I'm not sure
if this is relevant for anything, but I noticed it as a behavioral
discrepancy when investigating this issue.

-----

InstCombine currently performs a constant folding attempt as part
of the main InstCombine loop, before visiting the instruction.
However, each visit method will also attempt to simplify the
instruction, which will in turn constant fold it. (Additionally,
we also constant fold instructions before the main InstCombine loop
and use a constant folding IR builder, so this is doubly redundant.)

There is one place where InstCombine visit methods currently don't
call into simplification, and that's casts. To be conservative,
I've added an explicit constant folding call there (though it has
no impact on tests).

This makes for a mild compile-time improvement and in particular
mitigates the compile-time regression from enabling load
simplification in be88b5814d9efce131dbc0c8e288907e2e6c89be.

Differential Revision: https://reviews.llvm.org/D144369
2023-02-27 12:23:06 +01:00
Vitaly Buka
779679284e Revert "[InstCombine] Remove early constant fold"
Increase compile time with ubsan ARM from 3 to 14 min single file.
I upload reproducer into D144369.

Also we have random timeouts on internal x86_64 builds.
Both bisected to this one.

This reverts commit 45a0b812fa13ec255cae91f974540a4d805a8d79.
2023-02-24 10:21:32 -08:00