On Thu, Jul 07, 2016 at 02:58:17AM +0000, Segher Boessenkool wrote: > Similar to PR70098, which is about integers in floating point registers, > we can have the completely analogous problem with vector registers as well > now that we allow integers in vector registers. So, this patch solves it > in the same way. This only works for targets with direct move. > > To recap: register allocation can decide to put an integer mode value in > a floating point or vector register. If that register is used in a bd*z > instruction, which is a jump instruction, reload can not do an output > reload on it (it does not do output reloads on any jump insns), so the > float or vector register will remain, and we have to allow it here or > recog will ICE. Later on we will split this to valid instructions, > including a move from that fp/vec register to an int register; it is this > move that will still fail (PR70098) if we do not have direct move enabled.
BTW, both pr70098 and pr71763 are triggered by combine, not loop-doloop as I was thinking earlier. See rtl dumps for the testcases. I doubt the "optimization" done by combine here is worth keeping, since loop-doloop.c ought to already handle the benficial inner loop use of ctr. Elsewhere we typically end up with an insn that needs splitting back to the original sequence. So we could avoid creating trouble for ourselves with the following patch. Bootstrap and regression test powerpc64le-linux and powerpc64-linux in progress. * config/rs6000/rs6000.md (UNSPEC_DONT_COMBINE): New unspec. (ctr<mode>): Add unspec. (ctr<mode>_internal* and splitters): Likewise. Renumber. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 7d9c660..b2d1118 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -148,6 +148,7 @@ UNSPEC_IEEE128_MOVE UNSPEC_IEEE128_CONVERT UNSPEC_SIGNBIT + UNSPEC_DONT_COMBINE ]) ;; @@ -12185,6 +12186,7 @@ (set (match_dup 0) (plus:P (match_dup 0) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 2 "")) (clobber (match_scratch:P 3 ""))])] "" @@ -12205,6 +12207,7 @@ (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) (clobber (match_scratch:P 4 "=X,X,&r,r"))] "" @@ -12229,6 +12232,7 @@ (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) (clobber (match_scratch:P 4 "=X,X,&r,r"))] "" @@ -12246,7 +12250,7 @@ ;; Similar but use EQ -(define_insn "*ctr<mode>_internal5" +(define_insn "*ctr<mode>_internal3" [(set (pc) (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") (const_int 1)) @@ -12255,6 +12259,7 @@ (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) (clobber (match_scratch:P 4 "=X,X,&r,r"))] "" @@ -12270,7 +12275,7 @@ [(set_attr "type" "branch") (set_attr "length" "*,16,20,20")]) -(define_insn "*ctr<mode>_internal6" +(define_insn "*ctr<mode>_internal4" [(set (pc) (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") (const_int 1)) @@ -12279,6 +12284,7 @@ (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) (clobber (match_scratch:P 4 "=X,X,&r,r"))] "" @@ -12305,6 +12311,7 @@ (match_operand 6 "" ""))) (set (match_operand:P 0 "int_reg_operand" "") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:P 4 ""))] "reload_completed" @@ -12330,6 +12337,7 @@ (match_operand 6 "" ""))) (set (match_operand:P 0 "nonimmediate_operand" "") (plus:P (match_dup 1) (const_int -1))) + (unspec [(const_int 0)] UNSPEC_DONT_COMBINE) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:P 4 ""))] "reload_completed && ! gpc_reg_operand (operands[0], SImode)" -- Alan Modra Australia Development Lab, IBM