(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
+(define_insn "*bmi_blsi_<mode>_cmp"
+ [(set (reg FLAGS_REG)
+ (compare
+ (and:SWI48
+ (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
+ "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
+ "blsi\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "btver2_decode" "double")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "*bmi_blsi_<mode>_ccno"
+ [(set (reg FLAGS_REG)
+ (compare
+ (and:SWI48
+ (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
+ (match_dup 1))
+ (const_int 0)))
+ (clobber (match_scratch:SWI48 0 "=r"))]
+ "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
+ "blsi\t{%1, %0|%0, %1}"
+ [(set_attr "type" "bitmanip")
+ (set_attr "btver2_decode" "double")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "*bmi_blsmsk_<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(xor:SWI48
--- /dev/null
+/* PR target/98567 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-stack-protector" } */
+/* { dg-final { scan-assembler-times "\tblsi" 4 } } */
+/* { dg-final { scan-assembler-times "\tsetne\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tsete\t" 2 } } */
+/* { dg-final { scan-assembler-not "\ttest\[ld]" } } */
+
+int
+foo (unsigned long x)
+{
+ return (-x & x) == 0;
+}
+
+int
+bar (unsigned int x)
+{
+ return (-x & x) == 0;
+}
+
+int
+baz (unsigned long x)
+{
+ return (x & -x) != 0;
+}
+
+int
+qux (unsigned int x)
+{
+ return 0 != (x & -x);
+}
--- /dev/null
+/* PR target/98567 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -fno-stack-protector" } */
+/* { dg-final { scan-assembler-times "\tblsi" 4 } } */
+/* { dg-final { scan-assembler-times "\tsetle\t" 2 } } */
+/* { dg-final { scan-assembler-times "\tsetg\t" 2 } } */
+/* { dg-final { scan-assembler-not "\ttest\[ld]" } } */
+
+int
+foo (unsigned long x)
+{
+ return 0 >= (int) (-x & x);
+}
+
+int
+bar (unsigned int x)
+{
+ return (int) (-x & x) <= 0;
+}
+
+int
+baz (unsigned long x)
+{
+ return (int) (x & -x) > 0;
+}
+
+int
+qux (unsigned int x)
+{
+ return 0 < (int) (x & -x);
+}