@@ -112,12 +112,6 @@ ccmp_candidate_p (gimple *g)
|| gimple_bb (gs0) != gimple_bb (g))
return false;
- if (!(INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs0)))
- || POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs0))))
- || !(INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs1)))
- || POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (gs1)))))
- return false;
-
tcode0 = gimple_assign_rhs_code (gs0);
tcode1 = gimple_assign_rhs_code (gs1);
if (TREE_CODE_CLASS (tcode0) == tcc_comparison
@@ -12398,6 +12398,18 @@ aarch64_gen_ccmp_first (rtx *prep_seq, rtx
*gen_seq,
icode = CODE_FOR_cmpdi;
break;
+ case SFmode:
+ cmp_mode = SFmode;
+ cc_mode = aarch64_select_cc_mode ((rtx_code) code, op0, op1);
+ icode = cc_mode == CCFPEmode ? CODE_FOR_fcmpesf : CODE_FOR_fcmpsf;
+ break;
+
+ case DFmode:
+ cmp_mode = DFmode;
+ cc_mode = aarch64_select_cc_mode ((rtx_code) code, op0, op1);
+ icode = cc_mode == CCFPEmode ? CODE_FOR_fcmpedf : CODE_FOR_fcmpdf;
+ break;
+
default:
end_sequence ();
return NULL_RTX;
@@ -12461,6 +12473,18 @@ aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq,
rtx prev, int cmp_code,
icode = CODE_FOR_ccmpdi;
break;
+ case SFmode:
+ cmp_mode = SFmode;
+ cc_mode = aarch64_select_cc_mode ((rtx_code) cmp_code, op0, op1);
+ icode = cc_mode == CCFPEmode ? CODE_FOR_fccmpesf : CODE_FOR_fccmpsf;
+ break;
+
+ case DFmode:
+ cmp_mode = DFmode;
+ cc_mode = aarch64_select_cc_mode ((rtx_code) cmp_code, op0, op1);
+ icode = cc_mode == CCFPEmode ? CODE_FOR_fccmpedf : CODE_FOR_fccmpdf;
+ break;
+
default:
end_sequence ();
return NULL_RTX;
@@ -279,6 +279,36 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
+(define_insn "fccmp<mode>"
+ [(set (match_operand:CCFP 1 "cc_register" "")
+ (if_then_else:CCFP
+ (match_operator 4 "aarch64_comparison_operator"
+ [(match_operand 0 "cc_register" "")
+ (const_int 0)])
+ (compare:CCFP
+ (match_operand:GPF 2 "register_operand" "w")
+ (match_operand:GPF 3 "register_operand" "w"))
+ (match_operand 5 "immediate_operand")))]
+ "TARGET_FLOAT"
+ "fccmp\\t%<s>2, %<s>3, %k5, %m4"
+ [(set_attr "type" "fcmp<s>")]
+)
+
+(define_insn "fccmpe<mode>"
+ [(set (match_operand:CCFPE 1 "cc_register" "")
+ (if_then_else:CCFPE
+ (match_operator 4 "aarch64_comparison_operator"
+ [(match_operand 0 "cc_register" "")
+ (const_int 0)])
+ (compare:CCFPE
+ (match_operand:GPF 2 "register_operand" "w")
+ (match_operand:GPF 3 "register_operand" "w"))
+ (match_operand 5 "immediate_operand")))]
+ "TARGET_FLOAT"
+ "fccmpe\\t%<s>2, %<s>3, %k5, %m4"
+ [(set_attr "type" "fcmp<s>")]
+)
+
;; Expansion of signed mod by a power of 2 using CSNEG.
;; For x0 % n where n is a power of 2 produce:
;; negs x1, x0
@@ -2794,7 +2824,7 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
-(define_insn "*cmp<mode>"
+(define_insn "fcmp<mode>"
[(set (reg:CCFP CC_REGNUM)
(compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
(match_operand:GPF 1 "aarch64_fp_compare_operand"
"Y,w")))]
@@ -2805,7 +2835,7 @@
[(set_attr "type" "fcmp<s>")]
)
-(define_insn "*cmpe<mode>"
+(define_insn "fcmpe<mode>"
[(set (reg:CCFPE CC_REGNUM)
(compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
(match_operand:GPF 1 "aarch64_fp_compare_operand"
"Y,w")))]
b/gcc/testsuite/gcc.target/aarch64/ccmp_1.c
new file mode 100644
@@ -0,0 +1,84 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f1 (int a)
+{
+ return a == 17 || a == 32;
+}
+
+int
+f2 (int a)
+{
+ return a == 33 || a == 18;
+}
+
+int
+f3 (int a, int b)
+{
+ return a == 19 && b == 34;
+}
+
+int
+f4 (int a, int b)
+{
+ return a == 35 && b == 20;
+}
+
+int
+f5 (int a)
+{
+ return a == 0 || a == 5;
+}
+
+int
+f6 (int a)
+{
+ return a == 6 || a == 0;
+}
+
+int
+f7 (int a, int b)
+{
+ return a == 0 && b == 7;
+}
+
+int
+f8 (int a, int b)
+{
+ return a == 9 && b == 0;
+}
+
+int
+f9 (float a, float b)
+{
+ return a < 0.0f && a > b;
+}
+
+int
+f10 (float a, float b)
+{
+ return a == b || b == 0.0f;
+}
+
+int
+f11 (double a, int b)
+{
+ return a < 0.0f && b == 30;
+}
+
+int
+f12 (double a, int b)
+{
+ return b == 31 || a == 0.0f;
+}
+
+int
+f13 (int a, int b)
+{
+ a += b;
+ return a == 3 || a == 0;
+}
+
+/* { dg-final { scan-assembler "fccmp\t" } } */
+/* { dg-final { scan-assembler "fccmpe\t" } } */