<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/llvm/lib/Transforms/Utils/SimplifyCFG.cpp, branch main</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>[SimplifyCFG] Simplify uncond br with icmp &amp; select (#165580)</title>
<updated>2025-11-08T12:52:19+00:00</updated>
<author>
<name>Kunqiu Chen</name>
<email>camsyn@foxmail.com</email>
</author>
<published>2025-11-08T12:52:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=a0e222f7c7bc7b6de43391fbbdada8d511004b9c'/>
<id>a0e222f7c7bc7b6de43391fbbdada8d511004b9c</id>
<content type='text'>
Previously, SimplifyCFG only simplified unconditional branches when they
met a pattern (`swicth` -&gt; `icmp` -&gt; `br` -&gt; `phi`) as follows:
```LLVM
   switch i8 %A, label %DEFAULT [ i8 1, label %end    i8 2, label %end ]
DEFAULT:
   %tmp = icmp eq i8 %A, 92
   br label %end
end:
   ... = phi i1 [ true, %entry ], [ %tmp, %DEFAULT ], [ true, %entry ]
```

This PR supports a new and more generic pattern (`switch` -&gt; `icmp` -&gt;
`select` -&gt; `br` -&gt; `phi` ) to simplify unconditional branches as
follows:
```LLVM
; BEFORE
case1:
  switch i32 %x, label %DEFAULT [ 
    i32 0, label %end    
    i32 1, label %case2 
  ]
case2:
  br label %end
DEFAULT:
  %tmp = icmp eq i32 %x, 2
  %val = select i1 %tmp, i32 V3, i32 V4
  br label %end
end:
  ... = phi i32 [ V1, %case1 ], [ V2, %case2 ], [ %val, %DEFAULT ]
```

We prefer to split the edge to 'end' so that there are TWO entries of
V3/V4 to the PHI, merging the icmp &amp; select into the switch, as follows:
```LLVM
; AFTER
case1:
  switch i32 %x, label %DEFAULT [
    i32 0, label %end
    i32 1, label %case2
    i32 2, label %case3
  ]
case2:
  br label %end
case3:
  br label %end
DEFAULT:
  br label %end
end:
  ... = phi i32 [ V1, %case1 ], [ V2, %case2 ], [ V3, %case3 ], [ V4, %DEFAULT]
```

Alive2 Proof: https://alive2.llvm.org/ce/z/jYHM4f
Promising Optimization Impact:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3006</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, SimplifyCFG only simplified unconditional branches when they
met a pattern (`swicth` -&gt; `icmp` -&gt; `br` -&gt; `phi`) as follows:
```LLVM
   switch i8 %A, label %DEFAULT [ i8 1, label %end    i8 2, label %end ]
DEFAULT:
   %tmp = icmp eq i8 %A, 92
   br label %end
end:
   ... = phi i1 [ true, %entry ], [ %tmp, %DEFAULT ], [ true, %entry ]
```

This PR supports a new and more generic pattern (`switch` -&gt; `icmp` -&gt;
`select` -&gt; `br` -&gt; `phi` ) to simplify unconditional branches as
follows:
```LLVM
; BEFORE
case1:
  switch i32 %x, label %DEFAULT [ 
    i32 0, label %end    
    i32 1, label %case2 
  ]
case2:
  br label %end
DEFAULT:
  %tmp = icmp eq i32 %x, 2
  %val = select i1 %tmp, i32 V3, i32 V4
  br label %end
end:
  ... = phi i32 [ V1, %case1 ], [ V2, %case2 ], [ %val, %DEFAULT ]
```

We prefer to split the edge to 'end' so that there are TWO entries of
V3/V4 to the PHI, merging the icmp &amp; select into the switch, as follows:
```LLVM
; AFTER
case1:
  switch i32 %x, label %DEFAULT [
    i32 0, label %end
    i32 1, label %case2
    i32 2, label %case3
  ]
case2:
  br label %end
case3:
  br label %end
DEFAULT:
  br label %end
end:
  ... = phi i32 [ V1, %case1 ], [ V2, %case2 ], [ V3, %case3 ], [ V4, %DEFAULT]
```

Alive2 Proof: https://alive2.llvm.org/ce/z/jYHM4f
Promising Optimization Impact:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3006</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Fix weight calculation for `simplifySwitchOfPowersOfTwo` (#165956)</title>
<updated>2025-11-05T20:02:33+00:00</updated>
<author>
<name>Mircea Trofin</name>
<email>mtrofin@google.com</email>
</author>
<published>2025-11-05T20:02:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=f76c132230326a296c4fb8f7cb6c0fb6b943fadb'/>
<id>f76c132230326a296c4fb8f7cb6c0fb6b943fadb</id>
<content type='text'>
Continued from #165804

This maintains the BFI of the default branch. Originally `10/63`​, post-pass, it ends up being `5/63 + 58/63 * 5/58`​(first term is from `PROF`​, second is the probability of going to the switch lookup times the probability, there, of taking the default branch)

Issue #147390</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Continued from #165804

This maintains the BFI of the default branch. Originally `10/63`​, post-pass, it ends up being `5/63 + 58/63 * 5/58`​(first term is from `PROF`​, second is the probability of going to the switch lookup times the probability, there, of taking the default branch)

Issue #147390</pre>
</div>
</content>
</entry>
<entry>
<title>[ProfCheck][NFC] Make Function argument from branch weight setter optional (#166032)</title>
<updated>2025-11-05T15:40:37+00:00</updated>
<author>
<name>Mircea Trofin</name>
<email>mtrofin@google.com</email>
</author>
<published>2025-11-05T15:40:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=52cb6e9d49f836b624bd0536734afd7aa4194ca0'/>
<id>52cb6e9d49f836b624bd0536734afd7aa4194ca0</id>
<content type='text'>
This picks up from #166028, making the `Function` argument optional:
most cases don't need to provide it, but in e.g. InstCombine's case,
where the instruction (select, branch) is not attached to a function
yet, the function needs to be passed explicitly.

Co-authored-by: Florian Hahn &lt;flo@fhahn.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This picks up from #166028, making the `Function` argument optional:
most cases don't need to provide it, but in e.g. InstCombine's case,
where the instruction (select, branch) is not attached to a function
yet, the function needs to be passed explicitly.

Co-authored-by: Florian Hahn &lt;flo@fhahn.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Fix value enumeration of a full range (#166379)</title>
<updated>2025-11-04T17:43:05+00:00</updated>
<author>
<name>Yingwei Zheng</name>
<email>dtcxzyw2333@gmail.com</email>
</author>
<published>2025-11-04T17:43:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=4ce58833d3653f0b15d5458b8430ec8cf25fdc16'/>
<id>4ce58833d3653f0b15d5458b8430ec8cf25fdc16</id>
<content type='text'>
ConstantRange uses `[-1, -1)` as the canonical form of a full set.
Therefore, the `for (APInt I = Lower; I != Upper; ++I)` idiom doesn't
work for full ranges. This patch fixes the value enumeration in
`ConstantComparesGatherer` to prevent missing values for full sets.

Closes https://github.com/llvm/llvm-project/issues/166369.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ConstantRange uses `[-1, -1)` as the canonical form of a full set.
Therefore, the `for (APInt I = Lower; I != Upper; ++I)` idiom doesn't
work for full ranges. This patch fixes the value enumeration in
`ConstantComparesGatherer` to prevent missing values for full sets.

Closes https://github.com/llvm/llvm-project/issues/166369.</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Eliminate dead edges of switches according to the domain of conditions (#165748)</title>
<updated>2025-11-04T12:55:33+00:00</updated>
<author>
<name>Yingwei Zheng</name>
<email>dtcxzyw2333@gmail.com</email>
</author>
<published>2025-11-04T12:55:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=8a84b285f67cb778493e225dc9699d902921e7b0'/>
<id>8a84b285f67cb778493e225dc9699d902921e7b0</id>
<content type='text'>
In simplifycfg/cvp/sccp, we eliminate dead edges of switches according
to the knownbits/range info of conditions. However, these approximations
may not meet the real-world needs when the domain of condition values is
sparse. For example, if the condition can only be either -3 or 3, we
cannot prove that the condition never evaluates to 1 (knownbits:
???????1, range: [-3, 4)).
This patch adds a helper function `collectPossibleValues` to enumerate
all the possible values of V. To fix the motivating issue,
`eliminateDeadSwitchCases` will use the result to remove dead edges.

Note: In
https://discourse.llvm.org/t/missed-optimization-due-to-overflow-check/88700
I proposed a new value lattice kind to represent such values. But I find
it hard to apply because the transition becomes much complicated.

Compile-time impact looks neutral:
https://llvm-compile-time-tracker.com/compare.php?from=32d6b2139a6c8f79e074e8c6cfe0cc9e79c4c0c8&amp;to=e47c26e3f1bf9eb062684dda4fafce58438e994b&amp;stat=instructions:u
This patch removes many dead error-handling codes:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3012
Closes https://github.com/llvm/llvm-project/issues/165179.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In simplifycfg/cvp/sccp, we eliminate dead edges of switches according
to the knownbits/range info of conditions. However, these approximations
may not meet the real-world needs when the domain of condition values is
sparse. For example, if the condition can only be either -3 or 3, we
cannot prove that the condition never evaluates to 1 (knownbits:
???????1, range: [-3, 4)).
This patch adds a helper function `collectPossibleValues` to enumerate
all the possible values of V. To fix the motivating issue,
`eliminateDeadSwitchCases` will use the result to remove dead edges.

Note: In
https://discourse.llvm.org/t/missed-optimization-due-to-overflow-check/88700
I proposed a new value lattice kind to represent such values. But I find
it hard to apply because the transition becomes much complicated.

Compile-time impact looks neutral:
https://llvm-compile-time-tracker.com/compare.php?from=32d6b2139a6c8f79e074e8c6cfe0cc9e79c4c0c8&amp;to=e47c26e3f1bf9eb062684dda4fafce58438e994b&amp;stat=instructions:u
This patch removes many dead error-handling codes:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/3012
Closes https://github.com/llvm/llvm-project/issues/165179.</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG]: Switch on umin replaces default (#164097)</title>
<updated>2025-11-04T10:35:40+00:00</updated>
<author>
<name>kper</name>
<email>kevin.per@protonmail.com</email>
</author>
<published>2025-11-04T10:35:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=5b2f9b53bdb348393bba221c5f69bfac179092c8'/>
<id>5b2f9b53bdb348393bba221c5f69bfac179092c8</id>
<content type='text'>
A switch on `umin` can eliminate the default case by making the `umin`'s
constant the default case.

Proof: https://alive2.llvm.org/ce/z/_N6nfs
Fixes: https://github.com/llvm/llvm-project/issues/162111</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A switch on `umin` can eliminate the default case by making the `umin`'s
constant the default case.

Proof: https://alive2.llvm.org/ce/z/_N6nfs
Fixes: https://github.com/llvm/llvm-project/issues/162111</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Don't propagate weights to unconditional branches in `turnSwitchRangeIntoICmp` (#165931)</title>
<updated>2025-10-31T23:10:59+00:00</updated>
<author>
<name>Mircea Trofin</name>
<email>mtrofin@google.com</email>
</author>
<published>2025-10-31T23:10:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6adef40e756eb427508ae245bfa0fd846573782e'/>
<id>6adef40e756eb427508ae245bfa0fd846573782e</id>
<content type='text'>
PR #161000 introduced a bug whereby the IR would become invalid by having an unconditional branch have `!prof`​attached to it. This only became evident in PR #165744, because the IR of `test/Transforms/SimplifyCFG/pr165301.ll`​was simple enough to both (1) introduce the unconditional branch, and (2) survive in that fashion until the end of the pass (simplifycfg) and thus trip the verifier.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
PR #161000 introduced a bug whereby the IR would become invalid by having an unconditional branch have `!prof`​attached to it. This only became evident in PR #165744, because the IR of `test/Transforms/SimplifyCFG/pr165301.ll`​was simple enough to both (1) introduce the unconditional branch, and (2) survive in that fashion until the end of the pass (simplifycfg) and thus trip the verifier.</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Propagate profile in `simplifySwitchOfPowersOfTwo` (#165804)</title>
<updated>2025-10-31T20:05:18+00:00</updated>
<author>
<name>Mircea Trofin</name>
<email>mtrofin@google.com</email>
</author>
<published>2025-10-31T20:05:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=fe8ab75b408b4a252a1d0233c8ef585360b66490'/>
<id>fe8ab75b408b4a252a1d0233c8ef585360b66490</id>
<content type='text'>
`simplifySwitchOfPowersOfTwo`​ converts (when applicable, see `00f5a1e30b`​) a switch to a conditional branch. Its false case goes to the `default`​ target of the former switch, and the true case goes to a BB performing a `cttz`​. We can calculate the branch weights from the branch weights of the old switch.

Issue #147390</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`simplifySwitchOfPowersOfTwo`​ converts (when applicable, see `00f5a1e30b`​) a switch to a conditional branch. Its false case goes to the `default`​ target of the former switch, and the true case goes to a BB performing a `cttz`​. We can calculate the branch weights from the branch weights of the old switch.

Issue #147390</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Avoid use-after-free when removing incoming values from PHI nodes (#165744)</title>
<updated>2025-10-31T02:30:29+00:00</updated>
<author>
<name>Yingwei Zheng</name>
<email>dtcxzyw2333@gmail.com</email>
</author>
<published>2025-10-31T02:30:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=56777e7da2cb30f72a3ddc9861a2fbe3b9adbc6b'/>
<id>56777e7da2cb30f72a3ddc9861a2fbe3b9adbc6b</id>
<content type='text'>
`PHINode::removeIncomingValue` removes itself when there are no incoming
edges. Then we cannot use it to retrieve the next instruction.

Closes https://github.com/llvm/llvm-project/issues/165301.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`PHINode::removeIncomingValue` removes itself when there are no incoming
edges. Then we cannot use it to retrieve the next instruction.

Closes https://github.com/llvm/llvm-project/issues/165301.
</pre>
</div>
</content>
</entry>
<entry>
<title>[SimplifyCFG] Hoist common code when succ is unreachable block (#165570)</title>
<updated>2025-10-29T18:45:27+00:00</updated>
<author>
<name>Kunqiu Chen</name>
<email>camsyn@foxmail.com</email>
</author>
<published>2025-10-29T18:45:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b2fe5d1482ebab36d75922c41e73b64ab157c98b'/>
<id>b2fe5d1482ebab36d75922c41e73b64ab157c98b</id>
<content type='text'>
Previously, `hoistCommonCodeFromSuccessors` returned early if one of the
succ of BB has &gt;1 predecessors.

However, if the succ is an unreachable BB, we can relax the condition to
perform `hoistCommonCodeFromSuccessors` based on the assumption of not
reaching UB.

See discussion https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2989
for details.

Alive2 proof: https://alive2.llvm.org/ce/z/OJOw0s
Promising optimization impact:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2995</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, `hoistCommonCodeFromSuccessors` returned early if one of the
succ of BB has &gt;1 predecessors.

However, if the succ is an unreachable BB, we can relax the condition to
perform `hoistCommonCodeFromSuccessors` based on the assumption of not
reaching UB.

See discussion https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2989
for details.

Alive2 proof: https://alive2.llvm.org/ce/z/OJOw0s
Promising optimization impact:
https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2995</pre>
</div>
</content>
</entry>
</feed>
