This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][ARM] Set "conds" attribute for non-predicable ARMv8-A instructions


Hi all,

Some ARMv8-A instructions in the vrint* family as well as the vmaxnm and vminnm ones do not have a conditional variant and have therefore their "predicable" attribute set to "no". However we've discovered that they can still end up conditionalised in some cases because of the arm_cond_branch pattern that can remove a conditional and conditionalise the next instruction, unless the "conds" attribute forbids it. To prevent this happeninf with the vrint and vmaxnm, vminnm instructions, this patch sets the "conds" attribute to "unconditional".

This was caught in a testcase where the vrinta instruction ended up being conditionalised (producing vrintagt) which thankfully the assembler caught and complained. If this had happened on the smin/smax patterns that don't have a '%?' in their output template, we would have ended silently miscompiling!

This should go into trunk and the 4.8 branch.

Tested arm-none-eabi on a model.

Ok?

Thanks,
Kyrill

2013-11-28  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * config/arm/iterators.md (vrint_conds): New int attribute.
    * config/arm/vfp.md (<vrint_pattern><SDF:mode>2): Set conds attribute.
    (smax<mode>3): Likewise.
    (smin<mode>3): Likewise.

2013-11-28  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * gcc.target/arm/vrinta-ce.c: New testcase.
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index db1634b..dc4cf0d 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -525,6 +525,10 @@
                                   (UNSPEC_VRINTA "no") (UNSPEC_VRINTM "no")
                                   (UNSPEC_VRINTR "yes") (UNSPEC_VRINTX "yes")])
 
+(define_int_attr vrint_conds [(UNSPEC_VRINTZ "nocond") (UNSPEC_VRINTP "unconditional")
+                              (UNSPEC_VRINTA "unconditional") (UNSPEC_VRINTM "unconditional")
+                              (UNSPEC_VRINTR "nocond") (UNSPEC_VRINTX "nocond")])
+
 (define_int_attr nvrint_variant [(UNSPEC_NVRINTZ "z") (UNSPEC_NVRINTP "p")
                                 (UNSPEC_NVRINTA "a") (UNSPEC_NVRINTM "m")
                                 (UNSPEC_NVRINTX "x") (UNSPEC_NVRINTN "n")])
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 22b6325..6d0515a 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -1277,7 +1277,8 @@
   "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
   [(set_attr "predicable" "<vrint_predicable>")
    (set_attr "predicable_short_it" "no")
-   (set_attr "type" "f_rint<vfp_type>")]
+   (set_attr "type" "f_rint<vfp_type>")
+   (set_attr "conds" "<vrint_conds>")]
 )
 
 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
@@ -1293,7 +1294,8 @@
 		  (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
   "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
-  [(set_attr "type" "f_minmax<vfp_type>")]
+  [(set_attr "type" "f_minmax<vfp_type>")
+   (set_attr "conds" "unconditional")]
 )
 
 (define_insn "smin<mode>3"
@@ -1302,7 +1304,8 @@
 		  (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
   "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
-  [(set_attr "type" "f_minmax<vfp_type>")]
+  [(set_attr "type" "f_minmax<vfp_type>")
+   (set_attr "conds" "unconditional")]
 )
 
 ;; Unimplemented insns:
diff --git a/gcc/testsuite/gcc.target/arm/vrinta-ce.c b/gcc/testsuite/gcc.target/arm/vrinta-ce.c
new file mode 100644
index 0000000..71c5b3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/vrinta-ce.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_v8_vfp_ok } */
+/* { dg-options "-O2 -marm -march=armv8-a" } */
+/* { dg-add-options arm_v8_vfp } */
+
+double foo (double a)
+{
+  if (a > 3.0)
+    return  __builtin_round (a);
+
+  return 0.0;
+}
+
+/* { dg-final { scan-assembler-times "vrinta.f64\td\[0-9\]+" 1 } } */
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]