diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 6c49e24cc05..f77a716434f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -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(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)); } } diff --git a/test/CodeGen/X86/dagcombine-select.ll b/test/CodeGen/X86/dagcombine-select.ll index 50d2809e008..45d832431ab 100644 --- a/test/CodeGen/X86/dagcombine-select.ll +++ b/test/CodeGen/X86/dagcombine-select.ll @@ -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)