<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/llvm/test/CodeGen/AMDGPU/mul.ll, branch users/nico/python-2</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[PHIElimination] Revert #131837 #146320 #146337 (#146850)</title>
<updated>2025-07-03T11:48:08+00:00</updated>
<author>
<name>Guy David</name>
<email>49722543+guy-david@users.noreply.github.com</email>
</author>
<published>2025-07-03T11:48:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=76274eb2b3439aac6991c6b505248e00627e5693'/>
<id>76274eb2b3439aac6991c6b505248e00627e5693</id>
<content type='text'>
Reverting because mis-compiles:
- https://github.com/llvm/llvm-project/pull/131837
- https://github.com/llvm/llvm-project/pull/146320
- https://github.com/llvm/llvm-project/pull/146337</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Reverting because mis-compiles:
- https://github.com/llvm/llvm-project/pull/131837
- https://github.com/llvm/llvm-project/pull/146320
- https://github.com/llvm/llvm-project/pull/146337</pre>
</div>
</content>
</entry>
<entry>
<title>[PHIElimination] Reuse existing COPY in predecessor basic block (#131837)</title>
<updated>2025-06-29T18:28:42+00:00</updated>
<author>
<name>Guy David</name>
<email>49722543+guy-david@users.noreply.github.com</email>
</author>
<published>2025-06-29T18:28:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=f5c62ee0fa0466382cb11f6fad80d323b0fca057'/>
<id>f5c62ee0fa0466382cb11f6fad80d323b0fca057</id>
<content type='text'>
The insertion point of COPY isn't always optimal and could eventually
lead to a worse block layout, see the regression test in the first
commit.

This change affects many architectures but the amount of total
instructions in the test cases seems too be slightly lower.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The insertion point of COPY isn't always optimal and could eventually
lead to a worse block layout, see the regression test in the first
commit.

This change affects many architectures but the amount of total
instructions in the test cases seems too be slightly lower.</pre>
</div>
</content>
</entry>
<entry>
<title>MachineScheduler: Improve instruction clustering (#137784)</title>
<updated>2025-06-05T07:28:04+00:00</updated>
<author>
<name>Ruiling, Song</name>
<email>ruiling.song@amd.com</email>
</author>
<published>2025-06-05T07:28:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=0487db1f130913d4fad18483e305b843636ec4ce'/>
<id>0487db1f130913d4fad18483e305b843636ec4ce</id>
<content type='text'>
The existing way of managing clustered nodes was done through adding
weak edges between the neighbouring cluster nodes, which is a sort of
ordered queue. And this will be later recorded as `NextClusterPred` or
`NextClusterSucc` in `ScheduleDAGMI`.

But actually the instruction may be picked not in the exact order of the
queue. For example, we have a queue of cluster nodes A B C. But during
scheduling, node B might be picked first, then it will be very likely
that we only cluster B and C for Top-Down scheduling (leaving A alone).

Another issue is:
```
   if (!ReorderWhileClustering &amp;&amp; SUa-&gt;NodeNum &gt; SUb-&gt;NodeNum)
      std::swap(SUa, SUb);
   if (!DAG-&gt;addEdge(SUb, SDep(SUa, SDep::Cluster)))
```
may break the cluster queue.

For example, we want to cluster nodes (order as in `MemOpRecords`): 1 3
2. 1(SUa) will be pred of 3(SUb) normally. But when it comes to (3, 2),
As 3(SUa) &gt; 2(SUb), we would reorder the two nodes, which makes 2 be
pred of 3. This makes both 1 and 2 become preds of 3, but there is no
edge between 1 and 2. Thus we get a broken cluster chain.

To fix both issues, we introduce an unordered set in the change. This
could help improve clustering in some hard case.

One key reason the change causes so many test check changes is: As the
cluster candidates are not ordered now, the candidates might be picked
in different order from before.

The most affected targets are: AMDGPU, AArch64, RISCV.

For RISCV, it seems to me most are just minor instruction reorder, don't
see obvious regression.

For AArch64, there were some combining of ldr into ldp being affected.
With two cases being regressed and two being improved. This has more
deeper reason that machine scheduler cannot cluster them well both
before and after the change, and the load combine algorithm later is
also not smart enough.

For AMDGPU, some cases have more v_dual instructions used while some are
regressed. It seems less critical. Seems like test `v_vselect_v32bf16`
gets more buffer_load being claused.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The existing way of managing clustered nodes was done through adding
weak edges between the neighbouring cluster nodes, which is a sort of
ordered queue. And this will be later recorded as `NextClusterPred` or
`NextClusterSucc` in `ScheduleDAGMI`.

But actually the instruction may be picked not in the exact order of the
queue. For example, we have a queue of cluster nodes A B C. But during
scheduling, node B might be picked first, then it will be very likely
that we only cluster B and C for Top-Down scheduling (leaving A alone).

Another issue is:
```
   if (!ReorderWhileClustering &amp;&amp; SUa-&gt;NodeNum &gt; SUb-&gt;NodeNum)
      std::swap(SUa, SUb);
   if (!DAG-&gt;addEdge(SUb, SDep(SUa, SDep::Cluster)))
```
may break the cluster queue.

For example, we want to cluster nodes (order as in `MemOpRecords`): 1 3
2. 1(SUa) will be pred of 3(SUb) normally. But when it comes to (3, 2),
As 3(SUa) &gt; 2(SUb), we would reorder the two nodes, which makes 2 be
pred of 3. This makes both 1 and 2 become preds of 3, but there is no
edge between 1 and 2. Thus we get a broken cluster chain.

To fix both issues, we introduce an unordered set in the change. This
could help improve clustering in some hard case.

One key reason the change causes so many test check changes is: As the
cluster candidates are not ordered now, the candidates might be picked
in different order from before.

The most affected targets are: AMDGPU, AArch64, RISCV.

For RISCV, it seems to me most are just minor instruction reorder, don't
see obvious regression.

For AArch64, there were some combining of ldr into ldp being affected.
With two cases being regressed and two being improved. This has more
deeper reason that machine scheduler cannot cluster them well both
before and after the change, and the load combine algorithm later is
also not smart enough.

For AMDGPU, some cases have more v_dual instructions used while some are
regressed. It seems less critical. Seems like test `v_vselect_v32bf16`
gets more buffer_load being claused.</pre>
</div>
</content>
</entry>
<entry>
<title>[AMDGPU] Do not fold COPY with implicit operands (#136003)</title>
<updated>2025-04-22T11:33:06+00:00</updated>
<author>
<name>Mariusz Sikora</name>
<email>mariusz.sikora@amd.com</email>
</author>
<published>2025-04-22T11:33:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=1a48e1df4541ccccdaf14a6ea379be004e319a09'/>
<id>1a48e1df4541ccccdaf14a6ea379be004e319a09</id>
<content type='text'>
Folding may remove COPY from inside of the divergent loop.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Folding may remove COPY from inside of the divergent loop.</pre>
</div>
</content>
</entry>
<entry>
<title>[AMDGPU] Set hasSideEffects=0 for SALU psuedos (#134487)</title>
<updated>2025-04-11T15:35:01+00:00</updated>
<author>
<name>amansharma612</name>
<email>amansharma6122002@gmail.com</email>
</author>
<published>2025-04-11T15:35:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=976c37ec950a93ed60068389ad05454f76da1e55'/>
<id>976c37ec950a93ed60068389ad05454f76da1e55</id>
<content type='text'>
Fixes #128685

---------

Co-authored-by: Aman Sharma &lt;210100011@iitb.ac.in&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Fixes #128685

---------

Co-authored-by: Aman Sharma &lt;210100011@iitb.ac.in&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[AMDGPU] Unused sdst writing to null (#133229)</title>
<updated>2025-03-28T17:12:34+00:00</updated>
<author>
<name>Ana Mihajlovic</name>
<email>Ana.Mihajlovic@amd.com</email>
</author>
<published>2025-03-28T17:12:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=8c7550132f410766598ba88de6b7e7a2a4607f67'/>
<id>8c7550132f410766598ba88de6b7e7a2a4607f67</id>
<content type='text'>
Unused sdst writing to null to avoid a false VALU-&gt;SALU dependency
stall. This requires using the VOP3 encoding.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Unused sdst writing to null to avoid a false VALU-&gt;SALU dependency
stall. This requires using the VOP3 encoding.</pre>
</div>
</content>
</entry>
<entry>
<title>PeepholeOpt: Allow introducing subregister uses on reg_sequence (#127052)</title>
<updated>2025-02-22T02:16:14+00:00</updated>
<author>
<name>Matt Arsenault</name>
<email>Matthew.Arsenault@amd.com</email>
</author>
<published>2025-02-22T02:16:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=1bb43068f187141f20066a83675531161ed45051'/>
<id>1bb43068f187141f20066a83675531161ed45051</id>
<content type='text'>
This reverts d246cc618adc52fdbd69d44a2a375c8af97b6106. We now handle
composing subregister extracts through reg_sequence.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts d246cc618adc52fdbd69d44a2a375c8af97b6106. We now handle
composing subregister extracts through reg_sequence.</pre>
</div>
</content>
</entry>
<entry>
<title>[DAG] getNode - convert scalar i1 arithmetic calls to bitwise instructions (#125486)</title>
<updated>2025-02-03T16:36:01+00:00</updated>
<author>
<name>Simon Pilgrim</name>
<email>llvm-dev@redking.me.uk</email>
</author>
<published>2025-02-03T16:36:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b7c8271601461e02fb567d6cd175fe20e123d78a'/>
<id>b7c8271601461e02fb567d6cd175fe20e123d78a</id>
<content type='text'>
We already do this for vector vXi1 types - this patch removes the vector constraint to handle it for all bool types.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We already do this for vector vXi1 types - this patch removes the vector constraint to handle it for all bool types.</pre>
</div>
</content>
</entry>
<entry>
<title>PeepholeOpt: Do not add subregister indexes to reg_sequence operands (#124111)</title>
<updated>2025-01-30T13:42:02+00:00</updated>
<author>
<name>Matt Arsenault</name>
<email>Matthew.Arsenault@amd.com</email>
</author>
<published>2025-01-30T13:42:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=d246cc618adc52fdbd69d44a2a375c8af97b6106'/>
<id>d246cc618adc52fdbd69d44a2a375c8af97b6106</id>
<content type='text'>
Given the rest of the pass just gives up when it needs to compose
subregisters, folding a subregister extract directly into a reg_sequence
is counterproductive. Later fold attempts in the function will give up
on the subregister operand, preventing looking up through the reg_sequence.

It may still be profitable to do these folds if we start handling
the composes. There are some test regressions, but this mostly
looks better.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Given the rest of the pass just gives up when it needs to compose
subregisters, folding a subregister extract directly into a reg_sequence
is counterproductive. Later fold attempts in the function will give up
on the subregister operand, preventing looking up through the reg_sequence.

It may still be profitable to do these folds if we start handling
the composes. There are some test regressions, but this mostly
looks better.</pre>
</div>
</content>
</entry>
<entry>
<title>[AMDGPU] Occupancy w.r.t. workgroup size range is also a range (#123748)</title>
<updated>2025-01-23T15:07:57+00:00</updated>
<author>
<name>Lucas Ramirez</name>
<email>11032120+lucas-rami@users.noreply.github.com</email>
</author>
<published>2025-01-23T15:07:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6206f5444fc0732e6495703c75a67f1f90f5b418'/>
<id>6206f5444fc0732e6495703c75a67f1f90f5b418</id>
<content type='text'>
Occupancy (i.e., the number of waves per EU) depends, in addition to
register usage, on per-workgroup LDS usage as well as on the range of
possible workgroup sizes. Mirroring the latter, occupancy should
therefore be expressed as a range since different group sizes generally
yield different achievable occupancies.

`getOccupancyWithLocalMemSize` currently returns a scalar occupancy
based on the maximum workgroup size and LDS usage. With respect to the
workgroup size range, this scalar can be the minimum, the maximum, or
neither of the two of the range of achievable occupancies. This commit
fixes the function by making it compute and return the range of
achievable occupancies w.r.t. workgroup size and LDS usage; it also
renames it to `getOccupancyWithWorkGroupSizes` since it is the range of
workgroup sizes that produces the range of achievable occupancies.

Computing the achievable occupancy range is surprisingly involved.
Minimum/maximum workgroup sizes do not necessarily yield maximum/minimum
occupancies i.e., sometimes workgroup sizes inside the range yield the
occupancy bounds. The implementation finds these sizes in constant time;
heavy documentation explains the rationale behind the sometimes
relatively obscure calculations.

As a justifying example, consider a target with 10 waves / EU, 4 EUs/CU,
64-wide waves. Also consider a function with no LDS usage and a flat
workgroup size range of [513,1024].

- A group of 513 items requires 9 waves per group. Only 4 groups made up
of 9 waves each can fit fully on a CU at any given time, for a total of
36 waves on the CU, or 9 per EU. However, filling as much as possible
the remaining 40-36=4 wave slots without decreasing the number of groups
reveals that a larger group of 640 items yields 40 waves on the CU, or
10 per EU.
- Similarly, a group of 1024 items requires 16 waves per group. Only 2
groups made up of 16 waves each can fit fully on a CU ay any given time,
for a total of 32 waves on the CU, or 8 per EU. However, removing as
many waves as possible from the groups without being able to fit another
equal-sized group on the CU reveals that a smaller group of 896 items
yields 28 waves on the CU, or 7 per EU.

Therefore the achievable occupancy range for this function is not [8,9]
as the group size bounds directly yield, but [7,10].

Naturally this change causes a lot of test churn as instruction
scheduling is driven by achievable occupancy estimates. In most unit
tests the flat workgroup size range is the default [1,1024] which,
ignoring potential LDS limitations, would previously produce a scalar
occupancy of 8 (derived from 1024) on a lot of targets, whereas we now
consider the maximum occupancy to be 10 in such cases. Most tests are
updated automatically and checked manually for sanity. I also manually
changed some non-automatically generated assertions when necessary.

Fixes #118220.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Occupancy (i.e., the number of waves per EU) depends, in addition to
register usage, on per-workgroup LDS usage as well as on the range of
possible workgroup sizes. Mirroring the latter, occupancy should
therefore be expressed as a range since different group sizes generally
yield different achievable occupancies.

`getOccupancyWithLocalMemSize` currently returns a scalar occupancy
based on the maximum workgroup size and LDS usage. With respect to the
workgroup size range, this scalar can be the minimum, the maximum, or
neither of the two of the range of achievable occupancies. This commit
fixes the function by making it compute and return the range of
achievable occupancies w.r.t. workgroup size and LDS usage; it also
renames it to `getOccupancyWithWorkGroupSizes` since it is the range of
workgroup sizes that produces the range of achievable occupancies.

Computing the achievable occupancy range is surprisingly involved.
Minimum/maximum workgroup sizes do not necessarily yield maximum/minimum
occupancies i.e., sometimes workgroup sizes inside the range yield the
occupancy bounds. The implementation finds these sizes in constant time;
heavy documentation explains the rationale behind the sometimes
relatively obscure calculations.

As a justifying example, consider a target with 10 waves / EU, 4 EUs/CU,
64-wide waves. Also consider a function with no LDS usage and a flat
workgroup size range of [513,1024].

- A group of 513 items requires 9 waves per group. Only 4 groups made up
of 9 waves each can fit fully on a CU at any given time, for a total of
36 waves on the CU, or 9 per EU. However, filling as much as possible
the remaining 40-36=4 wave slots without decreasing the number of groups
reveals that a larger group of 640 items yields 40 waves on the CU, or
10 per EU.
- Similarly, a group of 1024 items requires 16 waves per group. Only 2
groups made up of 16 waves each can fit fully on a CU ay any given time,
for a total of 32 waves on the CU, or 8 per EU. However, removing as
many waves as possible from the groups without being able to fit another
equal-sized group on the CU reveals that a smaller group of 896 items
yields 28 waves on the CU, or 7 per EU.

Therefore the achievable occupancy range for this function is not [8,9]
as the group size bounds directly yield, but [7,10].

Naturally this change causes a lot of test churn as instruction
scheduling is driven by achievable occupancy estimates. In most unit
tests the flat workgroup size range is the default [1,1024] which,
ignoring potential LDS limitations, would previously produce a scalar
occupancy of 8 (derived from 1024) on a lot of targets, whereas we now
consider the maximum occupancy to be 10 in such cases. Most tests are
updated automatically and checked manually for sanity. I also manually
changed some non-automatically generated assertions when necessary.

Fixes #118220.</pre>
</div>
</content>
</entry>
</feed>
