PATCH RFC: Fix ARM bug by splitting up iwmmxt_movsi_insn

Ian Lance Taylor ian@wasabisystems.com
Mon Oct 13 08:21:00 GMT 2003


Richard Earnshaw <rearnsha@arm.com> writes:

> I think perhaps the best way to handle this is to force IF conversion to 
> fail by defining a macro that will force the conditionalization to fail 
> (for example, to make IFCVT_MODIFY_INSN return a NULL pattern for the 
> problem cases).  Another alternative is to provide the predicated version 
> of the move insn explicitly, and then to ensure that that version rejects 
> the impossible cases (the predicable attribute simply means that the code 
> generator will generate the predicated version of the pattern directly 
> from the non-predicated version).

Your alternative suggestion makes a lot of sense to me.  This patch
passes the C torture compile tests, and appears to do the right thing
with some simple test cases I constructed.  The register constraints
should tell reload how to handle the instruction.  Any thoughts?

Ian

Index: arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.141
diff -u -r1.141 arm.md
--- arm.md	7 Oct 2003 08:49:36 -0000	1.141
+++ arm.md	13 Oct 2003 07:56:23 -0000
@@ -8522,10 +8522,7 @@
 			 (match_dup 0)
 			 (match_operand 4 "" "")))
    (clobber (reg:CC CC_REGNUM))]
-  ;; Note we have to suppress this split for the iwmmxt because it
-  ;; creates a conditional movsi and the iwmmxt_movsi_insn pattern
-  ;; is not predicable.  This sucks.
-  "TARGET_ARM && reload_completed && ! TARGET_IWMMXT"
+  "TARGET_ARM && reload_completed"
   [(set (match_dup 5) (match_dup 6))
    (cond_exec (match_dup 7)
 	      (set (match_dup 0) (match_dup 4)))]
@@ -8553,10 +8550,7 @@
 			 (match_operand 4 "" "")
 			 (match_dup 0)))
    (clobber (reg:CC CC_REGNUM))]
-  ;; Note we have to suppress this split for the iwmmxt because it
-  ;; creates a conditional movsi and the iwmmxt_movsi_insn pattern
-  ;; is not predicable.  This sucks.
-  "TARGET_ARM && reload_completed && ! TARGET_IWMMXT"
+  "TARGET_ARM && reload_completed"
   [(set (match_dup 5) (match_dup 6))
    (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
 	      (set (match_dup 0) (match_dup 4)))]
@@ -8577,10 +8571,7 @@
 			 (match_operand 4 "" "")
 			 (match_operand 5 "" "")))
    (clobber (reg:CC CC_REGNUM))]
-  ;; Note we have to suppress this split for the iwmmxt because it
-  ;; creates a conditional movsi and the iwmmxt_movsi_insn pattern
-  ;; is not predicable.  This sucks.
-  "TARGET_ARM && reload_completed && ! TARGET_IWMMXT"
+  "TARGET_ARM && reload_completed"
   [(set (match_dup 6) (match_dup 7))
    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
 	      (set (match_dup 0) (match_dup 4)))
@@ -8612,10 +8603,7 @@
 			 (not:SI
 			  (match_operand:SI 5 "s_register_operand" ""))))
    (clobber (reg:CC CC_REGNUM))]
-  ;; Note we have to suppress this split for the iwmmxt because it
-  ;; creates a conditional movsi and the iwmmxt_movsi_insn pattern
-  ;; is not predicable.  This sucks.
-  "TARGET_ARM && reload_completed && ! TARGET_IWMMXT"
+  "TARGET_ARM && reload_completed"
   [(set (match_dup 6) (match_dup 7))
    (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
 	      (set (match_dup 0) (match_dup 4)))
Index: iwmmxt.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/iwmmxt.md,v
retrieving revision 1.2
diff -u -r1.2 iwmmxt.md
--- iwmmxt.md	28 Jun 2003 19:43:00 -0000	1.2
+++ iwmmxt.md	13 Oct 2003 07:56:23 -0000
@@ -124,6 +124,42 @@
    (set_attr "conds" "clob")]
 )
 
+;; Because iwmmxt_movsi_insn is not predicable, we produce the
+;; cond_exec version directly, with appropriate constraints.  This
+;; will force any predicated store of a iWMMXt general register to be
+;; done as an unconditional copy to an ARM general register followed
+;; by a predicated store to memory.
+
+(define_insn "*cond_iwmmxt_movsi_insn"
+  [(cond_exec
+     (match_operator 2 "arm_comparison_operator"
+      [(match_operand 3 "cc_register" "")
+      (const_int 0)])
+     (set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z")
+	  (match_operand:SI 1 "general_operand"      "rI,K,mi,r,r,z,m")))]
+  "TARGET_REALLY_IWMMXT
+   && (   register_operand (operands[0], SImode)
+       || register_operand (operands[1], SImode))"
+  "*
+   switch (which_alternative)
+   {
+   case 0: return \"mov%?\\t%0, %1\";
+   case 1: return \"mvn%?\\t%0, #%B1\";
+   case 2: return \"ldr%?\\t%0, %1\";
+   case 3: return \"str%?\\t%1, %0\";
+   case 4: return \"tmcr%?\\t%0, %1\";
+   case 5: return \"tmrc%?\\t%0, %1\";
+   default: return arm_output_load_gr (operands);
+  }"
+  [(set_attr "type"           "*,*,load,store1,*,*,load")
+   (set_attr "length"         "*,*,*,        *,*,*,  16")
+   (set_attr "pool_range"     "*,*,4096,     *,*,*,1024")
+   (set_attr "neg_pool_range" "*,*,4084,     *,*,*,   *")
+   ;; We don't want to predicate this instruction, as it is already
+   ;; predicated.
+   (set_attr "predicable"     "no")]
+)
+
 (define_insn "movv8qi_internal"
   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
 	(match_operand:V8QI 1 "general_operand"       "y,y,m,y,r,i"))]



More information about the Gcc-patches mailing list