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/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 @@ -432,10 +432,9 @@ define i32 @select_n_or_minus1(i1 signext %cond) { ; CHECK-LABEL: select_n_or_minus1: ; CHECK: # %bb.0: -; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $12414, %ecx # imm = 0x307E -; CHECK-NEXT: movl $-1, %eax -; CHECK-NEXT: cmovnel %ecx, %eax +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: notl %eax +; CHECK-NEXT: orl $12414, %eax # imm = 0x307E ; CHECK-NEXT: retq %sel = select i1 %cond, i32 12414, i32 -1 ret i32 %sel 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: