@@ -430,3 +430,54 @@ define i32 @cttz_32_ne_select_ffs(i32 %v) nounwind {
430430 %add = select i1 %tobool , i32 %.op , i32 0
431431 ret i32 %add
432432}
433+
434+ ; This matches the pattern emitted for __builtin_ffs - 1
435+ define i32 @cttz_32_eq_select_ffs_m1 (i32 %v ) nounwind {
436+ ; NOBMI-LABEL: cttz_32_eq_select_ffs_m1:
437+ ; NOBMI: # %bb.0:
438+ ; NOBMI-NEXT: bsfl %edi, %ecx
439+ ; NOBMI-NEXT: xorl %eax, %eax
440+ ; NOBMI-NEXT: cmpl $1, %edi
441+ ; NOBMI-NEXT: sbbl %eax, %eax
442+ ; NOBMI-NEXT: orl %ecx, %eax
443+ ; NOBMI-NEXT: retq
444+ ;
445+ ; BMI-LABEL: cttz_32_eq_select_ffs_m1:
446+ ; BMI: # %bb.0:
447+ ; BMI-NEXT: tzcntl %edi, %ecx
448+ ; BMI-NEXT: xorl %eax, %eax
449+ ; BMI-NEXT: cmpl $1, %edi
450+ ; BMI-NEXT: sbbl %eax, %eax
451+ ; BMI-NEXT: orl %ecx, %eax
452+ ; BMI-NEXT: retq
453+
454+ %cnt = tail call i32 @llvm.cttz.i32 (i32 %v , i1 true )
455+ %tobool = icmp eq i32 %v , 0
456+ %sel = select i1 %tobool , i32 -1 , i32 %cnt
457+ ret i32 %sel
458+ }
459+
460+ define i32 @cttz_32_ne_select_ffs_m1 (i32 %v ) nounwind {
461+ ; NOBMI-LABEL: cttz_32_ne_select_ffs_m1:
462+ ; NOBMI: # %bb.0:
463+ ; NOBMI-NEXT: bsfl %edi, %ecx
464+ ; NOBMI-NEXT: xorl %eax, %eax
465+ ; NOBMI-NEXT: cmpl $1, %edi
466+ ; NOBMI-NEXT: sbbl %eax, %eax
467+ ; NOBMI-NEXT: orl %ecx, %eax
468+ ; NOBMI-NEXT: retq
469+ ;
470+ ; BMI-LABEL: cttz_32_ne_select_ffs_m1:
471+ ; BMI: # %bb.0:
472+ ; BMI-NEXT: tzcntl %edi, %ecx
473+ ; BMI-NEXT: xorl %eax, %eax
474+ ; BMI-NEXT: cmpl $1, %edi
475+ ; BMI-NEXT: sbbl %eax, %eax
476+ ; BMI-NEXT: orl %ecx, %eax
477+ ; BMI-NEXT: retq
478+
479+ %cnt = tail call i32 @llvm.cttz.i32 (i32 %v , i1 true )
480+ %tobool = icmp ne i32 %v , 0
481+ %sel = select i1 %tobool , i32 %cnt , i32 -1
482+ ret i32 %sel
483+ }
0 commit comments