@@ -41,9 +41,8 @@ static bool is_supported_natively(Context* ctx, const Type* element_type) {
4141
4242static const Node * build_subgroup_first (Context * ctx , BodyBuilder * bb , const Node * src );
4343
44- static void build_fn_body (Context * ctx , Node * fn , const Node * param , const Type * t ) {
44+ static const Node * generate (Context * ctx , BodyBuilder * bb , const Node * t , const Node * param ) {
4545 IrArena * a = ctx -> rewriter .dst_arena ;
46- BodyBuilder * bb = begin_body (a );
4746 const Type * original_t = t ;
4847 t = get_maybe_nominal_type_body (t );
4948 switch (is_type (t )) {
@@ -56,11 +55,7 @@ static void build_fn_body(Context* ctx, Node* fn, const Node* param, const Type*
5655 const Node * e = gen_extract (bb , param , singleton (uint32_literal (a , i )));
5756 elements [i ] = build_subgroup_first (ctx , bb , e );
5857 }
59- fn -> payload .fun .body = finish_body (bb , fn_ret (a , (Return ) {
60- .fn = fn ,
61- .args = singleton (composite_helper (a , original_t , nodes (a , element_types .count , elements )))
62- }));
63- return ;
58+ return composite_helper (a , original_t , nodes (a , element_types .count , elements ));
6459 }
6560 case Type_Int_TAG : {
6661 if (t -> payload .int_type .width == IntTy64 ) {
@@ -73,17 +68,30 @@ static void build_fn_body(Context* ctx, Node* fn, const Node* param, const Type*
7368 hi = convert_int_zero_extend (bb , it , hi );
7469 lo = convert_int_zero_extend (bb , it , lo );
7570 hi = gen_primop_e (bb , lshift_op , empty (a ), mk_nodes (a , hi , int32_literal (a , 32 )));
76- const Node * result = gen_primop_e (bb , or_op , empty (a ), mk_nodes (a , lo , hi ));
77- fn -> payload .fun .body = finish_body (bb , fn_ret (a , (Return ) {
78- .fn = fn ,
79- .args = singleton (result )
80- }));
81- return ;
71+ return gen_primop_e (bb , or_op , empty (a ), mk_nodes (a , lo , hi ));
8272 }
8373 break ;
8474 }
75+ case Type_PtrType_TAG : {
76+ param = gen_reinterpret_cast (bb , uint64_type (a ), param );
77+ return gen_reinterpret_cast (bb , t , generate (ctx , bb , uint64_type (a ), param ));
78+ }
8579 default : break ;
8680 }
81+ return NULL ;
82+ }
83+
84+ static void build_fn_body (Context * ctx , Node * fn , const Node * param , const Type * t ) {
85+ IrArena * a = ctx -> rewriter .dst_arena ;
86+ BodyBuilder * bb = begin_body (a );
87+ const Node * result = generate (ctx , bb , t , param );
88+ if (result ) {
89+ fn -> payload .fun .body = finish_body (bb , fn_ret (a , (Return ) {
90+ .fn = fn ,
91+ .args = singleton (result )
92+ }));
93+ return ;
94+ }
8795
8896 log_string (ERROR , "subgroup_first emulation is not supported for " );
8997 log_node (ERROR , t );
0 commit comments