[PATCH] D92015: [DAGCombiner] Fold BRCOND(FREEZE(COND)) to BRCOND(COND)
Juneyoung Lee via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 24 02:11:30 PST 2020
aqjune created this revision.
aqjune added reviewers: craig.topper, RKSimon, efriedma, spatel.
Herald added subscribers: llvm-commits, ecnelises, steven.zhang, pengfei, hiraditya.
Herald added a project: LLVM.
aqjune requested review of this revision.
This patch resolves the suboptimal codegen described in http://llvm.org/pr47873 .
When CodeGenPrepare lowers select into a conditional branch, a freeze instruction is inserted.
It is then translated to `BRCOND(FREEZE(SETCC))` in SelDag.
The `FREEZE` in the middle of `SETCC` and `BRCOND` was causing a suboptimal code generation however.
This patch adds `BRCOND(FREEZE(COND))` -> `BRCOND(COND)` fold to DAGCombiner to remove the `FREEZE`.
To make this optimization sound, `BRCOND(UNDEF)` should be nondeterministic jump, rather than UB.
It wasn't clear what happens when the condition was undef however.
I updated the comments of `BRCOND` to make it explicit (as well as `BR_CC`, which is also a conditional branch instruction).
Note that it diverges from the semantics of `br` instruction in IR, which is explicitly UB.
Since the UB semantics was necessary to explain optimizations that use branching conditions, and SelDag doesn't seem to have such optimization, I think this divergence is okay.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D92015
Files:
llvm/include/llvm/CodeGen/ISDOpcodes.h
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/test/CodeGen/X86/select-prof-codegen.ll
Index: llvm/test/CodeGen/X86/select-prof-codegen.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/select-prof-codegen.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+
+; Compiling the select should not create 'seta - testb $1 - jump' sequence.
+define i32 @f(i32 %x, i32 %y) {
+; CHECK-LABEL: f:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: movl %edi, %eax
+; CHECK-NEXT: cmpl %esi, %edi
+; CHECK-NEXT: ja .LBB0_2
+; CHECK-NEXT: # %bb.1: # %select.false
+; CHECK-NEXT: movl %esi, %eax
+; CHECK-NEXT: .LBB0_2: # %select.end
+; CHECK-NEXT: retq
+entry:
+ %cmp = icmp ugt i32 %x, %y
+ %z = select i1 %cmp, i32 %x, i32 %y, !prof !0
+ ret i32 %z
+}
+
+!0 = !{!"branch_weights", i32 1, i32 2000}
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -14358,6 +14358,13 @@
SDValue N1 = N->getOperand(1);
SDValue N2 = N->getOperand(2);
+ // BRCOND(FREEZE(cond)) is equivalent to BRCOND(cond) (both are
+ // nondeterministic jumps).
+ if (N1->getOpcode() == ISD::FREEZE) {
+ return DAG.getNode(ISD::BRCOND, SDLoc(N), MVT::Other, Chain,
+ N1->getOperand(0), N2);
+ }
+
// If N is a constant we could fold this into a fallthrough or unconditional
// branch. However that doesn't happen very often in normal code, because
// Instcombine/SimplifyCFG should have handled the available opportunities.
Index: llvm/include/llvm/CodeGen/ISDOpcodes.h
===================================================================
--- llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -875,13 +875,15 @@
/// BRCOND - Conditional branch. The first operand is the chain, the
/// second is the condition, the third is the block to branch to if the
/// condition is true. If the type of the condition is not i1, then the
- /// high bits must conform to getBooleanContents.
+ /// high bits must conform to getBooleanContents. If the condition is undef,
+ /// it nondeterministically jumps to the block.
BRCOND,
/// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
/// that the condition is represented as condition code, and two nodes to
/// compare, rather than as a combined SetCC node. The operands in order
- /// are chain, cc, lhs, rhs, block to branch to if condition is true.
+ /// are chain, cc, lhs, rhs, block to branch to if condition is true. If
+ /// condition is undef, it nondeterministically jumps to the block.
BR_CC,
/// INLINEASM - Represents an inline asm block. This node always has two
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92015.307288.patch
Type: text/x-patch
Size: 2889 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201124/ee0202ac/attachment.bin>
More information about the llvm-commits
mailing list