Skip to content

Commit 2a27c05

Browse files
authored
[X86] Use BSR passthrough behaviour to fold (CMOV (BSR ?, X), Y, (X == 0)) -> (BSR Y, X) (llvm#143662)
Make use of targets that support BSR "pass through behaviour" on a zero input to remove a CMOV thats performing the same function BSF will be a trickier patch as we need to make sure it works with the "REP BSF" hack in X86MCInstLower
1 parent db8d34d commit 2a27c05

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49398,6 +49398,8 @@ static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
4939849398
// (ADD (CMOV C1-C2, (CTTZ X), (X != 0)), C2)
4939949399
// Or (CMOV (ADD (CTTZ X), C2), C1, (X == 0)) ->
4940049400
// (ADD (CMOV (CTTZ X), C1-C2, (X == 0)), C2)
49401+
// Or (CMOV (BSR ?, X), Y, (X == 0)) -> (BSR Y, X)
49402+
// TODO: Or (CMOV (BSF ?, X), Y, (X == 0)) -> (BSF Y, X)
4940149403
if ((CC == X86::COND_NE || CC == X86::COND_E) &&
4940249404
Cond.getOpcode() == X86ISD::CMP && isNullConstant(Cond.getOperand(1))) {
4940349405
SDValue Add = TrueOp;
@@ -49406,6 +49408,14 @@ static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
4940649408
if (CC == X86::COND_E)
4940749409
std::swap(Add, Const);
4940849410

49411+
// TODO: ADD BSF support, but requires changes to the "REP BSF" CTTZ hack.
49412+
if (Subtarget.hasBitScanPassThrough() && Add.getOpcode() == X86ISD::BSR &&
49413+
Add.getResNo() == 0 && Add.hasOneUse() &&
49414+
Add.getOperand(1) == Cond.getOperand(0)) {
49415+
return DAG.getNode(Add.getOpcode(), DL, Add->getVTList(), Const,
49416+
Add.getOperand(1));
49417+
}
49418+
4940949419
// We might have replaced the constant in the cmov with the LHS of the
4941049420
// compare. If so change it to the RHS of the compare.
4941149421
if (Const == Cond.getOperand(0))

llvm/test/CodeGen/X86/bsr.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,8 @@ define i32 @cmov_bsr32(i32 %x, i32 %y) nounwind {
162162
;
163163
; X64-LABEL: cmov_bsr32:
164164
; X64: # %bb.0:
165-
; X64-NEXT: movl $63, %eax
165+
; X64-NEXT: movl %esi, %eax
166166
; X64-NEXT: bsrl %edi, %eax
167-
; X64-NEXT: cmovel %esi, %eax
168167
; X64-NEXT: retq
169168
%1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
170169
%2 = xor i32 %1, 31
@@ -188,8 +187,8 @@ define i32 @cmov_bsr32_undef(i32 %x, i32 %y) nounwind {
188187
;
189188
; X64-LABEL: cmov_bsr32_undef:
190189
; X64: # %bb.0:
190+
; X64-NEXT: movl %esi, %eax
191191
; X64-NEXT: bsrl %edi, %eax
192-
; X64-NEXT: cmovel %esi, %eax
193192
; X64-NEXT: retq
194193
%1 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
195194
%2 = xor i32 %1, 31
@@ -239,9 +238,8 @@ define i64 @cmov_bsr64(i64 %x, i64 %y) nounwind {
239238
;
240239
; X64-LABEL: cmov_bsr64:
241240
; X64: # %bb.0:
242-
; X64-NEXT: movl $127, %eax
241+
; X64-NEXT: movq %rsi, %rax
243242
; X64-NEXT: bsrq %rdi, %rax
244-
; X64-NEXT: cmoveq %rsi, %rax
245243
; X64-NEXT: retq
246244
%1 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
247245
%2 = xor i64 %1, 63
@@ -279,8 +277,8 @@ define i64 @cmov_bsr64_undef(i64 %x, i64 %y) nounwind {
279277
;
280278
; X64-LABEL: cmov_bsr64_undef:
281279
; X64: # %bb.0:
280+
; X64-NEXT: movq %rsi, %rax
282281
; X64-NEXT: bsrq %rdi, %rax
283-
; X64-NEXT: cmoveq %rsi, %rax
284282
; X64-NEXT: retq
285283
%1 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
286284
%2 = xor i64 %1, 63

llvm/test/CodeGen/X86/pr40090.ll

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
define i64 @foo(i64 %x, i64 %y) {
55
; CHECK-LABEL: foo:
66
; CHECK: # %bb.0:
7-
; CHECK-NEXT: bsrq %rdi, %rax
8-
; CHECK-NEXT: orq $64, %rax
7+
; CHECK-NEXT: bsrq %rdi, %rcx
8+
; CHECK-NEXT: orq $64, %rcx
99
; CHECK-NEXT: bsrq %rsi, %rcx
10-
; CHECK-NEXT: cmoveq %rax, %rcx
1110
; CHECK-NEXT: movl $63, %eax
1211
; CHECK-NEXT: subq %rcx, %rax
1312
; CHECK-NEXT: retq
@@ -25,11 +24,9 @@ define i64 @bar(i64 %x, i64 %y) {
2524
; CHECK-LABEL: bar:
2625
; CHECK: # %bb.0:
2726
; CHECK-NEXT: movl $127, %ecx
28-
; CHECK-NEXT: movl $127, %eax
29-
; CHECK-NEXT: bsrq %rdi, %rax
30-
; CHECK-NEXT: xorq $64, %rax
27+
; CHECK-NEXT: bsrq %rdi, %rcx
28+
; CHECK-NEXT: xorq $64, %rcx
3129
; CHECK-NEXT: bsrq %rsi, %rcx
32-
; CHECK-NEXT: cmoveq %rax, %rcx
3330
; CHECK-NEXT: movl $63, %eax
3431
; CHECK-NEXT: subq %rcx, %rax
3532
; CHECK-NEXT: retq

0 commit comments

Comments
 (0)