Hi,

The previous patch for PR80376 produced a different sort of ICE, which wasn't
a terribly great solution.  I looked into Segher's suggestion based on code in
x86, but that wasn't appropriate here as the problem happens at a different
place.  The real secondary problem is that we produce a const0_rtx instead of
a mode-compatible CONST0_RTX, so the assignment of the built-in result to its
target rtx fails with an ICE.  I've gone through rs6000.c and fixed the places
where we do this in an obviously wrong manner.

This patch still fixes the missing vec_xxpermdi cases that were the primary
cause of the bug (this time with consistent whitespace), and corrects the
documentation to show that argument 3 must be a constant.  I also decided to
fix PR80315, which just had a silly pasto where we were checking the value
of the wrong argument, since this patch fixes one of the CONST0_RTX cases
right next to it.

Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions.
Is this ok for trunk?  Both bugs were reported against GCC 6.2, so I would
also like to backport the fixes to 6 and possibly 5.

Thanks,
Bill


2017-04-11  Bill Schmidt  <wschm...@linux.vnet.ibm.com>

        PR target/80376
        PR target/80315
        * config/rs6000/rs6000.c (rs6000_expand_unop_builtin): Return
        CONST0_RTX (mode) rather than const0_rtx where appropriate.
        (rs6000_expand_binop_builtin): Likewise.
        (rs6000_expand_ternop_builtin): Likewise; also add missing
        vsx_xxpermdi_* variants; also fix typo (arg1 => arg2) for
        vshasigma built-ins.
        * doc/extend.texi: Document that vec_xxpermdi's third argument
        must be a constant.


Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 246804)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -14550,7 +14550,7 @@ rs6000_expand_unop_builtin (enum insn_code icode,
          || INTVAL (op0) < -16)
        {
          error ("argument 1 must be a 5-bit signed literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
 
@@ -14653,7 +14653,7 @@ rs6000_expand_binop_builtin (enum insn_code icode,
          || TREE_INT_CST_LOW (arg1) & ~0x1f)
        {
          error ("argument 2 must be a 5-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_dfptstsfi_eq_dd
@@ -15579,7 +15579,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg2) & ~0xf)
        {
          error ("argument 3 must be a 4-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_vsx_xxpermdi_v2df
@@ -15586,6 +15586,11 @@ rs6000_expand_ternop_builtin (enum insn_code icode
            || icode == CODE_FOR_vsx_xxpermdi_v2di
            || icode == CODE_FOR_vsx_xxpermdi_v2df_be
            || icode == CODE_FOR_vsx_xxpermdi_v2di_be
+           || icode == CODE_FOR_vsx_xxpermdi_v1ti
+           || icode == CODE_FOR_vsx_xxpermdi_v4sf
+           || icode == CODE_FOR_vsx_xxpermdi_v4si
+           || icode == CODE_FOR_vsx_xxpermdi_v8hi
+           || icode == CODE_FOR_vsx_xxpermdi_v16qi
            || icode == CODE_FOR_vsx_xxsldwi_v16qi
            || icode == CODE_FOR_vsx_xxsldwi_v8hi
            || icode == CODE_FOR_vsx_xxsldwi_v4si
@@ -15599,7 +15604,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg2) & ~0x3)
        {
          error ("argument 3 must be a 2-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_vsx_set_v2df
@@ -15619,7 +15624,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg2) & ~0x1)
        {
          error ("argument 3 must be a 1-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_dfp_ddedpd_dd
@@ -15631,7 +15636,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg2) & ~0x3)
        {
          error ("argument 1 must be 0 or 2");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_dfp_denbcd_dd
@@ -15643,7 +15648,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg0) & ~0x1)
        {
          error ("argument 1 must be a 1-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_dfp_dscli_dd
@@ -15657,7 +15662,7 @@ rs6000_expand_ternop_builtin (enum insn_code icode
          || TREE_INT_CST_LOW (arg1) & ~0x3f)
        {
          error ("argument 2 must be a 6-bit unsigned literal");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
   else if (icode == CODE_FOR_crypto_vshasigmaw
@@ -15669,14 +15674,14 @@ rs6000_expand_ternop_builtin (enum insn_code icode
       if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (arg1, 2))
        {
          error ("argument 2 must be 0 or 1");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
 
       STRIP_NOPS (arg2);
-      if (TREE_CODE (arg2) != INTEGER_CST || wi::geu_p (arg1, 16))
+      if (TREE_CODE (arg2) != INTEGER_CST || wi::geu_p (arg2, 16))
        {
          error ("argument 3 must be in the range 0..15");
-         return const0_rtx;
+         return CONST0_RTX (tmode);
        }
     }
 
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 246804)
+++ gcc/doc/extend.texi (working copy)
@@ -17623,20 +17623,21 @@ void vec_vsx_st (vector bool char, int, vector boo
 void vec_vsx_st (vector bool char, int, unsigned char *);
 void vec_vsx_st (vector bool char, int, signed char *);
 
-vector double vec_xxpermdi (vector double, vector double, int);
-vector float vec_xxpermdi (vector float, vector float, int);
-vector long long vec_xxpermdi (vector long long, vector long long, int);
+vector double vec_xxpermdi (vector double, vector double, const int);
+vector float vec_xxpermdi (vector float, vector float, const int);
+vector long long vec_xxpermdi (vector long long, vector long long, const int);
 vector unsigned long long vec_xxpermdi (vector unsigned long long,
-                                        vector unsigned long long, int);
-vector int vec_xxpermdi (vector int, vector int, int);
+                                        vector unsigned long long, const int);
+vector int vec_xxpermdi (vector int, vector int, const int);
 vector unsigned int vec_xxpermdi (vector unsigned int,
-                                  vector unsigned int, int);
-vector short vec_xxpermdi (vector short, vector short, int);
+                                  vector unsigned int, const int);
+vector short vec_xxpermdi (vector short, vector short, const int);
 vector unsigned short vec_xxpermdi (vector unsigned short,
-                                    vector unsigned short, int);
-vector signed char vec_xxpermdi (vector signed char, vector signed char, int);
+                                    vector unsigned short, const int);
+vector signed char vec_xxpermdi (vector signed char, vector signed char,
+                                 const int);
 vector unsigned char vec_xxpermdi (vector unsigned char,
-                                   vector unsigned char, int);
+                                   vector unsigned char, const int);
 
 vector double vec_xxsldi (vector double, vector double, int);
 vector float vec_xxsldi (vector float, vector float, int);

Reply via email to