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 @@ -10341,6 +10341,13 @@ return DAG.getNode(ISD::OR, DL, VT, Cond, N2); } + // select Cond, C, -1 --> or (sext (not Cond)), C + if (C2->isAllOnes()) { + SDValue NotCond = DAG.getNOT(DL, Cond, MVT::i1); + NotCond = DAG.getSExtOrTrunc(NotCond, DL, VT); + return DAG.getNode(ISD::OR, DL, VT, NotCond, N1); + } + if (SDValue V = foldSelectOfConstantsUsingSra(N, DAG)) return V; } diff --git a/llvm/test/CodeGen/X86/cmov-promotion.ll b/llvm/test/CodeGen/X86/cmov-promotion.ll --- a/llvm/test/CodeGen/X86/cmov-promotion.ll +++ b/llvm/test/CodeGen/X86/cmov-promotion.ll @@ -124,10 +124,10 @@ define i64 @cmov_zpromotion_32_to_64(i1 %c) { ; CMOV-LABEL: cmov_zpromotion_32_to_64: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E -; CMOV-NEXT: movl $-1, %eax -; CMOV-NEXT: cmovnel %ecx, %eax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leal -1(%rdi), %eax +; CMOV-NEXT: orl $12414, %eax # imm = 0x307E ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_zpromotion_32_to_64: @@ -173,20 +173,18 @@ define i32 @cmov_spromotion_8_to_32(i1 %c) { ; CMOV-LABEL: cmov_spromotion_8_to_32: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $126, %ecx -; CMOV-NEXT: movl $-1, %eax -; CMOV-NEXT: cmovnel %ecx, %eax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leal -1(%rdi), %eax +; CMOV-NEXT: orl $126, %eax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_8_to_32: ; NO_CMOV: # %bb.0: -; NO_CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) -; NO_CMOV-NEXT: movl $126, %eax -; NO_CMOV-NEXT: jne .LBB7_2 -; NO_CMOV-NEXT: # %bb.1: -; NO_CMOV-NEXT: movl $-1, %eax -; NO_CMOV-NEXT: .LBB7_2: +; NO_CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; NO_CMOV-NEXT: andl $1, %eax +; NO_CMOV-NEXT: decl %eax +; NO_CMOV-NEXT: orl $126, %eax ; NO_CMOV-NEXT: retl %t0 = select i1 %c, i8 12414, i8 -1 %ret = sext i8 %t0 to i32 @@ -196,23 +194,21 @@ define i64 @cmov_spromotion_8_to_64(i1 %c) { ; CMOV-LABEL: cmov_spromotion_8_to_64: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $126, %ecx -; CMOV-NEXT: movq $-1, %rax -; CMOV-NEXT: cmovneq %rcx, %rax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leaq -1(%rdi), %rax +; CMOV-NEXT: orq $126, %rax ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_8_to_64: ; NO_CMOV: # %bb.0: -; NO_CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) -; NO_CMOV-NEXT: jne .LBB8_1 -; NO_CMOV-NEXT: # %bb.2: -; NO_CMOV-NEXT: movl $-1, %eax -; NO_CMOV-NEXT: movl $-1, %edx -; NO_CMOV-NEXT: retl -; NO_CMOV-NEXT: .LBB8_1: +; NO_CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax ; NO_CMOV-NEXT: xorl %edx, %edx -; NO_CMOV-NEXT: movl $126, %eax +; NO_CMOV-NEXT: btl $0, %eax +; NO_CMOV-NEXT: adcl $-1, %edx +; NO_CMOV-NEXT: andl $1, %eax +; NO_CMOV-NEXT: decl %eax +; NO_CMOV-NEXT: orl $126, %eax ; NO_CMOV-NEXT: retl %t0 = select i1 %c, i8 12414, i8 -1 %ret = sext i8 %t0 to i64 @@ -222,20 +218,18 @@ define i32 @cmov_spromotion_16_to_32(i1 %c) { ; CMOV-LABEL: cmov_spromotion_16_to_32: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E -; CMOV-NEXT: movl $-1, %eax -; CMOV-NEXT: cmovnel %ecx, %eax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leal -1(%rdi), %eax +; CMOV-NEXT: orl $12414, %eax # imm = 0x307E ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_16_to_32: ; NO_CMOV: # %bb.0: -; NO_CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) -; NO_CMOV-NEXT: movl $12414, %eax # imm = 0x307E -; NO_CMOV-NEXT: jne .LBB9_2 -; NO_CMOV-NEXT: # %bb.1: -; NO_CMOV-NEXT: movl $-1, %eax -; NO_CMOV-NEXT: .LBB9_2: +; NO_CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; NO_CMOV-NEXT: andl $1, %eax +; NO_CMOV-NEXT: decl %eax +; NO_CMOV-NEXT: orl $12414, %eax # imm = 0x307E ; NO_CMOV-NEXT: retl %t0 = select i1 %c, i16 12414, i16 -1 %ret = sext i16 %t0 to i32 @@ -245,23 +239,21 @@ define i64 @cmov_spromotion_16_to_64(i1 %c) { ; CMOV-LABEL: cmov_spromotion_16_to_64: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E -; CMOV-NEXT: movq $-1, %rax -; CMOV-NEXT: cmovneq %rcx, %rax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leaq -1(%rdi), %rax +; CMOV-NEXT: orq $12414, %rax # imm = 0x307E ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_16_to_64: ; NO_CMOV: # %bb.0: -; NO_CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) -; NO_CMOV-NEXT: jne .LBB10_1 -; NO_CMOV-NEXT: # %bb.2: -; NO_CMOV-NEXT: movl $-1, %eax -; NO_CMOV-NEXT: movl $-1, %edx -; NO_CMOV-NEXT: retl -; NO_CMOV-NEXT: .LBB10_1: +; NO_CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax ; NO_CMOV-NEXT: xorl %edx, %edx -; NO_CMOV-NEXT: movl $12414, %eax # imm = 0x307E +; NO_CMOV-NEXT: btl $0, %eax +; NO_CMOV-NEXT: adcl $-1, %edx +; NO_CMOV-NEXT: andl $1, %eax +; NO_CMOV-NEXT: decl %eax +; NO_CMOV-NEXT: orl $12414, %eax # imm = 0x307E ; NO_CMOV-NEXT: retl %t0 = select i1 %c, i16 12414, i16 -1 %ret = sext i16 %t0 to i64 @@ -271,23 +263,21 @@ define i64 @cmov_spromotion_32_to_64(i1 %c) { ; CMOV-LABEL: cmov_spromotion_32_to_64: ; CMOV: # %bb.0: -; CMOV-NEXT: testb $1, %dil -; CMOV-NEXT: movl $12414, %ecx # imm = 0x307E -; CMOV-NEXT: movq $-1, %rax -; CMOV-NEXT: cmovneq %rcx, %rax +; CMOV-NEXT: # kill: def $edi killed $edi def $rdi +; CMOV-NEXT: andl $1, %edi +; CMOV-NEXT: leaq -1(%rdi), %rax +; CMOV-NEXT: orq $12414, %rax # imm = 0x307E ; CMOV-NEXT: retq ; ; NO_CMOV-LABEL: cmov_spromotion_32_to_64: ; NO_CMOV: # %bb.0: -; NO_CMOV-NEXT: testb $1, {{[0-9]+}}(%esp) -; NO_CMOV-NEXT: jne .LBB11_1 -; NO_CMOV-NEXT: # %bb.2: -; NO_CMOV-NEXT: movl $-1, %eax -; NO_CMOV-NEXT: movl $-1, %edx -; NO_CMOV-NEXT: retl -; NO_CMOV-NEXT: .LBB11_1: +; NO_CMOV-NEXT: movzbl {{[0-9]+}}(%esp), %eax ; NO_CMOV-NEXT: xorl %edx, %edx -; NO_CMOV-NEXT: movl $12414, %eax # imm = 0x307E +; NO_CMOV-NEXT: btl $0, %eax +; NO_CMOV-NEXT: adcl $-1, %edx +; NO_CMOV-NEXT: andl $1, %eax +; NO_CMOV-NEXT: decl %eax +; NO_CMOV-NEXT: orl $12414, %eax # imm = 0x307E ; NO_CMOV-NEXT: retl %t0 = select i1 %c, i32 12414, i32 -1 %ret = sext i32 %t0 to i64 diff --git a/llvm/test/CodeGen/X86/pr16031.ll b/llvm/test/CodeGen/X86/pr16031.ll --- a/llvm/test/CodeGen/X86/pr16031.ll +++ b/llvm/test/CodeGen/X86/pr16031.ll @@ -4,10 +4,10 @@ define i64 @main(i1 %tobool1) nounwind { ; CHECK-LABEL: main: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: testb $1, {{[0-9]+}}(%esp) -; CHECK-NEXT: movl $-12, %ecx -; CHECK-NEXT: movl $-1, %eax -; CHECK-NEXT: cmovnel %ecx, %eax +; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: decl %eax +; CHECK-NEXT: orl $-12, %eax ; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: movl %eax, %edx ; CHECK-NEXT: addl $-1, %edx diff --git a/llvm/test/CodeGen/X86/select_const.ll b/llvm/test/CodeGen/X86/select_const.ll --- a/llvm/test/CodeGen/X86/select_const.ll +++ b/llvm/test/CodeGen/X86/select_const.ll @@ -268,9 +268,9 @@ ; CHECK-LABEL: sel_1_neg1: ; CHECK: # %bb.0: ; CHECK-NEXT: cmpl $43, %edi -; CHECK-NEXT: setge %al -; CHECK-NEXT: shlb $2, %al -; CHECK-NEXT: decb %al +; CHECK-NEXT: setl %al +; CHECK-NEXT: negb %al +; CHECK-NEXT: orb $3, %al ; CHECK-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sel = select i1 %cmp, i8 3, i8 -1 diff --git a/llvm/test/CodeGen/X86/zext-sext.ll b/llvm/test/CodeGen/X86/zext-sext.ll --- a/llvm/test/CodeGen/X86/zext-sext.ll +++ b/llvm/test/CodeGen/X86/zext-sext.ll @@ -16,26 +16,26 @@ ; CHECK-NEXT: movq (%rdx), %rax ; CHECK-NEXT: movswl 8(%rdi), %edx ; CHECK-NEXT: movswl (%rax,%rsi,2), %eax -; CHECK-NEXT: movl $1, %esi ; CHECK-NEXT: imull %edx, %eax -; CHECK-NEXT: xorl %edx, %edx ; CHECK-NEXT: addl $2138875574, %eax # imm = 0x7F7CA6B6 -; CHECK-NEXT: cmpl $-8608074, %eax # imm = 0xFF7CA6B6 -; CHECK-NEXT: movslq %eax, %rdi -; CHECK-NEXT: setl %dl ; CHECK-NEXT: cmpl $2138875574, %eax # imm = 0x7F7CA6B6 -; CHECK-NEXT: movq %rdi, %r8 -; CHECK-NEXT: leal -1(%rdx,%rdx), %edx -; CHECK-NEXT: cmovll %edx, %esi -; CHECK-NEXT: subq %rax, %r8 +; CHECK-NEXT: setl %sil +; CHECK-NEXT: cmpl $-8608074, %eax # imm = 0xFF7CA6B6 +; CHECK-NEXT: setge %dl +; CHECK-NEXT: andb %sil, %dl +; CHECK-NEXT: movslq %eax, %rsi +; CHECK-NEXT: movzbl %dl, %edx +; CHECK-NEXT: movq %rsi, %rdi +; CHECK-NEXT: subq %rax, %rdi +; CHECK-NEXT: negl %edx ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpl $1, %esi -; CHECK-NEXT: cmovneq %rax, %r8 -; CHECK-NEXT: testl %edi, %edi -; CHECK-NEXT: cmovnsq %rax, %r8 +; CHECK-NEXT: testl $-2, %edx +; CHECK-NEXT: cmovneq %rax, %rdi +; CHECK-NEXT: testl %esi, %esi +; CHECK-NEXT: cmovnsq %rax, %rdi ; CHECK-NEXT: movq (%rcx), %rax -; CHECK-NEXT: subq %r8, %rdi -; CHECK-NEXT: leaq -2138875574(%rax,%rdi), %rax +; CHECK-NEXT: subq %rdi, %rsi +; CHECK-NEXT: leaq -2138875574(%rax,%rsi), %rax ; CHECK-NEXT: movq %rax, (%rcx) ; CHECK-NEXT: retq entry: