@@ -1055,7 +1055,11 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc)
machine_mode mode = GET_MODE (x);
auto old_num_changes = num_validated_changes ();
- if (from && GET_CODE (x) == GET_CODE (from) && rtx_equal_p (x, from))
+ if (from
+ && GET_CODE (x) == GET_CODE (from)
+ && (REG_P (x)
+ ? REGNO (x) == REGNO (from)
+ : rtx_equal_p (x, from)))
{
/* Don't replace register asms in asm statements; we mustn't
change the user's register allocation. */
@@ -1065,11 +1069,26 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc)
&& asm_noperands (PATTERN (insn)) > 0)
return false;
+ rtx newval = to;
+ if (GET_MODE (x) != GET_MODE (from))
+ {
+ gcc_assert (REG_P (x) && HARD_REGISTER_P (x));
+ if (REG_NREGS (x) != REG_NREGS (from)
+ || !REG_CAN_CHANGE_MODE_P (REGNO (x), GET_MODE (from),
+ GET_MODE (x)))
+ return false;
+ newval = simplify_subreg (GET_MODE (x), to, GET_MODE (from),
+ subreg_lowpart_offset (GET_MODE (x),
+ GET_MODE (from)));
+ if (!newval)
+ return false;
+ }
+
if (should_unshare)
- validate_unshare_change (insn, loc, to, 1);
+ validate_unshare_change (insn, loc, newval, 1);
else
- validate_change (insn, loc, to, 1);
- if (mem_depth && !REG_P (to) && !CONSTANT_P (to))
+ validate_change (insn, loc, newval, 1);
+ if (mem_depth && !REG_P (newval) && !CONSTANT_P (newval))
{
/* We're substituting into an address, but TO will have the
form expected outside an address. Canonicalize it if
@@ -1083,9 +1102,9 @@ insn_propagation::apply_to_rvalue_1 (rtx *loc)
{
/* TO is owned by someone else, so create a copy and
return TO to its original form. */
- rtx to = copy_rtx (*loc);
+ newval = copy_rtx (*loc);
cancel_changes (old_num_changes);
- validate_change (insn, loc, to, 1);
+ validate_change (insn, loc, newval, 1);
}
}
num_replacements += 1;
@@ -1,6 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-march=sapphirerapids -O2" } */
-/* { dg-final { scan-assembler-times {vpunpcklqdq[ \t]+} 3 } } */
+/* { dg-final { scan-assembler-times {vpunpcklqdq[ \t]+} 3 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times {vpunpcklqdq[ \t]+} 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times {vmovhps[ \t]+} 1 { target ia32 } } } */
/* { dg-final { scan-assembler-not {vpermi2[wb][ \t]+} } } */
typedef _Float16 v8hf __attribute__((vector_size (16)));
@@ -17,6 +17,6 @@
/* { dg-final { scan-assembler-times "vpbroadcastw" 6 { target ia32 } } } */
/* { dg-final { scan-assembler-times "vpblendw" 3 { target ia32 } } } */
-/* { dg-final { scan-assembler-times "vpinsrw" 63 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "vpinsrw" 68 { target ia32 } } } */
/* { dg-final { scan-assembler-times "vpblendd" 3 } } */