Hi! On Tue, Jul 13, 2021 at 12:14:22PM -0500, Peter Bergner wrote: > +/* If the target storage locations of arguments MEM1 and MEM2 are > + adjacent, then return the argument that has the lower address. > + Otherwise, return NULL_RTX. */ > > -static bool > +static rtx > adjacent_mem_locations (rtx mem1, rtx mem2)
Note that the function name now nly makes much sense if you use the return value as a boolean (zero for false, non-zero for true). > @@ -18633,7 +18639,7 @@ power6_sched_reorder2 (rtx_insn **ready, int lastpos) > first_store_pos = pos; > > if (is_store_insn (last_scheduled_insn, &str_mem2) > - && adjacent_mem_locations (str_mem, str_mem2)) > + && adjacent_mem_locations (str_mem, str_mem2) != NULL_RTX) ... so don't change this? Or write != 0 != 0 != 0, if one time is good, three times must be better! :-) > @@ -26752,13 +26758,53 @@ rs6000_split_multireg_move (rtx dst, rtx src) > if (GET_MODE (src) == OOmode) > gcc_assert (VSX_REGNO_P (REGNO (dst))); > > - reg_mode = GET_MODE (XVECEXP (src, 0, 0)); > int nvecs = XVECLEN (src, 0); > for (int i = 0; i < nvecs; i++) > { > - int index = WORDS_BIG_ENDIAN ? i : nvecs - 1 - i; > - rtx dst_i = gen_rtx_REG (reg_mode, reg + index); > - emit_insn (gen_rtx_SET (dst_i, XVECEXP (src, 0, i))); > + rtx op; > + int regno = reg + i; > + > + if (WORDS_BIG_ENDIAN) > + { > + op = XVECEXP (src, 0, i); > + > + /* If we are loading an even VSX register and the memory > location > + is adjacent to the next register's memory location (if > any), > + then we can load them both with one LXVP instruction. */ > + if ((regno & 1) == 0) > + { > + rtx op2 = XVECEXP (src, 0, i + 1); > + if (adjacent_mem_locations (op, op2) == op) > + { > + op = adjust_address (op, OOmode, 0); > + /* Skip the next register, since we're going to > + load it together with this register. */ > + i++; > + } > + } > + } > + else > + { > + op = XVECEXP (src, 0, nvecs - i - 1); > + > + /* If we are loading an even VSX register and the memory > location > + is adjacent to the next register's memory location (if > any), > + then we can load them both with one LXVP instruction. */ > + if ((regno & 1) == 0) > + { > + rtx op2 = XVECEXP (src, 0, nvecs - i - 2); > + if (adjacent_mem_locations (op2, op) == op2) > + { > + op = adjust_address (op2, OOmode, 0); > + /* Skip the next register, since we're going to > + load it together with this register. */ > + i++; > + } > + } > + } > + > + rtx dst_i = gen_rtx_REG (GET_MODE (op), regno); > + emit_insn (gen_rtx_SET (dst_i, op)); > } So we are sure we have a hard register here, and it is a VSX register. Okay. Factoring this code would not hurt ;-) Okay for trunk. Thanks! Segher