Commit 006ba504 by Ilya Enkovich Committed by Ilya Enkovich

re PR target/65105 ([i386] XMM registers are not used for 64bit computations on 32bit target)

gcc/

	PR target/65105
	* config/i386/i386.c: Include dbgcnt.h.
	(has_non_address_hard_reg): New.
	(convertible_comparison_p): New.
	(scalar_to_vector_candidate_p): New.
	(remove_non_convertible_regs): New.
	(scalar_chain): New.
	(scalar_chain::scalar_chain): New.
	(scalar_chain::~scalar_chain): New.
	(scalar_chain::add_to_queue): New.
	(scalar_chain::mark_dual_mode_def): New.
	(scalar_chain::analyze_register_chain): New.
	(scalar_chain::add_insn): New.
	(scalar_chain::build): New.
	(scalar_chain::compute_convert_gain): New.
	(scalar_chain::replace_with_subreg): New.
	(scalar_chain::replace_with_subreg_in_insn): New.
	(scalar_chain::emit_conversion_insns): New.
	(scalar_chain::make_vector_copies): New.
	(scalar_chain::convert_reg): New.
	(scalar_chain::convert_op): New.
	(scalar_chain::convert_insn): New.
	(scalar_chain::convert): New.
	(convert_scalars_to_vector): New.
	(pass_data_stv): New.
	(pass_stv): New.
	(make_pass_stv): New.
	(ix86_option_override): Created and register stv pass.
	(flag_opts): Add -mstv.
	(ix86_option_override_internal): Likewise.
	* config/i386/i386.md (SWIM1248x): New.
	(*movdi_internal): Add xmm to mem alternative for TARGET_STV.
	(and<mode>3): Use SWIM1248x iterator instead of SWIM.
	(*anddi3_doubleword): New.
	(*zext<mode>_doubleword): New.
	(*zextsi_doubleword): New.
	(<code><mode>3): Use SWIM1248x iterator instead of SWIM.
	(*<code>di3_doubleword): New.
	* config/i386/i386.opt (mstv): New.
	* dbgcnt.def (stv_conversion): New.

gcc/testsuite/

	PR target/65105
	* gcc.target/i386/pr65105-1.c: New.
	* gcc.target/i386/pr65105-2.c: New.
	* gcc.target/i386/pr65105-3.c: New.
	* gcc.target/i386/pr65105-4.C: New.
	* gcc.dg/lower-subreg-1.c: Add -mno-stv options for ia32.

