On Mon, Jan 30, 2017 at 06:43:09PM -0600, Segher Boessenkool wrote: > Hi Jakub, Mike, > > On Mon, Jan 30, 2017 at 10:27:15PM +0100, Jakub Jelinek wrote: > > Accoring to make mddump generated tmp-mddump.md, on powerpc the only pattern > > with unsigned_fix:DI where the inner operand is SF or DFmode is the > > *fixuns_trunc<mode>di2_fctiduz. > > It seems like vsx_fixuns_trunc<mode><VSi>2 (in vsx.md) also wants to > handle this. Mike, do you remember?
Then we'd need something like (incomplete) following patch instead. gpc_reg_operand is actually used both in *fixuns_trunc<mode>di2_fctiduz and in vsx_fixuns_trunc<mode><VSi>2. What I think this patch doesn't handle properly is SFmode -> DImode unsigned_fix. I have no idea how SFmode is represented in vector registers, so have no idea if xscvdpuxds actually handles SFmode as well. But I don't see an iterator that would handle SFmode in vsx.md, only VSX_B is only (define_mode_iterator VSX_B [DF V4SF V2DF]) and even most of the iterators the vsx.md insn uses don't handle SFmode. So, shall the condition actually be || (<MODE>mode != SFmode && VECTOR_UNIT_VSX_P (<MODE>mode) ? 2017-01-31 Jakub Jelinek <ja...@redhat.com> PR target/79197 * config/rs6000/rs6000.md (fixuns_trunc<mode>di2): Use gpc_reg_operand instead of register_operand. Add all the conditions of *fixuns_trunc<mode>di2_fctiduz define_insn into condition. (*fixuns_trunc<mode>di2_fctiduz): Put all conditions on a single line. * config/vsx/vsx.md (vsx_fixuns_trunc<mode><VSi>2): Use VSX_B instead of VSX_F. * gcc.target/powerpc/pr79197.c: New test. * gcc.c-torture/compile/pr79197.c: New test. --- gcc/config/rs6000/rs6000.md.jj 2017-01-31 08:48:22.645210016 +0100 +++ gcc/config/rs6000/rs6000.md 2017-01-31 08:49:53.491028737 +0100 @@ -5742,16 +5742,16 @@ (define_insn_and_split "fixuns_trunc<mod (set_attr "type" "fp")]) (define_expand "fixuns_trunc<mode>di2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))" + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && ((TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ) + || VECTOR_UNIT_VSX_P (<MODE>mode))" "") (define_insn "*fixuns_trunc<mode>di2_fctiduz" [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] - "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS - && TARGET_FCTIDUZ" + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ" "@ fctiduz %0,%1 xscvdpuxds %x0,%x1" --- gcc/config/rs6000/vsx.md.jj 2017-01-26 09:14:27.000000000 +0100 +++ gcc/config/rs6000/vsx.md 2017-01-31 08:45:30.164452804 +0100 @@ -1650,7 +1650,7 @@ (define_insn "vsx_fix_trunc<mode><VSi>2" (define_insn "vsx_fixuns_trunc<mode><VSi>2" [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") - (unsigned_fix:<VSI> (match_operand:VSX_F 1 "gpc_reg_operand" "<VSr>,<VSa>")))] + (unsigned_fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,<VSa>")))] "VECTOR_UNIT_VSX_P (<MODE>mode)" "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" [(set_attr "type" "<VStype_simple>") --- gcc/testsuite/gcc.target/powerpc/pr79197.c.jj 2017-01-31 08:47:30.976881865 +0100 +++ gcc/testsuite/gcc.target/powerpc/pr79197.c 2017-01-31 08:47:30.976881865 +0100 @@ -0,0 +1,11 @@ +/* PR target/79197 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -mno-popcntd" } */ + +unsigned a; + +void +foo (void) +{ + a = *(double *) (__UINTPTR_TYPE__) 0x400000; +} --- gcc/testsuite/gcc.c-torture/compile/pr79197.c.jj 2017-01-31 08:47:30.976881865 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr79197.c 2017-01-31 08:47:30.976881865 +0100 @@ -0,0 +1,10 @@ +/* PR target/79197 */ + +unsigned long b; + +unsigned long +foo (float *a, float *x) +{ + __builtin_memcpy (a, x, sizeof (float)); + return *a; +} Jakub