Patchwork backport ARM movw fix to 4.4 to fix PR44626 ice-on-valid-code

login
register
mail settings
Submitter Mikael Pettersson
Date July 4, 2010, 7:53 p.m.
Message ID <19504.59044.331449.610462@pilspetsen.it.uu.se>
Download mbox | patch
Permalink /patch/57850/
State New
Headers show

Comments

Mikael Pettersson - July 4, 2010, 7:53 p.m.
PR44626 is an ice-on-valid-code regression affecting ARM in gcc-4.4.

The ICE was fixed for 4.5 by Nathan Sidwell's "[ARM] movw fix"
<http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01358.html> a year ago.
At the time he could not present a test case for mainline.

Well, now there is one (a big one) in PR44626.

This patch backports Nathan's movw fix to 4.4, and has been
confirmed to fix the ice.

Bootstrapped and regtested on armv5tel-unknown-linux-gnueabi
with no regressions.

Ok for 4.4? (I don't have svn write access.)

/Mikael

gcc/

2010-07-04  Mikael Pettersson  <mikpe@it.uu.se>

	PR target/44626

	Backport from mainline:
	2009-06-22  Nathan Sidwell  <nathan@codesourcery.com>

	* config/arm/arm.c (arm_print_operand): Deal with HIGH.
	* config/arm/constraints.md (j): New constraint for movw operands.
	(N): Remove thumb2 meaning.
	* config/arm/arm.md (*arm_movw): Delete.
	(*arm_movsi_insn): Use j constraint for movw instead of N constraint.
	* config/arm/vfp.md (*arm_movsi_vfp, *thumb2_movsi_vfp): Likewise.
	* config/arm/thumb2.md (*thumb2_movsi_insn): Likewise.

Patch

--- gcc-4.4-20100615/gcc/config/arm/arm.c.~1~	2010-02-18 14:13:03.000000000 +0100
+++ gcc-4.4-20100615/gcc/config/arm/arm.c	2010-06-22 19:56:24.000000000 +0200
@@ -13863,6 +13863,12 @@  arm_print_operand (FILE *stream, rtx x, 
 	default:
 	  gcc_assert (GET_CODE (x) != NEG);
 	  fputc ('#', stream);
+	  if (GET_CODE (x) == HIGH)
+	    {
+	      fputs (":lower16:", stream);
+	      x = XEXP (x, 0);
+	    }
+	    
 	  output_addr_const (stream, x);
 	  break;
 	}
--- gcc-4.4-20100615/gcc/config/arm/arm.md.~1~	2010-02-18 14:13:03.000000000 +0100
+++ gcc-4.4-20100615/gcc/config/arm/arm.md	2010-06-22 19:56:24.000000000 +0200
@@ -4984,18 +4984,9 @@ 
    (set_attr "length" "4")]
 )
 
-(define_insn "*arm_movw"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
-	(high:SI (match_operand:SI 1 "general_operand"      "i")))]
-  "TARGET_32BIT"
-  "movw%?\t%0, #:lower16:%c1"
-  [(set_attr "predicable" "yes")
-   (set_attr "length" "4")]
-)
-
 (define_insn "*arm_movsi_insn"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
-	(match_operand:SI 1 "general_operand"      "rk, I,K,N,mi,rk"))]
+	(match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,rk"))]
   "TARGET_ARM && ! TARGET_IWMMXT
    && !(TARGET_HARD_FLOAT && TARGET_VFP)
    && (   register_operand (operands[0], SImode)
--- gcc-4.4-20100615/gcc/config/arm/constraints.md.~1~	2010-02-17 17:16:16.000000000 +0100
+++ gcc-4.4-20100615/gcc/config/arm/constraints.md	2010-06-22 19:56:24.000000000 +0200
@@ -25,7 +25,7 @@ 
 ;; In ARM state, 'l' is an alias for 'r'
 
 ;; The following normal constraints have been used:
-;; in ARM/Thumb-2 state: G, H, I, J, K, L, M
+;; in ARM/Thumb-2 state: G, H, I, j, J, K, L, M
 ;; in Thumb-1 state: I, J, K, L, M, N, O
 
 ;; The following multi-letter normal constraints have been used:
@@ -66,6 +66,13 @@ 
 (define_register_constraint "h" "TARGET_THUMB ? HI_REGS : NO_REGS"
  "In Thumb state the core registers @code{r8}-@code{r15}.")
 
+(define_constraint "j"
+ "A constant suitable for a MOVW instruction. (ARM/Thumb-2)"
+ (and (match_test "TARGET_32BIT && arm_arch_thumb2")
+      (ior (match_code "high")
+	   (and (match_code "const_int")
+                (match_test "(ival & 0xffff0000) == 0")))))
+
 (define_register_constraint "k" "STACK_REG"
  "@internal The stack register.")
 
@@ -117,11 +124,9 @@ 
 		   : ((ival >= 0 && ival <= 1020) && ((ival & 3) == 0))")))
 
 (define_constraint "N"
- "In ARM/Thumb-2 state a constant suitable for a MOVW instruction.
-  In Thumb-1 state a constant in the range 0-31."
+ "Thumb-1 state a constant in the range 0-31."
  (and (match_code "const_int")
-      (match_test "TARGET_32BIT ? arm_arch_thumb2 && ((ival & 0xffff0000) == 0)
-				: (ival >= 0 && ival <= 31)")))
+      (match_test "!TARGET_32BIT && (ival >= 0 && ival <= 31)")))
 
 (define_constraint "O"
  "In Thumb-1 state a constant that is a multiple of 4 in the range
--- gcc-4.4-20100615/gcc/config/arm/thumb2.md.~1~	2010-02-24 15:50:43.000000000 +0100
+++ gcc-4.4-20100615/gcc/config/arm/thumb2.md	2010-06-22 19:56:24.000000000 +0200
@@ -225,7 +225,7 @@ 
 
 (define_insn "*thumb2_movsi_insn"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
-	(match_operand:SI 1 "general_operand"	   "rk ,I,K,N,mi,rk"))]
+	(match_operand:SI 1 "general_operand"	   "rk ,I,K,j,mi,rk"))]
   "TARGET_THUMB2 && ! TARGET_IWMMXT
    && !(TARGET_HARD_FLOAT && TARGET_VFP)
    && (   register_operand (operands[0], SImode)
--- gcc-4.4-20100615/gcc/config/arm/vfp.md.~1~	2008-09-01 15:40:49.000000000 +0200
+++ gcc-4.4-20100615/gcc/config/arm/vfp.md	2010-06-22 19:56:24.000000000 +0200
@@ -51,7 +51,7 @@ 
 ;; problems because small constants get converted into adds.
 (define_insn "*arm_movsi_vfp"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
-      (match_operand:SI 1 "general_operand"	   "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
+      (match_operand:SI 1 "general_operand"	   "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
   "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
    && (   s_register_operand (operands[0], SImode)
        || s_register_operand (operands[1], SImode))"
@@ -88,7 +88,7 @@ 
 
 (define_insn "*thumb2_movsi_vfp"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
-      (match_operand:SI 1 "general_operand"	   "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
+      (match_operand:SI 1 "general_operand"	   "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
   "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
    && (   s_register_operand (operands[0], SImode)
        || s_register_operand (operands[1], SImode))"