From-SVN: r228231
parent 2943f6f7
2015-09-29 Ilya Enkovich <enkovich.gnu@gmail.com>
PR target/65105
* config/i386/i386.c: Include dbgcnt.h.
(has_non_address_hard_reg): New.
(convertible_comparison_p): New.
(scalar_to_vector_candidate_p): New.
(remove_non_convertible_regs): New.
(scalar_chain): New.
(scalar_chain::scalar_chain): New.
(scalar_chain::~scalar_chain): New.
(scalar_chain::add_to_queue): New.
(scalar_chain::mark_dual_mode_def): New.
(scalar_chain::analyze_register_chain): New.
(scalar_chain::add_insn): New.
(scalar_chain::build): New.
(scalar_chain::compute_convert_gain): New.
(scalar_chain::replace_with_subreg): New.
(scalar_chain::replace_with_subreg_in_insn): New.
(scalar_chain::emit_conversion_insns): New.
(scalar_chain::make_vector_copies): New.
(scalar_chain::convert_reg): New.
(scalar_chain::convert_op): New.
(scalar_chain::convert_insn): New.
(scalar_chain::convert): New.
(convert_scalars_to_vector): New.
(pass_data_stv): New.
(pass_stv): New.
(make_pass_stv): New.
(ix86_option_override): Created and register stv pass.
(flag_opts): Add -mstv.
(ix86_option_override_internal): Likewise.
* config/i386/i386.md (SWIM1248x): New.
(*movdi_internal): Add xmm to mem alternative for TARGET_STV.
(and<mode>3): Use SWIM1248x iterator instead of SWIM.
(*anddi3_doubleword): New.
(*zext<mode>_doubleword): New.
(*zextsi_doubleword): New.
(<code><mode>3): Use SWIM1248x iterator instead of SWIM.
(*<code>di3_doubleword): New.
* config/i386/i386.opt (mstv): New.
* dbgcnt.def (stv_conversion): New.
2015-09-29 Tom de Vries <tom@codesourcery.com>
* tree-cfg.c (dump_function_to_file): Dump function attributes.
......@@ -981,6 +981,11 @@
(HI "TARGET_HIMODE_MATH")
SI])
;; Math-dependant integer modes with DImode.
(define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
(HI "TARGET_HIMODE_MATH")
SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
;; Math-dependant single word integer modes without QImode.
(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
SI (DI "TARGET_64BIT")])
......@@ -2097,9 +2102,9 @@
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
"=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
"=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
(match_operand:DI 1 "general_operand"
"riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
"riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
......@@ -2177,9 +2182,9 @@
[(set (attr "isa")
(cond [(eq_attr "alternative" "0,1")
(const_string "nox64")
(eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
(eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
(const_string "x64")
(eq_attr "alternative" "17")
(eq_attr "alternative" "18")
(const_string "x64_sse4")
]
(const_string "*")))
......@@ -2190,13 +2195,13 @@
(const_string "mmx")
(eq_attr "alternative" "7,8,9,10,11")
(const_string "mmxmov")
(eq_attr "alternative" "12,17")
(eq_attr "alternative" "12,18")
(const_string "sselog1")
(eq_attr "alternative" "13,14,15,16,18")
(eq_attr "alternative" "13,14,15,16,17,19")
(const_string "ssemov")
(eq_attr "alternative" "19,20")
(eq_attr "alternative" "20,21")
(const_string "ssecvt")
(eq_attr "alternative" "21,22,23,24")
(eq_attr "alternative" "22,23,24,25")
(const_string "mskmov")
(and (match_operand 0 "register_operand")
(match_operand 1 "pic_32bit_operand"))
......@@ -2211,16 +2216,16 @@
(set (attr "length_immediate")
(cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
(const_string "8")
(eq_attr "alternative" "17")
(eq_attr "alternative" "18")
(const_string "1")
]
(const_string "*")))
(set (attr "prefix_rex")
(if_then_else (eq_attr "alternative" "10,11,16,17,18")
(if_then_else (eq_attr "alternative" "10,11,17,18,19")
(const_string "1")
(const_string "*")))
(set (attr "prefix_extra")
(if_then_else (eq_attr "alternative" "17")
(if_then_else (eq_attr "alternative" "18")
(const_string "1")
(const_string "*")))
(set (attr "prefix")
......@@ -2248,13 +2253,26 @@
]
(const_string "TI"))
(and (eq_attr "alternative" "14,15")
(and (eq_attr "alternative" "14,15,16")
(not (match_test "TARGET_SSE2")))
(const_string "V2SF")
(eq_attr "alternative" "17")
(eq_attr "alternative" "18")
(const_string "TI")
]
(const_string "DI")))])
(const_string "DI")))
(set (attr "enabled")
(cond [(eq_attr "alternative" "15")
(if_then_else
(match_test "TARGET_STV && TARGET_SSE2")
(symbol_ref "false")
(const_string "*"))
(eq_attr "alternative" "16")
(if_then_else
(match_test "TARGET_STV && TARGET_SSE2")
(symbol_ref "true")
(symbol_ref "false"))
]
(const_string "*")))])
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand")
......@@ -3815,6 +3833,26 @@
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
(define_insn_and_split "*zext<mode>_doubleword"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
"!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
"#"
"&& reload_completed && GENERAL_REG_P (operands[0])"
[(set (match_dup 0) (zero_extend:SI (match_dup 1)))
(set (match_dup 2) (const_int 0))]
"split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
(define_insn_and_split "*zextsi_doubleword"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
"!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
"#"
"&& reload_completed && GENERAL_REG_P (operands[0])"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2) (const_int 0))]
"split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
;; Sign extension instructions
(define_expand "extendsidi2"
......@@ -7863,9 +7901,9 @@
;; it should be done with splitters.
(define_expand "and<mode>3"
[(set (match_operand:SWIM 0 "nonimmediate_operand")
(and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
(match_operand:SWIM 2 "<general_szext_operand>")))]
[(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
(and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
(match_operand:SWIM1248x 2 "<general_szext_operand>")))]
""
{
machine_mode mode = <MODE>mode;
......@@ -7943,6 +7981,23 @@
(const_string "*")))
(set_attr "mode" "SI,DI,DI,SI,DI")])
(define_insn_and_split "*anddi3_doubleword"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
(and:DI
(match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (AND, DImode, operands)"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
(and:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])
(parallel [(set (match_dup 3)
(and:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])]
"split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*andsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
......@@ -8430,9 +8485,9 @@
;; If this is considered useful, it should be done with splitters.
(define_expand "<code><mode>3"
[(set (match_operand:SWIM 0 "nonimmediate_operand")
(any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
(match_operand:SWIM 2 "<general_operand>")))]
[(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
(any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
(match_operand:SWIM1248x 2 "<general_operand>")))]
""
"ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
......@@ -8450,6 +8505,23 @@
[(set_attr "type" "alu,alu,msklog")
(set_attr "mode" "<MODE>")])
(define_insn_and_split "*<code>di3_doubleword"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
(any_or:DI
(match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
(clobber (reg:CC FLAGS_REG))]
"!TARGET_64BIT && TARGET_STV && TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
(any_or:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])
(parallel [(set (match_dup 3)
(any_or:SI (match_dup 4) (match_dup 5)))
(clobber (reg:CC FLAGS_REG))])]
"split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
(define_insn "*<code>hi_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
(any_or:HI
......
......@@ -567,6 +567,11 @@ Target Report Mask(VZEROUPPER) Save
Generate vzeroupper instruction before a transfer of control flow out of
the function.
mstv
Target Report Mask(STV) Save
Disable Scalar to Vector optimization pass transforming 64-bit integer
computations into a vector ones.
mdispatch-scheduler
Target RejectNegative Var(flag_dispatch_scheduler)
Do dispatch scheduling if processor is bdver1 or bdver2 or bdver3 or bdver4 and Haifa scheduling
......
......@@ -186,6 +186,7 @@ DEBUG_COUNTER (sel_sched_region_cnt)
DEBUG_COUNTER (sms_sched_loop)
DEBUG_COUNTER (split_for_sched2)
DEBUG_COUNTER (store_motion)
DEBUG_COUNTER (stv_conversion)
DEBUG_COUNTER (tail_call)
DEBUG_COUNTER (treepre_insert)
DEBUG_COUNTER (tree_sra)
......
2015-09-29 Ilya Enkovich <enkovich.gnu@gmail.com>
PR target/65105
* gcc.target/i386/pr65105-1.c: New.
* gcc.target/i386/pr65105-2.c: New.
* gcc.target/i386/pr65105-3.c: New.
* gcc.target/i386/pr65105-4.C: New.
* gcc.dg/lower-subreg-1.c: Add -mno-stv options for ia32.
2015-09-28 Segher Boessenkool <segher@kernel.crashing.org>
* gcc.dg/asm-4.c: Use braced words for the regular expressions.
......
/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
/* { dg-options "-O -fdump-rtl-subreg1" } */
/* { dg-additional-options "-mno-stv" { target ia32 } } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */
/* { dg-require-effective-target ilp32 } */
......
/* PR target/pr65105 */
/* { dg-do run { target { ia32 } } } */
/* { dg-options "-O2 -march=slm" } */
/* { dg-final { scan-assembler "por" } } */
/* { dg-final { scan-assembler "pand" } } */
#include "stdlib.h"
static int count = 0;
void __attribute__((noinline))
counter (long long l)
{
count++;
if (!l || count > 5)
exit (1);
}
void __attribute__((noinline))
test (long long *arr)
{
register unsigned long long tmp;
tmp = arr[0] | arr[1] & arr[2];
while (tmp)
{
counter (tmp);
tmp = *(arr++) & tmp;
}
}
void __attribute__((noinline))
fill_data (long long *arr)
{
arr[0] = 0x00ffffffL;
arr[1] = 0xffffff00L;
arr[2] = 0x00ffffffL;
arr[3] = 0x0000ff00L;
arr[4] = 0x00ff0000L;
arr[5] = 0xff000000L;
}
int
main (int argc, const char **argv)
{
long long arr[6];
fill_data (arr);
test (arr);
return count - 5;
}
/* PR target/pr65105 */
/* { dg-do compile { target { ia32 } } } */
/* { dg-options "-O2" } */
/* { dg-final { scan-assembler "por" } } */
long long i1, i2, res;
void
test ()
{
res = i1 | i2;
}
/* PR target/pr65105 */
/* { dg-do compile { target { ia32 } } } */
/* { dg-options "-O2 -march=slm -msse4.2" } */
/* { dg-final { scan-assembler "pand" } } */
/* { dg-final { scan-assembler "por" } } */
/* { dg-final { scan-assembler "ptest" } } */
long long i1, i2, i3, res;
void
test ()
{
res = i1 | i2;
if (res)
res &= i3;
}
/* PR target/pr65105 */
/* { dg-do run { target { ia32 } } } */
/* { dg-options "-O2 -march=slm" } */
struct s {
long long l1, l2, l3, l4, l5;
} *a;
long long b;
long long fn1()
{
try
{
b = (a->l1 | a->l2 | a->l3 | a->l4 | a->l5);
return a->l1;
}
catch (int)
{
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment