Hi All,

The following patch has been bootstrapped and regtested on powerpc64le-linux.

There is no immediate value splatting instruction in Power. Currently, those
values need to be stored in a register or memory. To address this issue, I
have updated the predicate for the second operand in vsx_splat to
splat_input_operand and corrected the assignment of op1 to operands[1].
These changes ensure that operand1 is stored in a register.

2024-02-26  Jeevitha Palanisamy  <jeevi...@linux.ibm.com>

gcc/
        PR target/113950
        * config/rs6000/vsx.md (vsx_splat_<mode>): Updated the predicates
        for second operand and corrected the assignment.

gcc/testsuite/
        PR target/113950
        * gcc.target/powerpc/pr113950.c: New testcase.

diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 6111cc90eb7..3e2df247630 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -4660,14 +4660,14 @@
 (define_expand "vsx_splat_<mode>"
   [(set (match_operand:VSX_D 0 "vsx_register_operand")
        (vec_duplicate:VSX_D
-        (match_operand:<VEC_base> 1 "input_operand")))]
+        (match_operand:<VEC_base> 1 "splat_input_operand")))]
   "VECTOR_MEM_VSX_P (<MODE>mode)"
 {
   rtx op1 = operands[1];
   if (MEM_P (op1))
     operands[1] = rs6000_force_indexed_or_indirect_mem (op1);
   else if (!REG_P (op1))
-    op1 = force_reg (<VSX_D:VEC_base>mode, op1);
+    operands[1] = force_reg (<VSX_D:VEC_base>mode, op1);
 })
 
 (define_insn "vsx_splat_<mode>_reg"
diff --git a/gcc/testsuite/gcc.target/powerpc/pr113950.c 
b/gcc/testsuite/gcc.target/powerpc/pr113950.c
new file mode 100644
index 00000000000..5c6865a8544
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr113950.c
@@ -0,0 +1,25 @@
+/* PR target/113950 */
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O1 -mdejagnu-cpu=power7" } */
+
+/* Verify we do not ICE on the following.  */
+
+void abort (void);
+
+int main ()
+{
+  int i;
+  vector signed long long vsll_result, vsll_expected_result;
+  signed long long sll_arg1;
+
+  sll_arg1 = 300;
+  vsll_expected_result = (vector signed long long) {300, 300};
+  vsll_result = __builtin_vsx_splat_2di (sll_arg1);  
+
+  for (i = 0; i < 2; i++)
+    if (vsll_result[i] != vsll_expected_result[i])
+      abort();
+
+  return 0;
+}


Reply via email to