4174 Commits

Author SHA1 Message Date
natanelh-mobileye
fa78d6a5f1
[SDAG] Shrink (abd? (?ext x) (?ext y)) (#171865)
Alive2 test: https://alive2.llvm.org/ce/z/maryYU
Lit test before change: https://godbolt.org/z/nEKWdPbMv

Fixes #171640
2025-12-17 16:30:52 +00:00
Simon Pilgrim
a68fde5780
[DAG] foldAddToAvg - optimize nested m_Reassociatable matchers (#171681)
The use of nested m_Reassociatable matchers by #169644 can result in
high compile times as the inner m_Reassociatable call is being repeated
a lot while the outer call is trying to match. Place the inner
m_ReassociatableAnd at the beginning of the pattern so it is not
repeatedly matched in recursion.
2025-12-15 13:41:02 +00:00
Shubham Sandeep Rastogi
16e6055273
Revert "[SelectionDAG] Salvage debuginfo when combining load and sext… (#171745)
… instrs. (#169779)"

This reverts commit 2b958b9ee24b8ea36dcc777b2d1bcfb66c4972b6.

I might have broken the sanitizer-x86_64-linux bot


/home/b/sanitizer-x86_64-linux/build/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_linux.cpp
clang++:
/home/b/sanitizer-x86_64-linux/build/llvm-project/llvm/include/llvm/ADT/ArrayRef.h:248:
const T &llvm::ArrayRef<llvm::DbgValueLocEntry>::operator[](size_t)
const [T = llvm::DbgValueLocEntry]: Assertion `Index < Length &&
"Invalid index!"' failed.
2025-12-10 16:49:59 -08:00
Shubham Sandeep Rastogi
2b958b9ee2
[SelectionDAG] Salvage debuginfo when combining load and sext instrs. (#169779)
SelectionDAG uses the DAGCombiner to fold a load followed by a sext to a
load and sext instruction. For example, in x86 we will see that

```
%1 = load i32, ptr @GlobArr
  #dbg_value(i32 %1, !43, !DIExpression(), !52)
%2 = sext i32 %1 to i64, !dbg !53
```

is converted to:

```
%0:gr64_nosp = MOVSX64rm32 $rip, 1, $noreg, @GlobArr, $noreg, debug-instr-number 1, debug-location !51
DBG_VALUE $noreg, $noreg, !"Idx", !DIExpression(), debug-location !52
```

The `DBG_VALUE` needs to be transferred correctly to the new combined
instruction, and it needs to be appended with a `DIExpression` which
contains a `DW_OP_LLVM_fragment`, describing that the lower bits of the
virtual register contain the value.

This patch fixes the above described problem.
2025-12-10 14:43:38 -08:00
Simon Pilgrim
804e768bda
[DAG] Recognise AVGFLOOR (((A >> 1) + (B >> 1)) + (A & B & 1)) patterns (#169644)
Recognise 'LSB' style AVGFLOOR patterns.

Alive2:
[https://alive2.llvm.org/ce/z/nfSSk_](https://alive2.llvm.org/ce/z/nfSSk_)

Fixes #53648
2025-12-10 08:44:11 +00:00
Guy David
29611f4cbe
[DAGCombiner] Relax nsz constraint for FP optimizations (#165011)
Some floating-point optimization don't trigger because they can produce
incorrect results around signed zeros, and rely on the existence of the
nsz flag which commonly appears when fast-math is enabled.
However, this flag is not a hard requirement when all of the users of
the combined value are either guaranteed to overwrite the sign-bit or
simply ignore it (comparisons, etc.).

The optimizations affected:
- fadd x, +0.0 -> x
- fsub x, -0.0 -> x
- fsub +0.0, x -> fneg x
- fdiv(x, sqrt(x)) -> sqrt(x)
- frem lowering with power-of-2 divisors
2025-12-09 12:07:46 +02:00
David Green
0959bb3001
[DAG] Generate UMULH/SMULH with wider vector types (#170283)
The existing code for generating umulh/smulh was checking that that the
getTypeToTransformTo was a LegalOrCustom operation. This only takes a
single legalization step though, so if v4i32 was legal, a v8i32 would be
transformed but a v16i32 would not.

This patch introduces a getLegalTypeToTransformTo that performs
getTypeToTransformTo until a legal type is reached. The umulh/smulh code
can then use it to check if the final resultant type will be legal.
2025-12-08 19:35:32 +00:00
Hongyu Chen
11866c499b
[DAGCombiner] Don't peek through bitcast when checking isMulAddWithConstProfitable (#171056)
Fixes https://github.com/llvm/llvm-project/issues/171035
Peeking through bitcast may cause type mismatch between `AddNode` and
`ConstNode` in `isMulAddWithConstProfitable`.
2025-12-08 22:09:12 +08:00
Valeriy Savchenko
5c6918f24d
[DAGCombiner] Allow promoted constants in MULHU by power-of-2 -> SRL transform (#170562)
Type legalization can promote constant operands. The MULHU optimization
`mulhu x, (1 << c) -> x >> (bitwidth - c)` was failing when constants
were promoted because:

  1. `isConstantOrConstantVector` check rejected promoted constants
2. `BuildLogBase2` -> `takeInexpensiveLog2` -> `matchUnaryPredicate`
rejected promoted constants

This fixes both by adding `AllowTruncation=true`, following the pattern
from the recent UDIV fix (#169491).
2025-12-04 13:32:19 +00:00
Valeriy Savchenko
8e53a88de3
[DAGCombiner] Handle type-promoted constants in SDIV lowering (#169924)
Builds up on the solution proposed for #169491 and applies it for SDIV
as well.
2025-12-04 11:33:19 +00:00
Valeriy Savchenko
c5fa1f8c4b
[DAGCombiner] Handle type-promoted constants in UDIV lowering (#169491) 2025-12-03 19:34:21 +00:00
Matt Arsenault
cdb501064f
DAG: Avoid more uses of getLibcallName (#170402) 2025-12-03 13:01:04 -05:00
Lewis Crawford
ea3fdc5972
Avoid maxnum(sNaN, x) optimizations / folds (#170181)
The behaviour of constant-folding `maxnum(sNaN, x)` and `minnum(sNaN,
x)` has become controversial, and there are ongoing discussions about
which behaviour we want to specify in the LLVM IR LangRef.

See:
  - https://github.com/llvm/llvm-project/issues/170082
  - https://github.com/llvm/llvm-project/pull/168838
  - https://github.com/llvm/llvm-project/pull/138451
  - https://github.com/llvm/llvm-project/pull/170067
-
https://discourse.llvm.org/t/rfc-a-consistent-set-of-semantics-for-the-floating-point-minimum-and-maximum-operations/89006

This patch removes optimizations and constant-folding support for
`maxnum(sNaN, x)` but keeps it folded/optimized for `qNaN`. This should
allow for some more flexibility so the implementation can conform to
either the old or new version of the semantics specified without any
changes.

As far as I am aware, optimizations involving constant `sNaN` should
generally be edge-cases that rarely occur, so here should hopefully be
very little real-world performance impact from disabling these
optimizations.
2025-12-02 12:43:03 +00:00
Simon Pilgrim
38678a91f3
[DAG] getCarry - always succeed if we encounter a i1 type during trunc/ext peeling (#169777)
If we are force reconstructing a carry from a raw MVT::i1 type, make
sure we don't miss any cases while peeling through trunc/ext chains -
check for i1 types at the start of the while loop

Fixes #169691
2025-11-30 18:26:24 +00:00
Hongyu Chen
3fec26e329
[DAGCombiner] Don't optimize insert_vector_elt into shuffle if implicit truncation exists (#169022)
Fixes #169017
2025-11-22 03:33:53 +08:00
Craig Topper
01e5e4fd00
[DAGCombiner] Remove unneeded m_BitReverse from visitBITREVERSE. NFC (#168918)
We already know we're looking at BITREVERSE, we can match on the source
operand.
2025-11-20 18:20:47 +00:00
Matt Arsenault
0e1cb2de90
Reapply "DAG: Allow select ptr combine for non-0 address spaces" (#168292) (#168786)
This reverts commit 6d5f87fc4284c4c22512778afaf7f2ba9326ba7b.

Previously this failed due to treating the unknown MachineMemOperand
value as known uniform.
2025-11-20 12:13:46 -05:00
Sander de Smalen
f369a53d82
[DAGCombiner] Fold select into partial.reduce.add operands. (#167857)
This generates more optimal codegen when using partial reductions with
predication.

```
partial_reduce_*mla(acc, sel(p, mul(*ext(a), *ext(b)), splat(0)), splat(1))
-> partial_reduce_*mla(acc, sel(p, a, splat(0)), b)

partial.reduce.*mla(acc, sel(p, *ext(op), splat(0)), splat(1))
-> partial.reduce.*mla(acc, sel(p, op, splat(0)), splat(trunc(1)))
```
2025-11-18 09:49:42 +00:00
ronlieb
6d5f87fc42
Revert "DAG: Allow select ptr combine for non-0 address spaces" (#168292)
Reverts llvm/llvm-project#167909
2025-11-16 18:35:51 -05:00
Matt Arsenault
dd9bd3e8f0
DAG: Preserve poison in combineConcatVectorOfScalars (#168220) 2025-11-16 11:16:34 -08:00
Mikołaj Piróg
e7b41df10e
[SelectionDAGBuilder] Propagate fast-math flags to fpext (#167574)
As in title. Without this, fpext behaves in selectionDAG as always
having no fast-math flags.
2025-11-14 20:50:59 -08:00
Matt Arsenault
e5f499f48f
DAG: Allow select ptr combine for non-0 address spaces (#167909) 2025-11-13 18:58:08 +00:00
Simon Pilgrim
a5342d5fe5
Revert "[DAG] Fold (umin (sub a b) a) -> (usubo a b); (select usubo.1 a usubo.0)" (#167854)
Reverts llvm/llvm-project#161651 due to downstream bad codegen reports
2025-11-13 10:46:38 +00:00
Chaitanya Koparkar
1f58cbe60a
[DAG] Fold (umin (sub a b) a) -> (usubo a b); (select usubo.1 a usubo.0) (#161651)
Fixes #161036.
2025-11-12 14:38:21 +00:00
guan jian
3618ed14e4
[DAGCombiner] Add sra-xor-sra pattern fold (#166777)
Add `fold (sra (xor (sra x, c1), -1), c2) -> (sra (xor x, -1), c3)`

The IR like this:
```
  %a = ashr i8 %x, 6
  %n = xor i8 %a, -1
  %s = sext i8 %n to i16
  %r = and i16 %s, %y
  ret i16 %r
```

llvm will produce:
```
	slli	a0, a0, 56
	srai	a0, a0, 56
	not	a0, a0
	srai	a0, a0, 6
	and	a0, a0, a1
	ret
```

56 and 6 can be add up

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

---------

Co-authored-by: rez5427 <785369607@qq.com>
2025-11-10 19:03:34 -08:00
Matt Arsenault
a3d00e1ae4
DAG: Fold copysign with a known signmask to a disjoint or (#167266)
If the sign bit is a computed sign mask (i.e., we know it's
either +0 or -0), turn this into a disjoint or. This pattern
appears in the pow implementations.

We also need to know the sign bit of the magnitude is 0 for
the or to be disjoint. Unfortunately the DAG's FP tracking is
weak and we did not have a way to check if the sign bit is known
0, so add something for that. Ideally we would get a complete
computeKnownFPClass implementation.

This is intended to help avoid the regression which caused
d3e7c4ce7a3d7 to be reverted.
2025-11-10 08:55:45 -08:00
Damian Heaton
70f4b596cf
Add llvm.vector.partial.reduce.fadd intrinsic (#159776)
With this intrinsic, and supporting SelectionDAG nodes, we can better
make use of instructions such as AArch64's `FDOT`.
2025-11-07 15:36:54 +00:00
Simon Pilgrim
0ade2604f2
[DAG] visitBITCAST - fold (bitcast (freeze (load x))) -> (freeze (load (bitcast*)x)) (#164618)
Tweak the existing (bitcast (load x)) -> (load (bitcast*)x) fold to handle oneuse freeze as well

Inspired by #163070 - this tries to avoid in place replacement of frozen nodes which has caused infinite loops in the past
2025-11-07 10:50:52 +00:00
Hongyu Chen
1c756932e9
[DAGCombiner] Bail out if BitWidthDiff > BitWidth when folding cltz(and) - BitWidthDiff (#166607)
Fixes https://github.com/llvm/llvm-project/issues/166596
We cannot use `APInt::isMask` if `numBits` exceeds the bitwidth of APInt
or `numBits` is zero. We avoid such a case by guaranteeing BitWidthDiff
< BitWidth.
2025-11-06 15:33:38 +08:00
Kazu Hirata
31b8ba5670
[Analysis, CodeGen] Use ArrayRef instead of const ArrayRef (NFC) (#166026)
This patch improves readability by using "ArrayRef<T>" instead of
"const ArrayRef<T>" and "const ArrayRef<T> &" in function parameter
types.
2025-11-01 23:20:19 -07:00
Fabian Ritter
8ea447b4c4
[SDAG] Set InBounds when when computing offsets into memory objects (#165425)
When a load or store accesses N bytes starting from a pointer P, and we want to
compute an offset pointer within these N bytes after P, we know that the
arithmetic to add the offset must be inbounds. This is for example relevant
when legalizing too-wide memory accesses, when lowering memcpy&Co., or when
optimizing "vector-load -> extractelement" into an offset load.

For SWDEV-516125.
2025-10-31 11:27:55 +01:00
Fabian Ritter
a85e84b854
[SDAG] Preserve InBounds in DAGCombines (#165424)
This PR preserves the InBounds flag (#162477) where possible in PTRADD-related
DAGCombines. We can't preserve them in all the cases that we could in the
analogous GISel change (#152495) because SDAG usually represents pointers as
integers, which means that pointer provenance is not preserved between PTRADD
operations (see the discussion at PR #162477 for more details). This PR marks
the places in the DAGCombiner where this is relevant explicitly.

For SWDEV-516125.
2025-10-31 10:25:39 +01:00
Princeton Ferro
68e74f8f84
[DAGCombiner] Lower dynamic insertelt chain more efficiently (#162368)
For an insertelt with a dynamic index, the default handling in
DAGTypeLegalizer and LegalizeDAG will reserve a stack slot for the
vector, lower the insertelt to a store, then load the modified vector
back into temporaries. The vector store and load may be legalized into a
sequence of smaller operations depending on the target.

Let V = the vector size and L = the length of a chain of insertelts with
dynamic indices. In the worse case, this chain will lower to O(VL)
operations, which can increase code size dramatically.

Instead, identify such chains, reserve one stack slot for the vector,
and lower all of the insertelts to stores at once. This requires only
O(V + L) operations. This change only affects the default lowering
behavior.
2025-10-29 09:46:01 -07:00
Lauren
e964acf85f
[DAG] Fold mismatched widened avg idioms to narrow form (#147946) (#163366)
[DAG] Fold mismatched widened avg idioms to narrow form (fixes half of
[llvm#147946](https://github.com/llvm/llvm-project/issues/147946))

1. `trunc(avgceilu(sext(x), sext(y))) -> avgceils(x, y)` 
2. `trunc(avgceils(zext(x), zext(y))) -> avgceilu(x, y)`

When inputs are sign-extended, unsigned and signed averaging operations
produce identical results after truncation, allowing us to use the
semantically correct narrow operation.

alive2: https://alive2.llvm.org/ce/z/ZRbfHT
2025-10-27 12:24:41 +00:00
David Green
332f786a35
[DAG][AArch64] Ensure that ResNo is correct for uses of Ptr when considering postinc. (#164810)
We might be looking at a different use, for example in the uses of a
i32,i64,ch preindex load.

Fixes #164775
2025-10-24 11:33:08 +01:00
paperchalice
15d11ebc84
[NFC] "unsafe-fp-math" post cleanup (code comments part) (#164582) 2025-10-22 11:07:23 +00:00
kper
e83eee335c
[DAG] Create SDPatternMatch method m_SelectLike to match ISD::Select and ISD::VSelect (#164069)
Fixes #150019
2025-10-22 09:49:34 +00:00
Simon Pilgrim
f8edcba62d
[DAG] visitTRUNCATE - more aggressively fold trunc(add(x,x)) -> add(trunc(x),trunc(x)) (#164227)
We're very careful not to truncate binary arithmetic ops if it will
affect legality, or cause additional truncation instructions, hence we
currently limit this to cases where one operand is constant.

But if both ops are the same (i.e. for some add/mul cases) then we
wouldn't increase the number of truncations, so can be slightly more
aggressive at folding the truncation.
2025-10-21 10:17:57 +00:00
Simon Pilgrim
a51e498ea6
[DAG] combineTruncationShuffle - ensure the *_EXTEND_VECTOR_INREG node didn't come from a smaller type (#164160)
The *_EXTEND_VECTOR_INREG source vector must be the same size as the destination

We already have a similar TODO to handle more types.

Fixes #164107
2025-10-19 14:15:33 +00:00
paperchalice
bfee9db785
[DAGCombiner] Remove NoNaNsFPMath uses (#163504)
Users should use `nnan` flag instead.
2025-10-15 21:22:13 +08:00
paperchalice
dd44e63c8e
[DAGCombiner] Use FlagInserter in visitFSQRT (#163301)
Propagate fast-math flags for TLI.getSqrtEstimate etc.
2025-10-15 09:03:15 +08:00
Paul Walker
d7fc770340
[LLVM][DAGCombiner] Improve simplifyDivRem's effectiveness after type legalisation. (#162706)
simplifyDivRem does not work as well after type legalisation because
splatted constants can have a size mismatch between the scalar to splat
and the element type of the splatted result. simplifyDivRem does not
seem to care about this mismatch so I've updated the "is one" check
for the divisor to allow truncation.
2025-10-14 11:23:53 +01:00
Sam Parker
1820102167
Wasm fmuladd relaxed (#163177)
Reland #161355, after fixing up the cross-projects-tests for the wasm
simd intrinsics.

Original commit message:
Lower v4f32 and v2f64 fmuladd calls to relaxed_madd instructions.
If we have FP16, then lower v8f16 fmuladds to FMA.

I've introduced an ISD node for fmuladd to maintain the rounding
ambiguity through legalization / combine / isel.
2025-10-13 16:50:53 +01:00
Sam Parker
30d3441cf0
Revert "[WebAssembly] Lower fmuladd to madd and nmadd" (#163171)
Reverts llvm/llvm-project#161355

Looks like I've broken some intrinsic code generation.
2025-10-13 11:53:40 +01:00
Sam Parker
a4eb7ea225
[WebAssembly] Lower fmuladd to madd and nmadd (#161355)
Lower v4f32 and v2f64 fmuladd calls to relaxed_madd instructions.
If we have FP16, then lower v8f16 fmuladds to FMA.

I've introduced an ISD node for fmuladd to maintain the rounding
ambiguity through legalization / combine / isel.
2025-10-13 10:36:08 +01:00
paperchalice
a61107472b
[SelectionDAG] Remove NoInfsFPMath uses (#162788)
Users should use fast-math flags instead.
2025-10-12 09:34:24 +08:00
AZero13
d95f8ffee4
[ARM][TargetLowering] Combine Level should not be a factor in shouldFoldConstantShiftPairToMask (NFC) (#156949)
This should be based on the type and instructions, and only thumb uses
combine level anyway.
2025-10-11 10:58:48 +09:00
Yi-Chi Lee
a9c8e94b43
[DAGCombiner] Extend FP-to-Int cast without requiring nsz (#161093)
This patch updates the FP-to-Int conversion handling:
- For signed integers: use `ftrunc` followed by clamping to the target
integer range.
- For unsigned integers: apply `fabs` + `ftrunc`, then clamp.

This removes the previous dependence on `nsz` and ensures correct
lowering for both signed and unsigned cases.

I've tested the code generation of -mtriple=amdgcn. It seems that the
assembly code is expected, but I'm not sure how to write a general
testcase for every target.

Fixes #160623.
2025-10-11 00:34:33 +09:00
Lewis Crawford
4c2b1d495a
[DAGCombiner] Improve FMin/FMax DAGCombines (#161352)
Add several improvements to DAGCombine patterns for fmin/fmax:
 * Fix incorrect results due to minimumnum not being marked as IsMin
    - e.g. nnan minimumnum(x, +inf) returned +inf instead of x
 * Fix incorrect results checking maximumnum for vecreduce patterns
 * Make maxnum/minnum return QNaN if one input is SNaN instead of X
 * Quiet SNaN inputs when propagating them e.g. maximum(x, SNaN) = QNaN
 * Update comments to mark when SNaN propagation is being ignored
2025-10-09 18:00:50 +01:00
paperchalice
4967bc17df
[DAGCombiner] Remove NoSignedZerosFPMath in visitFNEG (#162052)
Remove the `NoSignedZerosFPMath` use in `visitFNEG`. Now the only use of
`NoSignedZerosFPMath` is in `foldFPToIntToFP`, but adding fast-math
flags support for `uitofp` may introduce breaking changes.
2025-10-08 17:01:47 +08:00