class svsra_impl : public function_base
{
+public:
+ gimple *
+ fold (gimple_folder &f) const override
+ {
+ /* Fold to svlsr/svasr if op1 is all zeros. */
+ tree op1 = gimple_call_arg (f.call, 0);
+ if (!integer_zerop (op1))
+ return NULL;
+ function_instance instance ("svlsr", functions::svlsr,
+ shapes::binary_uint_opt_n, MODE_n,
+ f.type_suffix_ids, GROUP_none, PRED_x);
+ if (!f.type_suffix (0).unsigned_p)
+ {
+ instance.base_name = "svasr";
+ instance.base = functions::svasr;
+ }
+ gcall *call = f.redirect_call (instance);
+ /* Add a ptrue as predicate, because unlike svsra, svlsr/svasr are
+ predicated intrinsics. */
+ gimple_call_set_arg (call, 0, build_all_ones_cst (f.gp_type ()));
+ /* For svsra, the shift amount (imm3) is uint64_t for all function types,
+ but for svlsr/svasr, imm3 has the same width as the function type. */
+ tree imm3 = gimple_call_arg (f.call, 2);
+ tree imm3_prec = wide_int_to_tree (f.scalar_type (0),
+ wi::to_widest (imm3));
+ gimple_call_set_arg (call, 2, imm3_prec);
+ return call;
+ }
public:
rtx
expand (function_expander &e) const override
TEST_UNIFORM_Z (sra_32_s32_untied, svint32_t,
z0 = svsra_n_s32 (z1, z2, 32),
z0 = svsra (z1, z2, 32))
+
+/*
+** sra_2_s32_zeroop1:
+** asr z0\.s, z1\.s, #2
+** ret
+*/
+TEST_UNIFORM_Z (sra_2_s32_zeroop1, svint32_t,
+ z0 = svsra_n_s32 (svdup_s32 (0), z1, 2),
+ z0 = svsra (svdup_s32 (0), z1, 2))
TEST_UNIFORM_Z (sra_64_s64_untied, svint64_t,
z0 = svsra_n_s64 (z1, z2, 64),
z0 = svsra (z1, z2, 64))
+
+/*
+** sra_2_s64_zeroop1:
+** asr z0\.d, z1\.d, #2
+** ret
+*/
+TEST_UNIFORM_Z (sra_2_s64_zeroop1, svint64_t,
+ z0 = svsra_n_s64 (svdup_s64 (0), z1, 2),
+ z0 = svsra (svdup_s64 (0), z1, 2))
TEST_UNIFORM_Z (sra_32_u32_untied, svuint32_t,
z0 = svsra_n_u32 (z1, z2, 32),
z0 = svsra (z1, z2, 32))
+
+/*
+** sra_2_u32_zeroop1:
+** lsr z0\.s, z1\.s, #2
+** ret
+*/
+TEST_UNIFORM_Z (sra_2_u32_zeroop1, svuint32_t,
+ z0 = svsra_n_u32 (svdup_u32 (0), z1, 2),
+ z0 = svsra (svdup_u32 (0), z1, 2))
TEST_UNIFORM_Z (sra_64_u64_untied, svuint64_t,
z0 = svsra_n_u64 (z1, z2, 64),
z0 = svsra (z1, z2, 64))
+
+/*
+** sra_2_u64_zeroop1:
+** lsr z0\.d, z1\.d, #2
+** ret
+*/
+TEST_UNIFORM_Z (sra_2_u64_zeroop1, svuint64_t,
+ z0 = svsra_n_u64 (svdup_u64 (0), z1, 2),
+ z0 = svsra (svdup_u64 (0), z1, 2))