+2013-09-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_select_cc_mode): Return CC_SWP for
+ comparison with negated operand.
+ * config/aarch64/aarch64.md (compare_neg<mode>): Match canonical RTL form.
+
2013-09-09 Richard Biener <rguenther@suse.de>
PR middle-end/58326
|| GET_CODE (x) == NEG))
return CC_NZmode;
- /* A compare with a shifted operand. Because of canonicalization,
+ /* A compare with a shifted or negated operand. Because of canonicalization,
the comparison will have to be swapped when we emit the assembly
code. */
if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
&& (GET_CODE (y) == REG || GET_CODE (y) == SUBREG)
&& (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
|| GET_CODE (x) == LSHIFTRT
- || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND))
+ || GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND
+ || GET_CODE (x) == NEG))
return CC_SWPmode;
/* A compare of a mode narrower than SI mode against zero can be done
)
(define_insn "*compare_neg<mode>"
- [(set (reg:CC CC_REGNUM)
- (compare:CC
- (match_operand:GPI 0 "register_operand" "r")
- (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
+ [(set (reg:CC_SWP CC_REGNUM)
+ (compare:CC_SWP
+ (neg:GPI (match_operand:GPI 0 "register_operand" "r"))
+ (match_operand:GPI 1 "register_operand" "r")))]
""
- "cmn\\t%<w>0, %<w>1"
+ "cmn\\t%<w>1, %<w>0"
[(set_attr "v8type" "alus")
(set_attr "type" "alus_reg")
(set_attr "mode" "<MODE>")]
+2013-09-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/cmn-neg.c: New test.
+
2013-09-09 Richard Biener <rguenther@suse.de>
PR middle-end/58326
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+extern void abort (void);
+
+void __attribute__ ((noinline))
+foo_s32 (int a, int b)
+{
+ if (a < -b)
+ abort ();
+}
+/* { dg-final { scan-assembler "cmn\tw\[0-9\]" } } */
+
+void __attribute__ ((noinline))
+foo_s64 (long long a, long long b)
+{
+ if (a < -b)
+ abort ();
+}
+/* { dg-final { scan-assembler "cmn\tx\[0-9\]" } } */
+
+
+int
+main (void)
+{
+ int a = 30;
+ int b = 42;
+ foo_s32 (a, b);
+ foo_s64 (a, b);
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */