Index: llvm/test/CodeGen/X86/bmi.ll =================================================================== --- llvm/test/CodeGen/X86/bmi.ll +++ llvm/test/CodeGen/X86/bmi.ll @@ -1053,4 +1053,104 @@ ret void } +define i32 @blsr32_branch(i32 %x) { +; X86-LABEL: blsr32_branch: +; X86: # %bb.0: +; X86-NEXT: pushl %esi +; X86-NEXT: .cfi_def_cfa_offset 8 +; X86-NEXT: .cfi_offset %esi, -8 +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: leal -1(%eax), %esi +; X86-NEXT: andl %eax, %esi +; X86-NEXT: jne .LBB46_2 +; X86-NEXT: # %bb.1: +; X86-NEXT: calll bar +; X86-NEXT: .LBB46_2: +; X86-NEXT: movl %esi, %eax +; X86-NEXT: popl %esi +; X86-NEXT: .cfi_def_cfa_offset 4 +; X86-NEXT: retl +; +; X64-LABEL: blsr32_branch: +; X64: # %bb.0: +; X64-NEXT: pushq %rbx +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: .cfi_offset %rbx, -16 +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal -1(%rdi), %ebx +; X64-NEXT: andl %edi, %ebx +; X64-NEXT: jne .LBB46_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: callq bar +; X64-NEXT: .LBB46_2: +; X64-NEXT: movl %ebx, %eax +; X64-NEXT: popq %rbx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %tmp = sub i32 %x, 1 + %tmp2 = and i32 %x, %tmp + %cmp = icmp eq i32 %tmp2, 0 + br i1 %cmp, label %1, label %2 + + tail call void @bar() + br label %2 + ret i32 %tmp2 +} + +define i64 @blsr64_branch(i64 %x) { +; X86-LABEL: blsr64_branch: +; X86: # %bb.0: +; X86-NEXT: pushl %edi +; X86-NEXT: .cfi_def_cfa_offset 8 +; X86-NEXT: pushl %esi +; X86-NEXT: .cfi_def_cfa_offset 12 +; X86-NEXT: .cfi_offset %esi, -12 +; X86-NEXT: .cfi_offset %edi, -8 +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %eax, %esi +; X86-NEXT: addl $-1, %esi +; X86-NEXT: movl %ecx, %edi +; X86-NEXT: adcl $-1, %edi +; X86-NEXT: andl %eax, %esi +; X86-NEXT: andl %ecx, %edi +; X86-NEXT: movl %esi, %eax +; X86-NEXT: orl %edi, %eax +; X86-NEXT: jne .LBB47_2 +; X86-NEXT: # %bb.1: +; X86-NEXT: calll bar +; X86-NEXT: .LBB47_2: +; X86-NEXT: movl %esi, %eax +; X86-NEXT: movl %edi, %edx +; X86-NEXT: popl %esi +; X86-NEXT: .cfi_def_cfa_offset 8 +; X86-NEXT: popl %edi +; X86-NEXT: .cfi_def_cfa_offset 4 +; X86-NEXT: retl +; +; X64-LABEL: blsr64_branch: +; X64: # %bb.0: +; X64-NEXT: pushq %rbx +; X64-NEXT: .cfi_def_cfa_offset 16 +; X64-NEXT: .cfi_offset %rbx, -16 +; X64-NEXT: leaq -1(%rdi), %rbx +; X64-NEXT: andq %rdi, %rbx +; X64-NEXT: jne .LBB47_2 +; X64-NEXT: # %bb.1: +; X64-NEXT: callq bar +; X64-NEXT: .LBB47_2: +; X64-NEXT: movq %rbx, %rax +; X64-NEXT: popq %rbx +; X64-NEXT: .cfi_def_cfa_offset 8 +; X64-NEXT: retq + %tmp = sub i64 %x, 1 + %tmp2 = and i64 %x, %tmp + %cmp = icmp eq i64 %tmp2, 0 + br i1 %cmp, label %1, label %2 + + tail call void @bar() + br label %2 + ret i64 %tmp2 +} + declare void @bar()