(ctz:SWI48 (match_dup 1)))]
"TARGET_BMI"
"tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
- "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
+ "&& (TARGET_AVOID_FALSE_DEP_FOR_BMI || TARGET_AVOID_FALSE_DEP_FOR_TZCNT)
+ && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel
return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
}
"(TARGET_BMI || TARGET_CPU_P (GENERIC))
- && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
+ && (TARGET_AVOID_FALSE_DEP_FOR_BMI || TARGET_AVOID_FALSE_DEP_FOR_TZCNT)
+ && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel
(clobber (reg:CC FLAGS_REG))]
"TARGET_BMI && TARGET_64BIT"
"tzcnt{l}\t{%1, %k0|%k0, %1}"
- "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
+ "&& (TARGET_AVOID_FALSE_DEP_FOR_BMI || TARGET_AVOID_FALSE_DEP_FOR_TZCNT)
+ && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel
return "bsf{l}\t{%1, %k0|%k0, %1}";
}
"(TARGET_BMI || TARGET_CPU_P (GENERIC))
- && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
+ && (TARGET_AVOID_FALSE_DEP_FOR_BMI || TARGET_AVOID_FALSE_DEP_FOR_TZCNT)
+ && epilogue_completed
&& optimize_function_for_speed_p (cfun)
&& !reg_mentioned_p (operands[0], operands[1])"
[(parallel
(set_attr "btver2_decode" "direct, double")
(set_attr "mode" "<MODE>")])
-(define_insn "*bmi_blsi_<mode>"
+(define_insn_and_split "*bmi_blsi_<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(and:SWI48
(neg:SWI48
(clobber (reg:CC FLAGS_REG))]
"TARGET_BMI"
"blsi\t{%1, %0|%0, %1}"
+ "&& TARGET_AVOID_FALSE_DEP_FOR_BLS
+ && epilogue_completed
+ && optimize_function_for_speed_p (cfun)
+ && !reg_mentioned_p (operands[0], operands[1])"
+ [(parallel
+ [(set (reg:CCNO FLAGS_REG)
+ (compare:CCNO
+ (and:SWI48
+ (neg:SWI48 (match_dup 1))
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0) (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+ "ix86_expand_clear (operands[0]);"
[(set_attr "type" "bitmanip")
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
+(define_split
+ [(set (match_operand 3 "flags_reg_operand")
+ (match_operator 4 "compare_operator"
+ [(and:SWI48
+ (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))
+ (match_dup 1))
+ (const_int 0)]))
+ (set (match_operand:SWI48 0 "register_operand")
+ (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
+ "TARGET_BMI
+ && TARGET_AVOID_FALSE_DEP_FOR_BLS
+ && epilogue_completed
+ && optimize_function_for_speed_p (cfun)
+ && !reg_mentioned_p (operands[0], operands[1])"
+ [(parallel
+ [(set (match_dup 3)
+ (match_op_dup 4
+ [(and:SWI48
+ (neg:SWI48 (match_dup 1))
+ (match_dup 1))
+ (const_int 0)]))
+ (set (match_dup 0) (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+ "ix86_expand_clear (operands[0]);")
+
+; False dependency happens when destination is only updated by blsi.
+(define_insn "*bmi_blsi_<mode>_falsedep"
+ [(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)))
+ (unspec [(match_operand:SWI48 2 "register_operand" "0")]
+ UNSPEC_INSN_FALSE_DEP)]
+ "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>")])
+
+;; No need for splitter of the false dependency, since the output is unused
+;; so it will not extend dependency chain.
(define_insn "*bmi_blsi_<mode>_ccno"
[(set (reg FLAGS_REG)
(compare
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
-(define_insn "*bmi_blsmsk_<mode>"
+(define_insn_and_split "*bmi_blsmsk_<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(xor:SWI48
(plus:SWI48
(clobber (reg:CC FLAGS_REG))]
"TARGET_BMI"
"blsmsk\t{%1, %0|%0, %1}"
+ "TARGET_AVOID_FALSE_DEP_FOR_BLS
+ && epilogue_completed
+ && optimize_function_for_speed_p (cfun)
+ && !reg_mentioned_p (operands[0], operands[1])"
+ [(parallel
+ [(set (match_dup 0)
+ (xor:SWI48
+ (plus:SWI48 (match_dup 1) (const_int -1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+ "ix86_expand_clear (operands[0]);"
+ [(set_attr "type" "bitmanip")
+ (set_attr "btver2_decode" "double")
+ (set_attr "mode" "<MODE>")])
+
+; False dependency happens when destination is only updated by blmsk.
+(define_insn "*bmi_blsmsk_<mode>_falsedep"
+ [(set (match_operand:SWI48 0 "register_operand" "=r")
+ (xor:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))
+ (unspec [(match_operand:SWI48 2 "register_operand" "0")]
+ UNSPEC_INSN_FALSE_DEP)]
+ "TARGET_BMI"
+ "blsmsk\t{%1, %0|%0, %1}"
[(set_attr "type" "bitmanip")
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
-(define_insn "*bmi_blsr_<mode>"
+(define_insn_and_split "*bmi_blsr_<mode>"
[(set (match_operand:SWI48 0 "register_operand" "=r")
(and:SWI48
(plus:SWI48
(const_int -1))
(match_dup 1)))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_BMI"
- "blsr\t{%1, %0|%0, %1}"
+ "TARGET_BMI"
+ "blsr\t{%1, %0|%0, %1}"
+ "&& TARGET_AVOID_FALSE_DEP_FOR_BLS
+ && epilogue_completed
+ && optimize_function_for_speed_p (cfun)
+ && !reg_mentioned_p (operands[0], operands[1])"
+ [(parallel
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (and:SWI48
+ (plus:SWI48 (match_dup 1) (const_int -1))
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0) (and:SWI48 (plus:SWI48 (match_dup 1) (const_int -1))
+ (match_dup 1)))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+ "ix86_expand_clear (operands[0]);"
[(set_attr "type" "bitmanip")
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
-(define_insn "*bmi_blsr_<mode>_cmp"
+(define_insn_and_split "*bmi_blsr_<mode>_cmp"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ
(and:SWI48
(match_dup 1)
(const_int -1))
(match_dup 1)))]
+ "TARGET_BMI"
+ "blsr\t{%1, %0|%0, %1}"
+ "&& TARGET_AVOID_FALSE_DEP_FOR_BLS
+ && epilogue_completed
+ && optimize_function_for_speed_p (cfun)
+ && !reg_mentioned_p (operands[0], operands[1])"
+ [(parallel
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (and:SWI48
+ (plus:SWI48 (match_dup 1) (const_int -1))
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0) (and:SWI48 (plus:SWI48 (match_dup 1) (const_int -1))
+ (match_dup 1)))
+ (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
+ "ix86_expand_clear (operands[0]);"
+ [(set_attr "type" "bitmanip")
+ (set_attr "btver2_decode" "double")
+ (set_attr "mode" "<MODE>")])
+
+; False dependency happens when destination is only updated by bslr.
+(define_insn "*bmi_blsr_<mode>_cmp_falsedep"
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (and:SWI48
+ (plus:SWI48
+ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
+ (const_int -1))
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_operand:SWI48 0 "register_operand" "=r")
+ (and:SWI48
+ (plus:SWI48
+ (match_dup 1)
+ (const_int -1))
+ (match_dup 1)))
+ (unspec [(match_operand:SWI48 2 "register_operand" "0")]
+ UNSPEC_INSN_FALSE_DEP)]
"TARGET_BMI"
"blsr\t{%1, %0|%0, %1}"
[(set_attr "type" "bitmanip")
(set_attr "btver2_decode" "double")
(set_attr "mode" "<MODE>")])
+;; No need for splitter of the false dependency, since the output is unused
+;; so it will not extend dependency chain.
(define_insn "*bmi_blsr_<mode>_ccz"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