diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2765,17 +2765,30 @@ break; } - // If this is not a carry, return. - if (V.getResNo() != 1) - return SDValue(); - - if (V.getOpcode() != ISD::ADDCARRY && V.getOpcode() != ISD::SUBCARRY && - V.getOpcode() != ISD::UADDO && V.getOpcode() != ISD::USUBO) - return SDValue(); + switch (V.getOpcode()) { + case ISD::ADDCARRY: + case ISD::SUBCARRY: + case ISD::UADDO: + case ISD::USUBO: { + // If this is not a carry, return. + if (V.getResNo() != 1) + return SDValue(); - EVT VT = V->getValueType(0); - if (!TLI.isOperationLegalOrCustom(V.getOpcode(), VT)) + EVT VT = V.getNode()->getValueType(0); + if (!TLI.isOperationLegalOrCustom(V.getOpcode(), VT)) + return SDValue(); + break; + } + case ISD::SETCC: { + // Consider SETULT which affects carry flag only. + ISD::CondCode CC = cast(V.getOperand(2))->get(); + if (CC != ISD::SETULT) + return SDValue(); + break; + } + default: return SDValue(); + } // If the result is masked, then no matter what kind of bool it is we can // return. If it isn't, then we need to make sure the bool type is either 0 or diff --git a/llvm/test/CodeGen/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll --- a/llvm/test/CodeGen/AArch64/arm64-csel.ll +++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll @@ -296,9 +296,9 @@ define i64 @foo18_overflow3(i1 %cmp) nounwind readnone optsize ssp { ; CHECK-LABEL: foo18_overflow3: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov x8, #-9223372036854775808 -; CHECK-NEXT: tst w0, #0x1 -; CHECK-NEXT: csel x0, x8, xzr, ne +; CHECK-NEXT: mov x8, #-9223372036854775808 +; CHECK-NEXT: tst w0, #0x1 +; CHECK-NEXT: csel x0, x8, xzr, ne ; CHECK-NEXT: ret entry: %. = select i1 %cmp, i64 -9223372036854775808, i64 0 @@ -309,9 +309,9 @@ define i64 @foo18_overflow4(i1 %cmp) nounwind readnone optsize ssp { ; CHECK-LABEL: foo18_overflow4: ; CHECK: // %bb.0: // %entry -; CHECK-NEXT: mov x8, #-9223372036854775808 -; CHECK-NEXT: tst w0, #0x1 -; CHECK-NEXT: csel x0, xzr, x8, ne +; CHECK-NEXT: mov x8, #-9223372036854775808 +; CHECK-NEXT: tst w0, #0x1 +; CHECK-NEXT: csel x0, xzr, x8, ne ; CHECK-NEXT: ret entry: %. = select i1 %cmp, i64 0, i64 -9223372036854775808 @@ -322,7 +322,9 @@ ; CHECK-LABEL: foo19: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: cmp x0, x1 -; CHECK-NEXT: cinc x0, x2, lo +; CHECK-NEXT: cset w8, lo +; CHECK-NEXT: cmp w8, #1 +; CHECK-NEXT: cinc x0, x2, hs ; CHECK-NEXT: ret entry: %cmp = icmp ult i64 %a, %b diff --git a/llvm/test/CodeGen/X86/addcarry.ll b/llvm/test/CodeGen/X86/addcarry.ll --- a/llvm/test/CodeGen/X86/addcarry.ll +++ b/llvm/test/CodeGen/X86/addcarry.ll @@ -743,38 +743,31 @@ define i32 @add_U320_without_i128_add(ptr nocapture dereferenceable(40) %0, i64 %1, i64 %2, i64 %3, i64 %4, i64 %5) nounwind { ; CHECK-LABEL: add_U320_without_i128_add: ; CHECK: # %bb.0: -; CHECK-NEXT: pushq %r14 -; CHECK-NEXT: pushq %rbx -; CHECK-NEXT: movq 16(%rdi), %rax -; CHECK-NEXT: leaq (%rax,%rcx), %r10 +; CHECK-NEXT: movq 16(%rdi), %r10 +; CHECK-NEXT: xorl %r11d, %r11d +; CHECK-NEXT: movq %r10, %rax +; CHECK-NEXT: addq %rcx, %rax +; CHECK-NEXT: setb %r11b ; CHECK-NEXT: addq %rsi, (%rdi) ; CHECK-NEXT: adcq %rdx, 8(%rdi) -; CHECK-NEXT: movq %rax, %rdx -; CHECK-NEXT: adcq %rcx, %rdx -; CHECK-NEXT: movq 24(%rdi), %r11 -; CHECK-NEXT: leaq (%r8,%r11), %r14 -; CHECK-NEXT: xorl %ebx, %ebx -; CHECK-NEXT: cmpq %r10, %rdx -; CHECK-NEXT: setb %bl -; CHECK-NEXT: addq %rcx, %rax -; CHECK-NEXT: adcq %r14, %rbx -; CHECK-NEXT: movq 32(%rdi), %r10 -; CHECK-NEXT: leaq (%r9,%r10), %rcx -; CHECK-NEXT: xorl %esi, %esi -; CHECK-NEXT: cmpq %r14, %rbx -; CHECK-NEXT: setb %sil -; CHECK-NEXT: addq %r11, %r8 -; CHECK-NEXT: adcq %rcx, %rsi +; CHECK-NEXT: adcq %rcx, %r10 +; CHECK-NEXT: xorl %ecx, %ecx +; CHECK-NEXT: addq 24(%rdi), %r8 +; CHECK-NEXT: setb %cl +; CHECK-NEXT: cmpq %rax, %r10 +; CHECK-NEXT: adcq %r8, %r11 +; CHECK-NEXT: movq 32(%rdi), %rdx +; CHECK-NEXT: leaq (%r9,%rdx), %rsi +; CHECK-NEXT: cmpq %r8, %r11 +; CHECK-NEXT: adcq %rsi, %rcx ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpq %rcx, %rsi +; CHECK-NEXT: cmpq %rsi, %rcx ; CHECK-NEXT: setb %al -; CHECK-NEXT: addq %r10, %r9 -; CHECK-NEXT: movq %rdx, 16(%rdi) -; CHECK-NEXT: movq %rbx, 24(%rdi) -; CHECK-NEXT: movq %rsi, 32(%rdi) +; CHECK-NEXT: addq %rdx, %r9 +; CHECK-NEXT: movq %r10, 16(%rdi) +; CHECK-NEXT: movq %r11, 24(%rdi) +; CHECK-NEXT: movq %rcx, 32(%rdi) ; CHECK-NEXT: adcl $0, %eax -; CHECK-NEXT: popq %rbx -; CHECK-NEXT: popq %r14 ; CHECK-NEXT: retq %7 = load i64, ptr %0, align 8 %8 = getelementptr inbounds %struct.U320, ptr %0, i64 0, i32 0, i64 1