https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98959
Peter Bergner <bergner at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |meissner at gcc dot gnu.org, | |wschmidt at gcc dot gnu.org --- Comment #13 from Peter Bergner <bergner at gcc dot gnu.org> --- Adding Bill and Mike for some input. So the bad insn below is being generated by the after LRA splitter, specifically the *vsx_le_perm_load_<mode> splitter which calls rs6000_emit_le_vsx_permute(). Bill, Mike and Segher, I assume that vsx function is NOT expecting to see an Altivec style and: address correct? Adding some uses of the altivec_indexed_or_indirect_operand () predicate to disable the splitters that call rs6000_emit_le_vsx_permute() seems to fix the bug for me. Does this look like the correct fix? diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ec068c58aa5..8db41a066b4 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -10059,6 +10059,11 @@ rs6000_const_vec (machine_mode mode) void rs6000_emit_le_vsx_permute (rtx dest, rtx source, machine_mode mode) { + if (MEM_P (dest)) + gcc_assert (!altivec_indexed_or_indirect_operand (dest, mode)); + else if (MEM_P (source)) + gcc_assert (!altivec_indexed_or_indirect_operand (source, mode)); + /* Scalar permutations are easier to express in integer modes rather than floating-point modes, so cast them here. We use V1TImode instead of TImode to ensure that the values don't go through GPRs. */ diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 3e0518631df..610490cb3d9 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -991,7 +991,8 @@ "@ # #" - "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" + "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR + && !altivec_indexed_or_indirect_operand (operands[1], <MODE>mode)" [(const_int 0)] { rtx tmp = (can_create_pseudo_p () @@ -1008,7 +1009,8 @@ (define_insn "*vsx_le_perm_store_<mode>" [(set (match_operand:VSX_LE_128 0 "memory_operand" "=Z,Q") (match_operand:VSX_LE_128 1 "vsx_register_operand" "+wa,r"))] - "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR" + "!BYTES_BIG_ENDIAN && TARGET_VSX && !TARGET_P9_VECTOR + & !altivec_indexed_or_indirect_operand (operands[0], <MODE>mode)" "@ # #" @@ -1019,7 +1021,8 @@ (define_split [(set (match_operand:VSX_LE_128 0 "memory_operand") (match_operand:VSX_LE_128 1 "vsx_register_operand"))] - "!BYTES_BIG_ENDIAN && TARGET_VSX && !reload_completed && !TARGET_P9_VECTOR" + "!BYTES_BIG_ENDIAN && TARGET_VSX && !reload_completed && !TARGET_P9_VECTOR + && !altivec_indexed_or_indirect_operand (operands[0], <MODE>mode)" [(const_int 0)] { rtx tmp = (can_create_pseudo_p () @@ -1075,7 +1078,8 @@ (define_split [(set (match_operand:VSX_LE_128 0 "memory_operand") (match_operand:VSX_LE_128 1 "vsx_register_operand"))] - "!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed && !TARGET_P9_VECTOR" + "!BYTES_BIG_ENDIAN && TARGET_VSX && reload_completed && !TARGET_P9_VECTOR + && !altivec_indexed_or_indirect_operand (operands[0], <MODE>mode)" [(const_int 0)] { rs6000_emit_le_vsx_permute (operands[1], operands[1], <MODE>mode);