Patchwork [ARM] Fix ICE when using Neon vld1_dup_[su]64()

login
register
mail settings
Submitter Richard Earnshaw
Date Aug. 8, 2013, 1:49 p.m.
Message ID <5203A201.7040905@arm.com>
Download mbox | patch
Permalink /patch/265733/
State New
Headers show

Comments

Richard Earnshaw - Aug. 8, 2013, 1:49 p.m.
PR 57431 is an ICE when compiling for Neon intrinsics.  For completeness
vld1_dup_u64 is defined to fill a single element vector from a single
element of data, but this is in reality degenerate.
Unfortunately, by expanding this into a vec_duplicate operation we
confuse the mid-end of the compiler, since it expects a vector mode to
result from the duplicate operation.

The fix is to special-case the expand into the appropriate direct load
operation and to then simplify the logic for the remaining cases (which
now really are all duplicate operations).

	PR target/57431
	* arm/neon.md (neon_vld1_dupdi): New expand pattern.
	(neon_vld1_dup<mode> VD iterator): Iterate over VD not VDX.

R.

Patch

--- neon.md	(revision 201427)
+++ neon.md	(local)
@@ -4593,19 +4593,20 @@  (define_insn "neon_vld1_lane<mode>"
 )
 
 (define_insn "neon_vld1_dup<mode>"
-  [(set (match_operand:VDX 0 "s_register_operand" "=w")
-        (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
+  [(set (match_operand:VD 0 "s_register_operand" "=w")
+        (vec_duplicate:VD (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
   "TARGET_NEON"
-{
-  if (GET_MODE_NUNITS (<MODE>mode) > 1)
-    return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
-  else
-    return "vld1.<V_sz_elem>\t%h0, %A1";
-}
-  [(set (attr "neon_type")
-      (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
-                    (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
-                    (const_string "neon_vld1_1_2_regs")))]
+  "vld1.<V_sz_elem>\t{%P0[]}, %A1"
+  [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
+)
+
+;; Special case for DImode.  Treat it exactly like a simple load.
+(define_expand "neon_vld1_dupdi"
+  [(set (match_operand:DI 0 "s_register_operand" "")
+        (unspec:DI [(match_operand:DI 1 "neon_struct_operand" "")]
+		   UNSPEC_VLD1))]
+  "TARGET_NEON"
+  ""
 )
 
 (define_insn "neon_vld1_dup<mode>"