@@ -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));
+ 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. */
@@ -987,11 +987,13 @@ (define_insn_and_split "*vsx_le_undo_permute_<mode>"
(define_insn_and_split "*vsx_le_perm_load_<mode>"
[(set (match_operand:VSX_LE_128 0 "vsx_register_operand" "=wa,r")
(match_operand:VSX_LE_128 1 "memory_operand" "Z,Q"))]
- "!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)"
"@
#
#"
- "!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 +1010,8 @@ (define_insn_and_split "*vsx_le_perm_load_<mode>"
(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 +1022,8 @@ (define_insn "*vsx_le_perm_store_<mode>"
(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 +1079,8 @@ (define_peephole2
(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);
@@ -1241,7 +1246,8 @@ (define_expand "vsx_load_<mode>"
"VECTOR_MEM_VSX_P (<MODE>mode)"
{
/* Expand to swaps if needed, prior to swap optimization. */
- if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR)
+ if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR
+ && !altivec_indexed_or_indirect_operand(operands[1], <MODE>mode))
{
rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode);
DONE;
@@ -1254,7 +1260,8 @@ (define_expand "vsx_store_<mode>"
"VECTOR_MEM_VSX_P (<MODE>mode)"
{
/* Expand to swaps if needed, prior to swap optimization. */
- if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR)
+ if (!BYTES_BIG_ENDIAN && !TARGET_P9_VECTOR
+ && !altivec_indexed_or_indirect_operand(operands[0], <MODE>mode))
{
rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode);
DONE;
new file mode 100644
@@ -0,0 +1,17 @@
+/* PR target/98959 */
+/* { dg-options "-fno-schedule-insns -O2 -mcmodel=small" } */
+
+/* Verify we do not ICE on the following. */
+
+typedef __attribute__ ((altivec (vector__))) unsigned __int128 v1ti_t;
+
+v1ti_t foo (v1ti_t v);
+
+void
+bug ()
+{
+ v1ti_t dv = { ((31415926539) << 6) };
+ dv = foo (dv);
+ if (dv[0] != 0)
+ __builtin_abort ();
+}