/* The shift count might be in SImode while int_mode might
be narrower. On IA-64 it is even DImode. If the shift
count is too large and doesn't fit into int_mode, we'd
- ICE. So, if int_mode is narrower than word, use
- word_mode for the shift count. */
+ ICE. So, if int_mode is narrower than
+ HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
if (GET_MODE (op1) == VOIDmode
- && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
- pop1 = rtx_mode_t (op1, word_mode);
+ && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
+ pop1 = rtx_mode_t (op1, DImode);
wide_int wop1 = pop1;
if (SHIFT_COUNT_TRUNCATED)
/* The rotate count might be in SImode while int_mode might
be narrower. On IA-64 it is even DImode. If the shift
count is too large and doesn't fit into int_mode, we'd
- ICE. So, if int_mode is narrower than word, use
- word_mode for the shift count. */
+ ICE. So, if int_mode is narrower than
+ HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
if (GET_MODE (op1) == VOIDmode
- && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
- pop1 = rtx_mode_t (op1, word_mode);
+ && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
+ pop1 = rtx_mode_t (op1, DImode);
if (wi::neg_p (pop1))
return NULL_RTX;
wide_int shift
= rtx_mode_t (op1,
GET_MODE (op1) == VOIDmode
- && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
- ? word_mode : mode);
+ && (GET_MODE_PRECISION (int_mode)
+ < HOST_BITS_PER_WIDE_INT)
+ ? DImode : mode);
if (SHIFT_COUNT_TRUNCATED)
shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
--- /dev/null
+/* PR rtl-optimization/123523 */
+/* { dg-do compile } */
+/* { dg-options "-O -mavx512vl -mavx512bw" } */
+
+typedef __attribute__((__vector_size__ (16))) short V;
+typedef __attribute__((__vector_size__ (32))) short W;
+
+char c;
+W *p, *q;
+short s;
+
+void
+bar (V v, int, int, int, int, int, int, void *)
+{
+ W w = __builtin_ia32_psrlw256_mask ((W) { }, v, *p, 0);
+ short x = __builtin_ia32_pcmpgtw256_mask (w, *q, 0);
+ __builtin_mul_overflow (x, c, &s);
+}
+
+void
+foo ()
+{
+ bar ((V){0, -14}, 0, 0, 0, 0, 0, 0, q);
+}