The fsel define_insn uses fpr_reg_operand for its predicates. This won't work because passes can put a hard register in the operands: in the testcase, combine likes to forward the parameter registers to what then is still an smin, and then split1 uses "*s<minmax><mode>3_fpr" (which has gpc_reg_operand). And then we have a GPR in the operand, which does not match fpr_reg_operand.
It seems to me the predicates should be gpc_reg_operand here as well. This patch changes that. Mike, does this look correct? Was there a reason it used fpr_reg_operand? Bootstrapped and tested on powerpc64-linux. Segher 2017-01-27 Segher Boessenkool <seg...@kernel.crashing.org> * config/rs6000/rs6000.md (*fsel<SFDF:mode><SFDF2:mode>4): Use gpc_reg_operand instead of fpr_reg_operand. --- gcc/config/rs6000/rs6000.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3f29221..f32b381 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -4946,12 +4946,12 @@ (define_expand "mov<mode>cc" }") (define_insn "*fsel<SFDF:mode><SFDF2:mode>4" - [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>") + [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") (if_then_else:SFDF - (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>") + (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") (match_operand:SFDF2 4 "zero_fp_constant" "F")) - (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>") - (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))] + (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") + (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) -- 1.9.3