On Sat, Jul 23, 2011 at 2:38 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Fri, Jul 22, 2011 at 9:03 PM, H.J. Lu <hongjiu...@intel.com> wrote: > >> This patch adds x32 LEA insn support. The main issue is >> >> gen_lowpart (Pmode, operands[1]); >> >> doesn't work on symbol. This patch avoids it. >> >> Also we shouldn't generate 32bit store with x32 PIC source. >> >> Any comments? > > Can you please post some testcases to see the effect of the patch? > > Thanks, > Uros. >
Here is the updated patch with 3 testcases -- H.J. --- gcc/ 2011-07-22 H.J. Lu <hongjiu...@intel.com> PR target/47381 * config/i386/constraints.md (Ys): Rewritten. (Ye): Updated. (Yl): Likewise. * config/i386/constraints.md (i): Replace "i" with "Ye". (l): New. (g): Replace "g" with "rmYe". (general_operand): Replace general_operand with with si_general_operand on SI. (general_szext_operand): Likewise. (*movsi_internal): Replace "i" with "Ys". (*add<mode>_1): Replace <i> with <l>. (addsi_1_zext): Replace general_operand with si_general_operand and "g" with "rmYe". (*addsi_2_zext): Likewise. (*subsi_1_zext): Likewise. (*subsi_2_zext): Likewise. (*subsi_3_zext): Likewise. (*addsi3_carry_zext): Likewise. (*subsi3_carry_zext): Likewise. (*andsi_1): Likewise. (*andsi_1_zext): Likewise. (*andsi_2_zext): Likewise. (LEA split): Replace nonmemory_operand with si_lea_nonmemory_operand and "i" with "Ye". (*lea_general_2): Likewise. (*lea_general_2_zext): Likewise. (*lea_general_1): Replace immediate_operand with si_lea_immediate_operand and "i" with "Ye". (*lea_general_1_zext): Likewise. (*lea_general_3): Likewise. (*lea_general_3_zext): Likewise. config/i386/predicates.md (si_general_operand): New. (si_lea_immediate_operand): Likewise. (si_lea_nonmemory_operand): Likewise. gcc/testsuite/ 2011-07-22 H.J. Lu <hongjiu...@intel.com> PR target/47381 * gcc.target/i386/pr47381-1.c: New. * gcc.target/i386/pr47381-2.c: Likewise. * gcc.target/i386/pr47381-3.c: Likewise.
gcc/ 2011-07-22 H.J. Lu <hongjiu...@intel.com> PR target/47381 * config/i386/constraints.md (Ys): Rewritten. (Ye): Updated. (Yl): Likewise. * config/i386/constraints.md (i): Replace "i" with "Ye". (l): New. (g): Replace "g" with "rmYe". (general_operand): Replace general_operand with with si_general_operand on SI. (general_szext_operand): Likewise. (*movsi_internal): Replace "i" with "Ys". (*add<mode>_1): Replace <i> with <l>. (addsi_1_zext): Replace general_operand with si_general_operand and "g" with "rmYe". (*addsi_2_zext): Likewise. (*subsi_1_zext): Likewise. (*subsi_2_zext): Likewise. (*subsi_3_zext): Likewise. (*addsi3_carry_zext): Likewise. (*subsi3_carry_zext): Likewise. (*andsi_1): Likewise. (*andsi_1_zext): Likewise. (*andsi_2_zext): Likewise. (LEA split): Replace nonmemory_operand with si_lea_nonmemory_operand and "i" with "Ye". (*lea_general_2): Likewise. (*lea_general_2_zext): Likewise. (*lea_general_1): Replace immediate_operand with si_lea_immediate_operand and "i" with "Ye". (*lea_general_1_zext): Likewise. (*lea_general_3): Likewise. (*lea_general_3_zext): Likewise. config/i386/predicates.md (si_general_operand): New. (si_lea_immediate_operand): Likewise. (si_lea_nonmemory_operand): Likewise. gcc/testsuite/ 2011-07-22 H.J. Lu <hongjiu...@intel.com> PR target/47381 * gcc.target/i386/pr47381-1.c: New. * gcc.target/i386/pr47381-2.c: Likewise. * gcc.target/i386/pr47381-3.c: Likewise. diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 8d3e45a..a5d54a1 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -123,6 +123,31 @@ "optimize_function_for_speed_p (cfun) ? GENERAL_REGS : NO_REGS" "@internal Any integer register when integer XFmode moves are enabled.") +;; Constant constraints. +;; We also use the Y prefix to denote constant constraints: +;; s Immediate constant source operand for store +;; e Immediate constant for SImode +;; l Immediate constant for lea + +(define_constraint "Ys" + "@internal Immediate constant source operand for store." + (and (match_operand 0 "immediate_operand") + (ior (match_test "!TARGET_X32") + (not (match_operand 0 "pic_32bit_operand"))))) + +(define_constraint "Ye" + "@internal Immediate constant for SImode." + (if_then_else (and (match_test "TARGET_X32") + (match_test "flag_pic")) + (match_operand 0 "x86_64_immediate_operand") + (match_operand 0 "immediate_operand"))) + +(define_constraint "Yl" + "@internal Immediate constant for lea." + (if_then_else (match_test "TARGET_X32") + (match_operand 0 "si_lea_immediate_operand") + (match_operand 0 "immediate_operand"))) + (define_constraint "z" "@internal Constant call address operand." (match_operand 0 "constant_call_address_operand")) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index b704fa7..02b6fd6 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -861,10 +861,13 @@ (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) ;; Immediate operand constraint for integer modes. -(define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")]) +(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 "g") (DI "rme")]) +(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rmYe") (DI "rme")]) ;; Immediate operand constraint for double integer modes. (define_mode_attr di [(SI "iF") (DI "e")]) @@ -876,7 +879,7 @@ (define_mode_attr general_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "si_general_operand") (DI "x86_64_general_operand") (TI "x86_64_general_operand")]) @@ -884,7 +887,7 @@ (define_mode_attr general_szext_operand [(QI "general_operand") (HI "general_operand") - (SI "general_operand") + (SI "si_general_operand") (DI "x86_64_szext_general_operand")]) ;; Immediate operand predicate for integer modes. @@ -2180,11 +2198,13 @@ [(const_int 0)] "ix86_split_long_move (operands); DONE;") +;; Use "Ys" constraint to disallow store with X32 PIC operand as +;; immediate. (define_insn "*movsi_internal" [(set (match_operand:SI 0 "nonimmediate_operand" - "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") + "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x") (match_operand:SI 1 "general_operand" - "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] + "g ,rYs,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))] "!(MEM_P (operands[0]) && MEM_P (operands[1]))" { switch (get_attr_type (insn)) @@ -5453,7 +5473,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)" { @@ -5512,7 +5532,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 "general_operand" "g,0,li")))) + (match_operand:SI 2 "si_general_operand" "rmYe,0,lYl")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" { @@ -5844,7 +5864,7 @@ [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))) + (match_operand:SI 2 "si_lea_nonmemory_operand" "")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" @@ -5901,7 +5921,7 @@ [(set (reg FLAGS_REG) (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] @@ -6240,7 +6260,7 @@ [(set (match_operand 0 "register_operand" "=r") (plus (plus (match_operand 1 "index_register_operand" "l") (match_operand 2 "register_operand" "r")) - (match_operand 3 "immediate_operand" "i")))] + (match_operand 3 "si_lea_immediate_operand" "Ye")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) @@ -6273,7 +6293,7 @@ (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") (match_operand:SI 2 "register_operand" "r")) - (match_operand:SI 3 "immediate_operand" "i"))))] + (match_operand:SI 3 "si_lea_immediate_operand" "Ye"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6293,7 +6313,7 @@ [(set (match_operand 0 "register_operand" "=r") (plus (mult (match_operand 1 "index_register_operand" "l") (match_operand 2 "const248_operand" "i")) - (match_operand 3 "nonmemory_operand" "ri")))] + (match_operand 3 "si_lea_nonmemory_operand" "rYe")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL @@ -6326,7 +6346,7 @@ (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") (match_operand:SI 2 "const248_operand" "n")) - (match_operand:SI 3 "nonmemory_operand" "ri"))))] + (match_operand:SI 3 "si_lea_nonmemory_operand" "rYe"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6346,7 +6366,7 @@ (plus (plus (mult (match_operand 1 "index_register_operand" "l") (match_operand 2 "const248_operand" "i")) (match_operand 3 "register_operand" "r")) - (match_operand 4 "immediate_operand" "i")))] + (match_operand 4 "si_lea_immediate_operand" "Ye")))] "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) && (!TARGET_PARTIAL_REG_STALL @@ -6384,7 +6404,7 @@ (match_operand:SI 1 "index_register_operand" "l") (match_operand:SI 2 "const248_operand" "n")) (match_operand:SI 3 "register_operand" "r")) - (match_operand:SI 4 "immediate_operand" "i"))))] + (match_operand:SI 4 "si_lea_immediate_operand" "Ye"))))] "TARGET_64BIT" "#" "&& reload_completed" @@ -6481,7 +6501,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g")))) + (match_operand:SI 2 "si_general_operand" "rmYe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sub{l}\t{%2, %k0|%k0, %2}" @@ -6518,7 +6538,7 @@ [(set (reg FLAGS_REG) (compare (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI @@ -6545,7 +6565,7 @@ (define_insn "*subsi_3_zext" [(set (reg FLAGS_REG) (compare (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "g"))) + (match_operand:SI 2 "si_general_operand" "rmYe"))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (minus:SI (match_dup 1) @@ -6592,7 +6612,7 @@ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") (plus:SI (match_operator 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) - (match_operand:SI 2 "general_operand" "g"))))) + (match_operand:SI 2 "si_general_operand" "rmYe"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" "adc{l}\t{%2, %k0|%k0, %2}" @@ -6607,7 +6627,7 @@ (minus:SI (match_operand:SI 1 "register_operand" "0") (plus:SI (match_operator 3 "ix86_carry_flag_operator" [(reg FLAGS_REG) (const_int 0)]) - (match_operand:SI 2 "general_operand" "g"))))) + (match_operand:SI 2 "si_general_operand" "rmYe"))))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" "sbb{l}\t{%2, %k0|%k0, %2}" @@ -7730,7 +7750,7 @@ (define_insn "*andsi_1" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") - (match_operand:SI 2 "general_operand" "ri,rm,L"))) + (match_operand:SI 2 "si_general_operand" "rYe,rm,L"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, SImode, operands)" { @@ -7777,7 +7797,7 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")))) + (match_operand:SI 2 "si_general_operand" "rmYe")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" "and{l}\t{%2, %k0|%k0, %2}" @@ -7940,7 +7960,7 @@ [(set (reg FLAGS_REG) (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") - (match_operand:SI 2 "general_operand" "g")) + (match_operand:SI 2 "si_general_operand" "rmYe")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 2ef9129..267136a 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1188,3 +1198,24 @@ return false; return true; }) + +;; Test for a valid general operand for SImode. +(define_predicate "si_general_operand" + (if_then_else (and (match_test "TARGET_X32") + (match_test "flag_pic")) + (match_operand 0 "x86_64_general_operand") + (match_operand 0 "general_operand"))) + +;; Test for a valid immediate operand for lea in SImode. +(define_predicate "si_lea_immediate_operand" + (and (match_operand 0 "immediate_operand") + (ior (match_test "!TARGET_X32") + (match_test "GET_MODE (op) != SImode") + (match_test "!SYMBOLIC_CONST (op)")))) + +;; Test for a valid nonmemory operand for lea in SImode. +(define_predicate "si_lea_nonmemory_operand" + (and (match_operand 0 "nonmemory_operand") + (ior (match_test "!TARGET_X32") + (match_test "GET_MODE (op) != SImode") + (match_test "!SYMBOLIC_CONST (op)")))) 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)); +} diff --git a/gcc/testsuite/gcc.target/i386/pr47381-3.c b/gcc/testsuite/gcc.target/i386/pr47381-3.c new file mode 100644 index 0000000..c4b2127 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr47381-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=atom" } */ + +struct foo_t { + int limit; +} foo[3]; +void +bar () { + int i; + for (i = 0; i < 3; i++) { + __builtin_memset (&foo[i], 0, sizeof(*foo)); + } +}