I found the root cause. In function rs6000_preferred_reload_class, it specifically check the case that reload 0 into a VSX register, then the target reload class is VSX register. VSX instructions can't load a constant into VSX registers directly, I guess the author wanted to use a SUB or XOR instruction to get a 0 value. Then function gen_reload calls gen_move_insn to generate the reload instruction, which actually generates a movdi_internal64 insn, and it doesn't contain a constraint to handle the 0->VSX register case, and causes ICE.
So it can be fixed by adding a new constraint to movdi_internal64 to load 0 to VSX register. thanks Guozhi Wei On Tue, Aug 5, 2014 at 1:38 PM, Segher Boessenkool <seg...@kernel.crashing.org> wrote: > On Tue, Aug 05, 2014 at 01:32:00PM +0930, Alan Modra wrote: >> On Mon, Aug 04, 2014 at 05:54:04PM -0700, Carrot Wei wrote: >> > Another problem is in the definition of insn pattern "*movdi_internal64". >> > >> > (define_insn "*movdi_internal64" >> > [(set (match_operand:DI 0 "nonimmediate_operand" >> > "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wm") >> > (match_operand:DI 1 "input_operand" >> > "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wm,r"))] >> > "TARGET_POWERPC64 >> > && (gpc_reg_operand (operands[0], DImode) >> > || gpc_reg_operand (operands[1], DImode))" >> > >> > The predicates of this insn pattern allow the moving of an integer to >> > VSX register, but there is no constraint allow this case. Can this >> > cause problem in reload? >> >> Probably, just as you found with fprs. The underlying issue is that >> the operand predicates don't match the operand constraints. What's >> more, you can't make them match without breaking up the insn, or >> adding a whole lot of extra alternatives. > > Can you disallow this in the condition of the pattern, just like it > already requires at least one of the operands to be gpc_reg_operand? > > > Segher