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

Reply via email to