Hi Richard,
I have attached a WIP untested patch for PR96463.
IIUC, the PR suggests to transform
lhs = svld1rq ({-1, -1, ...}, &v[0])
into:
lhs = vec_perm_expr<v, v, {0, 0, ...}>
if v is vector of 4 elements, and each element is 32 bits on little
endian target ?
I am sorry if this sounds like a silly question, but I am not sure how
to convert a vector of type int32x4_t into svint32_t ? In the patch, I
simply used NOP_EXPR (which I expected to fail), and gave type error
during gimple verification:
svint32_t
foo (int32x4_t x)
{
return svld1rq (svptrue_b8 (), &x[0]);
}
transformed to:
EMERGENCY DUMP:
svint32_t foo (int32x4_t x)
{
svint32_t _3;
__Int32x4_t _4;
<bb 2> :
_4 = VEC_PERM_EXPR <x_5(D), x_5(D), { 0, 0, 0, 0 }>;
_3 = (svint32_t) _4;
return _3;
}
and ICE's with:
pr96463.c:8:1: error: invalid vector types in nop conversion
8 | }
| ^
svint32_t
__Int32x4_t
_3 = (svint32_t) _4;
during GIMPLE pass: ccp
Could you please suggest how to proceed ?
Thanks,
Prathamesh
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 02e42a71e5e..3834f33443a 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -44,6 +44,13 @@
#include "aarch64-sve-builtins-shapes.h"
#include "aarch64-sve-builtins-base.h"
#include "aarch64-sve-builtins-functions.h"
+#include "print-tree.h"
+#include "gimple-pretty-print.h"
+
+/* ??? Including tree-ssanames.h requires including other header dependencies.
+ Just including the prototype for now. */
+extern tree make_ssa_name_fn (struct function *, tree, gimple *,
+ unsigned int version = 0);
using namespace aarch64_sve;
@@ -1207,6 +1214,52 @@ public:
insn_code icode = code_for_aarch64_sve_ld1rq (e.vector_mode (0));
return e.use_contiguous_load_insn (icode);
}
+
+ gimple *
+ fold (gimple_folder &f) const OVERRIDE
+ {
+ tree arg0 = gimple_call_arg (f.call, 0);
+ tree arg1 = gimple_call_arg (f.call, 1);
+
+ /* Transform:
+ lhs = svld1rq ({-1, -1, ... }, &v[0])
+ into:
+ tmp = vec_perm_expr<v, v, {0, 0, ...}>.
+ lhs = nop_expr tmp
+ on little endian target. */
+
+ if (!BYTES_BIG_ENDIAN
+ && integer_all_onesp (arg0)
+ && TREE_CODE (arg1) == ADDR_EXPR)
+ {
+ tree t = TREE_OPERAND (arg1, 0);
+ if (TREE_CODE (t) == ARRAY_REF)
+ {
+ tree index = TREE_OPERAND (t, 1);
+ t = TREE_OPERAND (t, 0);
+ if (integer_zerop (index) && TREE_CODE (t) == VIEW_CONVERT_EXPR)
+ {
+ t = TREE_OPERAND (t, 0);
+ tree vectype = TREE_TYPE (t);
+ if (VECTOR_TYPE_P (vectype)
+ && known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
+ && wi::to_wide (TYPE_SIZE (vectype)) == 128)
+ {
+ tree new_temp = ::make_ssa_name_fn (cfun, vectype, NULL);
+ tree zero_vec = build_vector_from_val (vectype, index);
+ gimple *g = gimple_build_assign (new_temp, VEC_PERM_EXPR,
t, t, zero_vec);
+ /* ??? How to convert between vector types if
gimple_call_lhs (f.call) and
+ new_temp have different types ? */
+ gimple *g2 = gimple_build_assign (gimple_call_lhs (f.call),
NOP_EXPR, new_temp);
+ gsi_insert_before (f.gsi, g, GSI_SAME_STMT);
+ return g2;
+ }
+ }
+ }
+ }
+
+ return NULL;
+ }
};
class svld1ro_impl : public load_replicate