/* Number of elements in the vector. */
w = GET_MODE_NUNITS (mode);
- rtx round_data[MAX_VECT_LEN];
- rtx round_reg, round_data_rtx;
-
- if (mode != E_V32QImode)
+ /* If we are using xvshuf.*, clamp the selector to avoid unpredictable
+ output. */
+ if (maskmode != V8SImode && maskmode != V4DImode)
{
- for (int i = 0; i < w; i += 1)
- {
- round_data[i] = GEN_INT (0x1f);
- }
-
- if (mode == E_V4DFmode)
- {
- round_data_rtx = gen_rtx_CONST_VECTOR (E_V4DImode,
- gen_rtvec_v (w, round_data));
- round_reg = gen_reg_rtx (E_V4DImode);
- }
- else if (mode == E_V8SFmode)
- {
-
- round_data_rtx = gen_rtx_CONST_VECTOR (E_V8SImode,
- gen_rtvec_v (w, round_data));
- round_reg = gen_reg_rtx (E_V8SImode);
- }
- else
- {
- round_data_rtx = gen_rtx_CONST_VECTOR (mode,
- gen_rtvec_v (w, round_data));
- round_reg = gen_reg_rtx (mode);
- }
-
- emit_move_insn (round_reg, round_data_rtx);
- switch (mode)
- {
- case E_V32QImode:
- emit_insn (gen_andv32qi3 (mask, mask, round_reg));
- break;
- case E_V16HImode:
- emit_insn (gen_andv16hi3 (mask, mask, round_reg));
- break;
- case E_V8SImode:
- case E_V8SFmode:
- emit_insn (gen_andv8si3 (mask, mask, round_reg));
- break;
- case E_V4DImode:
- case E_V4DFmode:
- emit_insn (gen_andv4di3 (mask, mask, round_reg));
- break;
- default:
- gcc_unreachable ();
- break;
- }
+ rtx t = gen_const_vec_duplicate (maskmode, GEN_INT (0x1f));
+ mask = expand_binop (maskmode, and_optab, mask, t, NULL_RTX, false,
+ OPTAB_DIRECT);
}
if (mode == V4DImode || mode == V4DFmode)
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -mlasx" } */
+/* { dg-require-effective-target loongarch_asx_hw } */
+
+[[gnu::vector_size (32)]] char a, b, c;
+
+[[gnu::noipa]] void
+test (void)
+{
+ a = __builtin_shuffle (a, b, c);
+}
+
+int
+main (void)
+{
+ a = (typeof (a)){} + 5;
+ b = (typeof (a)){} + 6;
+ c = (typeof (a)){} + 64;
+ test ();
+ if (a[0] != 5)
+ __builtin_trap ();
+}
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -mlasx" } */
+/* { dg-require-effective-target loongarch_asx_hw } */
+
+[[gnu::vector_size(32)]] short a, b, c;
+
+[[gnu::noipa]] void
+test (void)
+{
+ a = __builtin_shuffle(a, b, c) + c;
+}
+
+int
+main (void)
+{
+ a = (typeof (a)){} + 1;
+ b = (typeof (b)){} + 2;
+ c = (typeof (c)){} + 128;
+ test ();
+ if (a[0] != 129)
+ __builtin_trap ();
+}