diff --git a/gcc/ChangeLog.x32 b/gcc/ChangeLog.x32
index e41f4f5..ed72339 100644
--- a/gcc/ChangeLog.x32
+++ b/gcc/ChangeLog.x32
@@ -1,5 +1,14 @@
 2011-01-20  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR target/47381
+	* config/i386/constraints.md (Yl): New.
+
+	* config/i386/i386.md (l): New.
+	(*add<mode>_1): Replace <i> with <l>.
+	(*addsi_1_zext): Replace "lYe" with "lYl".
+
+2011-01-20  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR target/47372
 	* config/i386/i386.c (ix86_delegitimize_address): Call
 	simplify_gen_subreg for PIC with ptr_mode only if modes of
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 16caa75..e8cc202 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -109,6 +109,7 @@
 ;; We also use the Y prefix to denote constant constraints:
 ;;  s	Immediate constant for x32 store
 ;;  e	Immediate constant for x32
+;;  l	Immediate constant for lea 
 
 (define_constraint "Ys"
   "Immediate constant for x32 store."
@@ -119,7 +120,13 @@
   (if_then_else (and (match_test "TARGET_X32")
 		     (match_test "flag_pic"))
     (match_operand 0 "x86_64_immediate_operand")
-  (match_operand 0 "immediate_operand")))
+    (match_operand 0 "immediate_operand")))
+
+(define_constraint "Yl"
+  "Immediate constant for lea."
+  (if_then_else (match_test "TARGET_X32")
+    (match_operand 0 "x32_lea_immediate_operand")
+    (match_operand 0 "immediate_operand")))
 
 ;; Integer constant constraints.
 (define_constraint "I"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c8bdf86..862dd4f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -841,6 +841,9 @@
 ;; Immediate operand constraint for integer modes.
 (define_mode_attr i [(QI "n") (HI "n") (SI "Ye") (DI "e")])
 
+;; Immediate operand constraint for integer modes with lea.
+(define_mode_attr l [(QI "n") (HI "n") (SI "Yl") (DI "e")])
+
 ;; General operand constraint for word modes.
 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rmYe") (DI "rme")])
 
@@ -5690,7 +5693,7 @@
   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
 	(plus:SWI48
 	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
-	  (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
+	  (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<l>")))
    (clobber (reg:CC FLAGS_REG))]
   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
 {
@@ -5749,7 +5752,7 @@
   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
 	(zero_extend:DI
 	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
-		   (match_operand:SI 2 "x32_general_operand" "rmYe,0,lYe"))))
+		   (match_operand:SI 2 "x32_general_operand" "rmYe,0,lYl"))))
    (clobber (reg:CC FLAGS_REG))]
   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
 {
diff --git a/gcc/testsuite/ChangeLog.x32 b/gcc/testsuite/ChangeLog.x32
index 9184dbe..28b6f47 100644
--- a/gcc/testsuite/ChangeLog.x32
+++ b/gcc/testsuite/ChangeLog.x32
@@ -1,5 +1,11 @@
 2011-01-20  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR target/47381
+	* gcc.target/i386/pr47381-1.c: New.
+	* gcc.target/i386/pr47381-2.c: Likewise.
+
+2011-01-20  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR target/47372
 	* gcc.target/i386/pr47372-1.c: New.
 	* gcc.target/i386/pr47372-2.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/i386/pr47381-1.c b/gcc/testsuite/gcc.target/i386/pr47381-1.c
new file mode 100644
index 0000000..738a892
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47381-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned IPos;
+typedef unsigned char uch;
+extern uch window[];
+unsigned max_chain_length;
+unsigned strstart;
+int longest_match(IPos cur_match, int len, int best_len)
+{
+    unsigned chain_length = max_chain_length;
+    register uch *scan = window + strstart;
+    register uch *match;
+    register uch scan_end1 = scan[best_len-1];
+    register uch scan_end = scan[best_len];
+    do {
+        ;
+        match = window + cur_match;
+        if (match[best_len] != scan_end ||
+            match[best_len-1] != scan_end1 ||
+            *match != *scan ||
+            *++match != scan[1]) continue;
+            best_len = len;
+    } while ( --chain_length != 0);
+    return best_len;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr47381-2.c b/gcc/testsuite/gcc.target/i386/pr47381-2.c
new file mode 100644
index 0000000..8aa7be7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47381-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef unsigned long ulg;
+long block_start;
+typedef unsigned char uch;
+extern uch window[];
+ unsigned strstart;
+ulg flush_block (char *buf, ulg stored_len, int eof);
+ulg deflate()
+{
+    return flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : (char*)((void *)0), (long)strstart - block_start, (1));
+}
