1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 20:43:44 +02:00

[X86] Canonicalize the pattern for __builtin_ffs in a similar way to '__builtin_ffs + 5'

We now emit a move of -1 before the cmov and do the addition after the cmov just like the case with an extra addition.

This may be slightly worse for code size, but is more consistent with other compilers. And we might be able to hoist the mov -1 outside of loops.

llvm-svn: 338613
This commit is contained in:
Craig Topper 2018-08-01 18:38:46 +00:00
parent 524257d0d4
commit 97fe71d952
2 changed files with 20 additions and 16 deletions

View File

@ -33395,10 +33395,13 @@ static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
SDValue Add = TrueOp;
SDValue Const = FalseOp;
// Canonicalize the condition code for easier matching and output.
if (CC == X86::COND_E) {
if (CC == X86::COND_E)
std::swap(Add, Const);
CC = X86::COND_NE;
}
// We might have replaced the constant in the cmov with the LHS of the
// compare. If so change it to the RHS of the compare.
if (Const == Cond.getOperand(0))
Const = Cond.getOperand(1);
// Ok, now make sure that Add is (add (cttz X), C2) and Const is a constant.
if (isa<ConstantSDNode>(Const) && Add.getOpcode() == ISD::ADD &&
@ -33410,7 +33413,8 @@ static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
// This should constant fold.
SDValue Diff = DAG.getNode(ISD::SUB, DL, VT, Const, Add.getOperand(1));
SDValue CMov = DAG.getNode(X86ISD::CMOV, DL, VT, Diff, Add.getOperand(0),
DAG.getConstant(CC, DL, MVT::i8), Cond);
DAG.getConstant(X86::COND_NE, DL, MVT::i8),
Cond);
return DAG.getNode(ISD::ADD, DL, VT, CMov, Add.getOperand(1));
}
}

View File

@ -383,18 +383,18 @@ define i32 @cttz_32_ne_select(i32 %v) nounwind {
define i32 @cttz_32_eq_select_ffs(i32 %v) nounwind {
; NOBMI-LABEL: cttz_32_eq_select_ffs:
; NOBMI: # %bb.0:
; NOBMI-NEXT: bsfl %edi, %eax
; NOBMI-NEXT: bsfl %edi, %ecx
; NOBMI-NEXT: movl $-1, %eax
; NOBMI-NEXT: cmovnel %ecx, %eax
; NOBMI-NEXT: incl %eax
; NOBMI-NEXT: testl %edi, %edi
; NOBMI-NEXT: cmovel %edi, %eax
; NOBMI-NEXT: retq
;
; BMI-LABEL: cttz_32_eq_select_ffs:
; BMI: # %bb.0:
; BMI-NEXT: tzcntl %edi, %eax
; BMI-NEXT: tzcntl %edi, %ecx
; BMI-NEXT: movl $-1, %eax
; BMI-NEXT: cmovael %ecx, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: testl %edi, %edi
; BMI-NEXT: cmovel %edi, %eax
; BMI-NEXT: retq
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
@ -407,18 +407,18 @@ define i32 @cttz_32_eq_select_ffs(i32 %v) nounwind {
define i32 @cttz_32_ne_select_ffs(i32 %v) nounwind {
; NOBMI-LABEL: cttz_32_ne_select_ffs:
; NOBMI: # %bb.0:
; NOBMI-NEXT: bsfl %edi, %eax
; NOBMI-NEXT: bsfl %edi, %ecx
; NOBMI-NEXT: movl $-1, %eax
; NOBMI-NEXT: cmovnel %ecx, %eax
; NOBMI-NEXT: incl %eax
; NOBMI-NEXT: testl %edi, %edi
; NOBMI-NEXT: cmovel %edi, %eax
; NOBMI-NEXT: retq
;
; BMI-LABEL: cttz_32_ne_select_ffs:
; BMI: # %bb.0:
; BMI-NEXT: tzcntl %edi, %eax
; BMI-NEXT: tzcntl %edi, %ecx
; BMI-NEXT: movl $-1, %eax
; BMI-NEXT: cmovael %ecx, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: testl %edi, %edi
; BMI-NEXT: cmovel %edi, %eax
; BMI-NEXT: retq
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)