This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, rs6000] Fix PR70963: Wrong code for V2DF/V2DI vec_cts with zero scale factor


Hi,

PR70963 reports a problem with vec_cts when used to convert vector double to vector long long.
This is due to a register with an undefined value that is generated only when the scale factor is
zero.  This patch adds logic to provide the correct value when the scale factor is zero.

The problem from the PR is in the define_expand for vsx_xvcvdpsxds_scale.  The define_expand
for vsx_xvcvdpuxds_scale clearly has the same problem, although it is not possible to reach this
via a call to vec_cts.  The raw builtin __builtin_vsx_xvcvdpuxds_scale can be used, however, and
Iâve shown this in the test case.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions.  Is this ok for
trunk, and eventual backport to 6 and 5?

Thanks,
Bill


[gcc]

2016-05-09  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

        * config/rs6000/vsx.md (vsx_xvcvdpsxds_scale): Generate correct
        code for a zero scale factor.
        (vsx_xvcvdpuxds_scale): Likewise.

[gcc/testsuite]

2016-05-09  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

        * gcc.target/powerpc/pr70963.c: New.


Index: gcc/config/rs6000/vsx.md                                                 
===================================================================
--- gcc/config/rs6000/vsx.md    (revision 236051)                               
+++ gcc/config/rs6000/vsx.md    (working copy)                                  
@@ -1717,10 +1717,15 @@
 {                                                                              
   rtx op0 = operands[0];                                                       
   rtx op1 = operands[1];                                                       
-  rtx tmp = gen_reg_rtx (V2DFmode);                                            
+  rtx tmp;                                                                     
   int scale = INTVAL(operands[2]);                                             
-  if (scale != 0)                                                              
-    rs6000_scale_v2df (tmp, op1, scale);                                       
+  if (scale == 0)                                                              
+    tmp = op1;                                                                 
+  else                                                                         
+    {                                                                          
+      tmp  = gen_reg_rtx (V2DFmode);                                           
+      rs6000_scale_v2df (tmp, op1, scale);                                     
+    }                                                                          
   emit_insn (gen_vsx_xvcvdpsxds (op0, tmp));                                   
   DONE;                                                                        
 })                                                                             
@@ -1741,10 +1746,15 @@
 {                                                                              
   rtx op0 = operands[0];                                                       
   rtx op1 = operands[1];                                                       
-  rtx tmp = gen_reg_rtx (V2DFmode);                                            
+  rtx tmp;                                                                     
   int scale = INTVAL(operands[2]);                                             
-  if (scale != 0)                                                              
-    rs6000_scale_v2df (tmp, op1, scale);                                       
+  if (scale == 0)                                                              
+    tmp = op1;                                                                 
+  else                                                                         
+    {                                                                          
+      tmp = gen_reg_rtx (V2DFmode);                                            
+      rs6000_scale_v2df (tmp, op1, scale);                                     
+    }                                                                          
   emit_insn (gen_vsx_xvcvdpuxds (op0, tmp));                                   
   DONE;                                                                        
 })                                                                             
Index: gcc/testsuite/gcc.target/powerpc/pr70963.c                               
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr70963.c  (revision 0)                    
+++ gcc/testsuite/gcc.target/powerpc/pr70963.c  (working copy)                  
@@ -0,0 +1,39 @@
+/* { dg-do run { target { powerpc64*-*-* && vsx_hw } } } */                    
+/* { dg-require-effective-target powerpc_vsx_ok } */                           
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */                  
+/* { dg-options "-maltivec" } */                                               
+                                                                               
+#include <stdlib.h>                                                            
+#include <stdio.h>                                                             
+#include <altivec.h>                                                           
+                                                                               
+static int failed;                                                             
+static void test (void);                                                       
+                                                                               
+static void check (int result, const char *name)                               
+{                                                                              
+  if (!result)                                                                 
+    {                                                                          
+      failed++;                                                                
+      printf ("fail %s\n", name);                                              
+    }                                                                          
+}                                                                              
+                                                                               
+int main (void)                                                                
+{                                                                              
+  test ();                                                                     
+  if (failed)                                                                  
+    abort ();                                                                  
+  return 0;                                                                    
+}                                                                              
+                                                                               
+vector double x = { 81.0, 76.0 };                                              
+vector long long y = { 81, 76 };                                               
+                                                                               
+static void test()                                                             
+{                                                                              
+  vector long long a = vec_cts (x, 0);                                         
+  vector double b = vec_ctf (a, 0);                                            
+  check (vec_all_eq (a, y), "vec_cts");                                        
+  check (vec_all_eq (b, x), "vec_ctf");                                        
+}                                                                              



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]