| Age | Commit message (Collapse) | Author |
|
This patch allows urem by a constant to be expanded more efficiently to
avoid the need for expensive udiv instructions. This is part of the
resolution to issue #118090
|
|
In the pre-legalizer combiner, there exists a bug with UseVectorTruncate
match-apply optimization. When the destinations' types do not match the
vector element type of the G_UNMERGE_VALUES instruction, the resulting
collapsed truncate does not preserve original functional behavior. This
commit introduces a simple type check to ensure that the destination
types match the vector element type.
|
|
Fixes issue: https://github.com/llvm/llvm-project/issues/139752
When G_SHUFFLE_VECTOR has only 1 element then it is possible the vector
is decayed into a scalar.
|
|
As shown in https://alive2.llvm.org/ce/z/PVwcTL we need to clear the nsw
flags too when converting a sub to a add if the constant is INT_MIN.
Fixes #137254
|
|
|
|
This patch dismantles G_SHUFFLE_VECTOR before lowering. The original
lowering would emit extract vector element ops. We found that by using
unmerged values the build vector op combine could find ways to fold.
Only enabled on AMDGPU.
This resolves #123631
|
|
CombinerHelper::matchCombineExtractedVectorLoad
|
|
- rename `GISelKnownBits` to `GISelValueTracking` to analyze more than
just `KnownBits` in the future
|
|
|
|
We need to check `G_CTLZ` because the combine uses `G_CTLZ` to get log
base 2,
and it is not always legal for on a target.
Fixes SWDEV-512440.
|
|
|
|
This resolves #123212
|
|
(#120998)
This is the GISel version of #120666. Also supports both unsigned and
signed version of min & max.
|
|
The SelectionDAG Isel supports the both version of combines mentioned
below :
```
select Cond, Pow2, 0 --> (zext Cond) << log2(Pow2)
select Cond, 0, Pow2 --> (zext !Cond) << log2(Pow2)
```
The GlobalIsel for now only supports the first one defined in it's
generic combinerHelper.cpp. This patch adds the missing second one.
|
|
There are a number of backends (specifically AArch64, AMDGPU, Mips, and
RISCV) which contain a “TODO: make CombinerHelper methods const”
comment. This PR does just that and makes all of the CombinerHelper
methods const, removes the TODO comments and makes the associated
instances const. This change makes some sense because the CombinerHelper
class simply modifies the state of _other_ objects to which it holds
pointers or references.
Note that AMDGPU contains an identical comment for an instance of
AMDGPUCombinerHelper (a subclass of CombinerHelper). I deliberately
haven’t modified the methods of that class in order to limit the scope
of the change. I’m happy to do so either now or as a follow-up.
|
|
|
|
matchHoistLogicOpWithSameOpcodeHands
In case both LeftHandInst and RightHandInst are IMPLICIT_DEF with no input
operands, this patch protects against the post-legalizer-combiner
matchHoistLogicOpWithSameOpcodeHands with no operands. The
prelegalizercombiner-hoist-same-hands.mir test was cleaned up a little in the
process, and has a post-legalizer run line added so that the implicit_def do
not get folded awwy.
|
|
`std::move` to avoid copy (#118068)
|
|
We import the llvm.ssub.with.overflow.* Intrinsics, but the Legalizer
also builds them while legalizing other opcodes, see narrowScalarAddSub.
|
|
not reference a (#115377)
|
|
Add `ICmpInst::compare()` overload accepting `KnownBits`, similar to the
existing one accepting `APInt`. This is not directly part of KnownBits
(or APInt) for layering reasons.
|
|
CombineShuffleConcat.
In case the first element is undef, we need to look through to find a valid
type for the inputs.
|
|
-C) (#114309)"
The increase in fallbacks that was previously reported were not caused
by this change.
Original description:
This matches InstCombine and DAGCombine.
RISC-V only has an ADDI instruction so without this we need additional
patterns to do the conversion.
Some of the AMDGPU tests look like possible regressions. Maybe some
patterns from isel aren't imported.
|
|
|
|
-C) (#114309)"
This reverts commit 999dfb2067eb75609b735944af876279025ac171.
I received a report that his may have increased fallbacks on AArch64.
|
|
This fixes a bug that started triggering after #111730, where we could
remove a load with multiple uses. It looks like the match should be
checking the other register in a one-use check.
%SrcReg = load..
%DstReg = sign_extend_inreg %SrcReg
|
|
This matches InstCombine and DAGCombine.
RISC-V only has an ADDI instruction so without this we need additional
patterns to do the conversion.
Some of the AMDGPU tests look like possible regressions. Maybe some
patterns from isel aren't imported.
|
|
The sext_inreg (load) combine was not deleting the old load instruction,
and it would never be deleted if volatile or atomic.
|
|
G_UNMERGE_VALUES (G_ANYEXT (G_BUILD_VECTOR))
ag G_UNMERGE_VALUES llvm/test/CodeGen/AArch64/GlobalISel | grep ANYEXT
[ANYEXT] is build vector or shuffle vector
Prior art:
https://reviews.llvm.org/D87117
https://reviews.llvm.org/D87166
https://reviews.llvm.org/D87174
https://reviews.llvm.org/D87427
; CHECK-NEXT: [[BUILD_VECTOR2:%[0-9]+]]:_(<8 x s8>) = G_BUILD_VECTOR
[[C2]](s8), [[C2]](s8), [[C2]](s8), [[C2]](s8), [[DEF1]](s8),
[[DEF1]](s8), [[DEF1]](s8), [[DEF1]](s8)
; CHECK-NEXT: [[ANYEXT1:%[0-9]+]]:_(<8 x s16>) = G_ANYEXT
[[BUILD_VECTOR2]](<8 x s8>)
; CHECK-NEXT: [[UV10:%[0-9]+]]:_(<4 x s16>), [[UV11:%[0-9]+]]:_(<4 x
s16>) = G_UNMERGE_VALUES
[[ANYEXT1]](<8 x s16>)
Test:
llvm/test/CodeGen/AArch64/GlobalISel/combine-unmerge.mir
|
|
Combine is needed to clear redundant ANDs with 1 that will be
created by reg-bank-select to clean-up high bits in register.
Fix replaceRegWith from CombinerHelper:
If copy had to be inserted, first create copy then delete MI.
If MI is deleted first insert point is not valid.
|
|
(#111230)
mul and shl have different meanings for the nsw flag. We need to drop it
when converting a multiply by the minimum negative value.
|
|
Tries to combine scalarised truncates into vector truncate operations
EXAMPLE:
`%a(i32), %b(i32) = G_UNMERGE %src(<2 x i32>)`
`%T_a(i16) = G_TRUNC %a(i32)`
`%T_b(i16) = G_TRUNC %b(i32)`
`%Imp(i16) = G_IMPLICIT_DEF(i16)`
`%dst(v8i16) = G_MERGE_VALUES %T_a(i16), %T_b(i16), %Imp(i16),
%Imp(i16)`
===>
`%Imp(<2 x i32>) = G_IMPLICIT_DEF(<2 x i32>)`
`%Mid(<4 x s16>) = G_CONCAT_VECTORS %src(<2 x i32>), %Imp(<2 x i32>)`
`%dst(<4 x s16>) = G_TRUNC %Mid(<4 x s16>)`
|
|
These combines call getNumElements() which isn't valid for scalable
vectors.
|
|
Credits:
https://reviews.llvm.org/D86516
combine-ext.mir
Notable semantic changes:
InstCombine does not mix zero and sign extend,
see CastInst::isEliminableCastPair.
New version has legality checks.
Folds sext/zext of anyext -> sext/zext
Support for nneg
Future work:
nneg zext of sext -> sext
sext of nneg zext -> sext
|
|
|
|
|
|
Credits:
https://github.com/llvm/llvm-project/pull/90964
https://reviews.llvm.org/D87050
combine-trunc.mir
Functional changes intended.
|
|
Preparation for more cast combines
|
|
Group the code for handling Exact udiv together above the code for
non-Exact. Move the computeKnownBits call to after the Exact udiv
handling.
|
|
Have simpler lowering for exact udivs in both SelectionDAG and
GlobalISel.
The algorithm is the same between unsigned exact divs and signed divs
save for arithmetic vs logical shift for even divisors, according to
Hacker's Delight, 2nd Edition, page 242.
|
|
The verifier does not accept single-element G_CONCAT_VECTORS, so if there is a
single Op generate a COPY instead.
|
|
Credits: https://reviews.llvm.org/D99283
|
|
|
|
(#95217)
SelectionDAG already converts FPOWI into a series of optimized multiplications,
this patch introduces the same optimization into GlobalISel.
|
|
|
|
As far as I can tell, this pull request was not approved, and
did not go through an RFC on discourse.
This reverts commit 89881480030f48f83af668175b70a9798edca2fb.
This reverts commit 225d8fc8eb24fb797154c1ef6dcbe5ba033142da.
|
|
Currently, on different platform, the behaivor of llvm.minnum is
different if one operand is sNaN:
When we compare sNaN vs NUM:
ARM/AArch64/PowerPC: follow the IEEE754-2008's minNUM: return qNaN.
RISC-V/Hexagon follow the IEEE754-2019's minimumNumber: return NUM. X86:
Returns NUM but not same with IEEE754-2019's minimumNumber as
+0.0 is not always greater than -0.0.
MIPS/LoongArch/Generic: return NUM.
LIBCALL: returns qNaN.
So, let's introduce llvm.minmumnum/llvm.maximumnum, which always follow
IEEE754-2019's minimumNumber/maximumNumber.
Half-fix: #93033
|
|
Multiple static instances of this utility function have been found in
different GlobalISel files.
Unifying them by adding an instance in utils.cpp.
|
|
(#89023)
|
|
This patch converts `zext nneg` to `sext` on RISCV to use free sext.
---------
Co-authored-by: Thorsten Schütt <schuett@gmail.com>
|