diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 20d190bd4aff2f..169c955f0ba89f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -28443,13 +28443,27 @@ static SDValue LowerABD(SDValue Op, const X86Subtarget &Subtarget, bool IsSigned = Op.getOpcode() == ISD::ABDS; const TargetLowering &TLI = DAG.getTargetLoweringInfo(); - // TODO: Move to TargetLowering expandABD() once we have ABD promotion. if (VT.isScalarInteger()) { + // abds(lhs, rhs) -> select(slt(lhs,rhs),sub(rhs,lhs),sub(lhs,rhs)) + // abdu(lhs, rhs) -> select(ult(lhs,rhs),sub(rhs,lhs),sub(lhs,rhs)) + if (Subtarget.canUseCMOV() && VT.bitsGE(MVT::i32)) { + SDVTList VTs = DAG.getVTList(VT, MVT::i32); + X86::CondCode CC = IsSigned ? X86::COND_L : X86::COND_B; + SDValue LHS = DAG.getFreeze(Op.getOperand(0)); + SDValue RHS = DAG.getFreeze(Op.getOperand(1)); + SDValue Diff0 = DAG.getNode(X86ISD::SUB, dl, VTs, LHS, RHS); + SDValue Diff1 = DAG.getNode(X86ISD::SUB, dl, VTs, RHS, LHS); + return DAG.getNode(X86ISD::CMOV, dl, VT, Diff1, Diff0, + DAG.getTargetConstant(CC, dl, MVT::i8), + Diff1.getValue(1)); + } + + // TODO: Move to TargetLowering expandABD() once we have ABD promotion. + // abds(lhs, rhs) -> trunc(abs(sub(sext(lhs), sext(rhs)))) + // abdu(lhs, rhs) -> trunc(abs(sub(zext(lhs), zext(rhs)))) unsigned WideBits = std::max(2 * VT.getScalarSizeInBits(), 32u); MVT WideVT = MVT::getIntegerVT(WideBits); if (TLI.isTypeLegal(WideVT)) { - // abds(lhs, rhs) -> trunc(abs(sub(sext(lhs), sext(rhs)))) - // abdu(lhs, rhs) -> trunc(abs(sub(zext(lhs), zext(rhs)))) unsigned ExtOpc = IsSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; SDValue LHS = DAG.getNode(ExtOpc, dl, WideVT, Op.getOperand(0)); SDValue RHS = DAG.getNode(ExtOpc, dl, WideVT, Op.getOperand(1)); diff --git a/llvm/test/CodeGen/X86/abds-neg.ll b/llvm/test/CodeGen/X86/abds-neg.ll index 541ed1cbf4fe89..b72bb46209d2d6 100644 --- a/llvm/test/CodeGen/X86/abds-neg.ll +++ b/llvm/test/CodeGen/X86/abds-neg.ll @@ -139,28 +139,25 @@ define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind { define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i16_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i16_i32: ; X64: # %bb.0: -; X64-NEXT: # kill: def $edi killed $edi def $rdi -; X64-NEXT: movswq %di, %rcx -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movswl %di, %ecx +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %ecx, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $ax killed $ax killed $rax +; X64-NEXT: # kill: def $ax killed $ax killed $eax ; X64-NEXT: retq %aext = sext i16 %a to i64 %bext = sext i32 %b to i64 @@ -205,26 +202,22 @@ define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind { define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32: ; X64: # %bb.0: -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i32 %b to i64 @@ -238,27 +231,23 @@ define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { ; X86-LABEL: abd_ext_i32_i16: ; X86: # %bb.0: -; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_i16: ; X64: # %bb.0: -; X64-NEXT: # kill: def $esi killed $esi def $rsi -; X64-NEXT: movswq %si, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movswl %si, %eax +; X64-NEXT: movl %edi, %ecx +; X64-NEXT: subl %eax, %ecx +; X64-NEXT: subl %edi, %eax +; X64-NEXT: cmovll %ecx, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i16 %b to i64 @@ -272,26 +261,22 @@ define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32_undef: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_undef: ; X64: # %bb.0: -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i32 %b to i64 @@ -332,9 +317,8 @@ define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovgq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovgeq %rsi, %rax ; X64-NEXT: negq %rax ; X64-NEXT: retq %aext = sext i64 %a to i128 @@ -376,9 +360,8 @@ define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovgq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovgeq %rsi, %rax ; X64-NEXT: negq %rax ; X64-NEXT: retq %aext = sext i64 %a to i128 diff --git a/llvm/test/CodeGen/X86/abds.ll b/llvm/test/CodeGen/X86/abds.ll index fd47de5af05ab4..e972ef3787e4d5 100644 --- a/llvm/test/CodeGen/X86/abds.ll +++ b/llvm/test/CodeGen/X86/abds.ll @@ -129,26 +129,23 @@ define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind { define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i16_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i16_i32: ; X64: # %bb.0: -; X64-NEXT: # kill: def $edi killed $edi def $rdi -; X64-NEXT: movswq %di, %rcx -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $ax killed $ax killed $rax +; X64-NEXT: movswl %di, %ecx +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %ecx, %esi +; X64-NEXT: cmovgel %esi, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax ; X64-NEXT: retq %aext = sext i16 %a to i64 %bext = sext i32 %b to i64 @@ -191,24 +188,20 @@ define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind { define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32: ; X64: # %bb.0: -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i32 %b to i64 @@ -221,25 +214,21 @@ define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { ; X86-LABEL: abd_ext_i32_i16: ; X86: # %bb.0: -; X86-NEXT: movswl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_i16: ; X64: # %bb.0: -; X64-NEXT: # kill: def $esi killed $esi def $rsi -; X64-NEXT: movswq %si, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movswl %si, %eax +; X64-NEXT: movl %edi, %ecx +; X64-NEXT: subl %eax, %ecx +; X64-NEXT: subl %edi, %eax +; X64-NEXT: cmovll %ecx, %eax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i16 %b to i64 @@ -252,24 +241,20 @@ define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32_undef: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_undef: ; X64: # %bb.0: -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: retq %aext = sext i32 %a to i64 %bext = sext i32 %b to i64 @@ -306,9 +291,8 @@ define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovgq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovgeq %rsi, %rax ; X64-NEXT: retq %aext = sext i64 %a to i128 %bext = sext i64 %b to i128 @@ -345,9 +329,8 @@ define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovgq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovgeq %rsi, %rax ; X64-NEXT: retq %aext = sext i64 %a to i128 %bext = sext i64 %b to i128 @@ -542,24 +525,20 @@ define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind { define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_minmax_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovlel %edx, %eax +; X86-NEXT: cmovll %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_minmax_i32: ; X64: # %bb.0: -; X64-NEXT: movslq %esi, %rax -; X64-NEXT: movslq %edi, %rcx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovgel %esi, %eax ; X64-NEXT: retq %min = call i32 @llvm.smin.i32(i32 %a, i32 %b) %max = call i32 @llvm.smax.i32(i32 %a, i32 %b) @@ -594,9 +573,8 @@ define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovgq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovgeq %rsi, %rax ; X64-NEXT: retq %min = call i64 @llvm.smin.i64(i64 %a, i64 %b) %max = call i64 @llvm.smax.i64(i64 %a, i64 %b) diff --git a/llvm/test/CodeGen/X86/abdu-neg.ll b/llvm/test/CodeGen/X86/abdu-neg.ll index fe4525009ad5c8..9cb3e5e8bf0c26 100644 --- a/llvm/test/CodeGen/X86/abdu-neg.ll +++ b/llvm/test/CodeGen/X86/abdu-neg.ll @@ -139,27 +139,25 @@ define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind { define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i16_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i16_i32: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax ; X64-NEXT: movzwl %di, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %ecx, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $ax killed $ax killed $rax +; X64-NEXT: # kill: def $ax killed $ax killed $eax ; X64-NEXT: retq %aext = zext i16 %a to i64 %bext = zext i32 %b to i64 @@ -204,26 +202,22 @@ define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind { define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: movl %edi, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i32 %b to i64 @@ -237,26 +231,23 @@ define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { ; X86-LABEL: abd_ext_i32_i16: ; X86: # %bb.0: -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_i16: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %ecx ; X64-NEXT: movzwl %si, %eax -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %ecx +; X64-NEXT: subl %eax, %ecx +; X64-NEXT: subl %edi, %eax +; X64-NEXT: cmovbl %ecx, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i16 %b to i64 @@ -270,26 +261,22 @@ define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32_undef: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_undef: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: movl %edi, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: negl %eax -; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i32 %b to i64 @@ -324,9 +311,8 @@ define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovaq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: negq %rax ; X64-NEXT: retq %aext = zext i64 %a to i128 @@ -362,9 +348,8 @@ define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovaq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: negq %rax ; X64-NEXT: retq %aext = zext i64 %a to i128 diff --git a/llvm/test/CodeGen/X86/abdu.ll b/llvm/test/CodeGen/X86/abdu.ll index 2e2a1debc38cb1..e808e0f21babf2 100644 --- a/llvm/test/CodeGen/X86/abdu.ll +++ b/llvm/test/CodeGen/X86/abdu.ll @@ -129,25 +129,23 @@ define i16 @abd_ext_i16(i16 %a, i16 %b) nounwind { define i16 @abd_ext_i16_i32(i16 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i16_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: # kill: def $ax killed $ax killed $eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i16_i32: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax ; X64-NEXT: movzwl %di, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $ax killed $ax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %ecx, %esi +; X64-NEXT: cmovael %esi, %eax +; X64-NEXT: # kill: def $ax killed $ax killed $eax ; X64-NEXT: retq %aext = zext i16 %a to i64 %bext = zext i32 %b to i64 @@ -190,24 +188,20 @@ define i16 @abd_ext_i16_undef(i16 %a, i16 %b) nounwind { define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: movl %edi, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i32 %b to i64 @@ -220,24 +214,21 @@ define i32 @abd_ext_i32(i32 %a, i32 %b) nounwind { define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { ; X86-LABEL: abd_ext_i32_i16: ; X86: # %bb.0: -; X86-NEXT: movzwl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_i16: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %ecx ; X64-NEXT: movzwl %si, %eax -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %ecx +; X64-NEXT: subl %eax, %ecx +; X64-NEXT: subl %edi, %eax +; X64-NEXT: cmovbl %ecx, %eax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i16 %b to i64 @@ -250,24 +241,20 @@ define i32 @abd_ext_i32_i16(i32 %a, i16 %b) nounwind { define i32 @abd_ext_i32_undef(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_ext_i32_undef: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_ext_i32_undef: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: movl %edi, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: retq %aext = zext i32 %a to i64 %bext = zext i32 %b to i64 @@ -296,9 +283,8 @@ define i64 @abd_ext_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovaq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: retq %aext = zext i64 %a to i128 %bext = zext i64 %b to i128 @@ -327,9 +313,8 @@ define i64 @abd_ext_i64_undef(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovaq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: retq %aext = zext i64 %a to i128 %bext = zext i64 %b to i128 @@ -512,24 +497,20 @@ define i16 @abd_minmax_i16(i16 %a, i16 %b) nounwind { define i32 @abd_minmax_i32(i32 %a, i32 %b) nounwind { ; X86-LABEL: abd_minmax_i32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: movl %eax, %edx -; X86-NEXT: subl %ecx, %edx -; X86-NEXT: negl %edx +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: subl %eax, %edx ; X86-NEXT: subl %ecx, %eax -; X86-NEXT: cmovbel %edx, %eax +; X86-NEXT: cmovbl %edx, %eax ; X86-NEXT: retl ; ; X64-LABEL: abd_minmax_i32: ; X64: # %bb.0: -; X64-NEXT: movl %esi, %eax -; X64-NEXT: movl %edi, %ecx -; X64-NEXT: subq %rax, %rcx -; X64-NEXT: movq %rcx, %rax -; X64-NEXT: negq %rax -; X64-NEXT: cmovsq %rcx, %rax -; X64-NEXT: # kill: def $eax killed $eax killed $rax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: subl %esi, %eax +; X64-NEXT: subl %edi, %esi +; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: retq %min = call i32 @llvm.umin.i32(i32 %a, i32 %b) %max = call i32 @llvm.umax.i32(i32 %a, i32 %b) @@ -556,9 +537,8 @@ define i64 @abd_minmax_i64(i64 %a, i64 %b) nounwind { ; X64: # %bb.0: ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: subq %rsi, %rax -; X64-NEXT: negq %rax -; X64-NEXT: subq %rsi, %rdi -; X64-NEXT: cmovaq %rdi, %rax +; X64-NEXT: subq %rdi, %rsi +; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: retq %min = call i64 @llvm.umin.i64(i64 %a, i64 %b) %max = call i64 @llvm.umax.i64(i64 %a, i64 %b)