Hi! 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. There is an expander for that instruction, which uses different operand predicates and different condition, so the following testcases show 2 different cases, in one the condition for the expander is true and false for the actual insn, the other where register_operand is true (SFmode subreg), while gpc_reg_operand is false. (There are other expanders and patterns that handle vector modes, or SImode, or DImode with KF/TFmodes.)
As there is just one insn that satisfies it, it makes no sense to have different conditions or different predicates (there would need to be other define_insn* patterns that would handle the rest), but I don't really even see the point in duplication of the condition and predicates, the define_insn itself can serve as expander. Bootstrapped/regtested on powerpc64{,le}-linux, ok for trunk? 2017-01-30 Jakub Jelinek <ja...@redhat.com> PR target/79197 * config/rs6000/rs6000.md (*fixuns_trunc<mode>di2_fctiduz): Rename to ... (fixuns_trunc<mode>di2): ... this, remove previous expander. Put all conditions on a single line. * gcc.target/powerpc/pr79197.c: New test. * gcc.c-torture/compile/pr79197.c: New test. --- gcc/config/rs6000/rs6000.md.jj 2017-01-23 18:41:20.000000000 +0100 +++ gcc/config/rs6000/rs6000.md 2017-01-30 14:44:12.148761705 +0100 @@ -5712,17 +5712,10 @@ (define_insn_and_split "fixuns_trunc<mod [(set_attr "length" "12") (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))" - "") - -(define_insn "*fixuns_trunc<mode>di2_fctiduz" +(define_insn "fixuns_trunc<mode>di2" [(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/testsuite/gcc.target/powerpc/pr79197.c.jj 2017-01-30 14:54:55.533314402 +0100 +++ gcc/testsuite/gcc.target/powerpc/pr79197.c 2017-01-30 14:55:20.407988406 +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-30 14:56:31.383058240 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr79197.c 2017-01-30 14:56:40.902933477 +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