From 40cca4f97caa0a29b71ec335f1d29daf484f73de Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 11 Mar 2008 20:18:48 +0100 Subject: [PATCH] re PR target/35540 (Segmentation fault with __builtin_parity() and -O1) PR target/35540 * config/i386/i386.md (paritysi2, paritydi2): Use register_operand constraint for operand 1. (paritysi2_cmp): Use register_operand constraint for operand 2. Use earlyclobber modifier for operand 1. Remove support for memory operands. (paritydi2_cmp): Use register_operand constraint for operand 3. Use earlyclobber modifier for operand 1. Remove support for memory operands. testsuite/ChangeLog: PR target/35540 * gcc.target/i386/pr35540.c: New test. From-SVN: r133118 --- gcc/ChangeLog | 14 +++++++- gcc/config/i386/i386.md | 35 ++++++++----------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr35540.c | 45 +++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr35540.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3fb00aabe6..ccd9abee4ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,17 @@ +2008-03-11 Uros Bizjak + + PR target/35540 + * config/i386/i386.md (paritysi2, paritydi2): Use register_operand + constraint for operand 1. + (paritysi2_cmp): Use register_operand constraint for operand 2. + Use earlyclobber modifier for operand 1. Remove support for + memory operands. + (paritydi2_cmp): Use register_operand constraint for operand 3. + Use earlyclobber modifier for operand 1. Remove support for + memory operands. + 2008-03-11 Paul Brook - Vladimir Prus + Vladimir Prus * config/arm/arm.c (use_return_insn): Check TARGET_APCS_FRAME. (arm_compute_save_reg0_reg12_mask): Always diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index eb942d60d9c..17e974d544a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15429,7 +15429,7 @@ (define_expand "paritydi2" [(set (match_operand:DI 0 "register_operand" "") - (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))] + (parity:DI (match_operand:DI 1 "register_operand" "")))] "! TARGET_POPCNT" { rtx scratch = gen_reg_rtx (QImode); @@ -15457,10 +15457,10 @@ (define_insn_and_split "paritydi2_cmp" [(set (reg:CC FLAGS_REG) - (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m"))) - (clobber (match_scratch:DI 0 "=r,X")) - (clobber (match_scratch:SI 1 "=r,r")) - (clobber (match_scratch:HI 2 "=Q,Q"))] + (parity:CC (match_operand:DI 3 "register_operand" "0"))) + (clobber (match_scratch:DI 0 "=r")) + (clobber (match_scratch:SI 1 "=&r")) + (clobber (match_scratch:HI 2 "=Q"))] "! TARGET_POPCNT" "#" "&& reload_completed" @@ -15476,20 +15476,18 @@ { operands[4] = gen_lowpart (SImode, operands[3]); - if (MEM_P (operands[3])) - emit_move_insn (operands[1], gen_highpart (SImode, operands[3])); - else if (! TARGET_64BIT) - operands[1] = gen_highpart (SImode, operands[3]); - else + if (TARGET_64BIT) { emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); } + else + operands[1] = gen_highpart (SImode, operands[3]); }) (define_expand "paritysi2" [(set (match_operand:SI 0 "register_operand" "") - (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))] + (parity:SI (match_operand:SI 1 "register_operand" "")))] "! TARGET_POPCNT" { rtx scratch = gen_reg_rtx (QImode); @@ -15508,9 +15506,9 @@ (define_insn_and_split "paritysi2_cmp" [(set (reg:CC FLAGS_REG) - (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m"))) - (clobber (match_scratch:SI 0 "=r,X")) - (clobber (match_scratch:HI 1 "=Q,Q"))] + (parity:CC (match_operand:SI 2 "register_operand" "0"))) + (clobber (match_scratch:SI 0 "=r")) + (clobber (match_scratch:HI 1 "=&Q"))] "! TARGET_POPCNT" "#" "&& reload_completed" @@ -15525,13 +15523,8 @@ { operands[3] = gen_lowpart (HImode, operands[2]); - if (MEM_P (operands[2])) - emit_move_insn (operands[1], gen_highpart (HImode, operands[2])); - else - { - emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); - emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); - } + emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); + emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); }) (define_insn "*parityhi2_cmp" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f6bf6834c3f..1fd06c444a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-11 Uros Bizjak + + PR target/35540 + * gcc.target/i386/pr35540.c: New test. + 2008-03-11 Uros Bizjak * g++.dg/inherit/override-attribs.C: Require ilp32 x86 target. diff --git a/gcc/testsuite/gcc.target/i386/pr35540.c b/gcc/testsuite/gcc.target/i386/pr35540.c new file mode 100644 index 00000000000..00af637d002 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35540.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +int __attribute__ ((noinline)) +test (unsigned int *a, int b) +{ + return b ? 1 : __builtin_parity (*a); +} + +int __attribute__ ((noinline)) +testl (unsigned long *a, int b) +{ + return b ? 1 : __builtin_parityl (*a); +} + +int __attribute__ ((noinline)) +testll (unsigned long long *a, int b) +{ + return b ? 1 : __builtin_parityll (*a); +} + +int +main () +{ + unsigned int a = 0; + unsigned long al; + unsigned long long all; + + a = 0x12345670; + if (test (&a, 0)) + abort (); + + al = 0x12345670ul; + if (testl (&al, 0)) + abort(); + +#if 1 + all = 0x12345678abcdef0ull; + if (testll (&all, 0)) + abort (); +#endif + return 0; +} -- 2.30.2