@@ -41,9 +41,8 @@ static bool is_supported_natively(Context* ctx, const Type* element_type) {
41
41
42
42
static const Node * build_subgroup_first (Context * ctx , BodyBuilder * bb , const Node * src );
43
43
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 ) {
45
45
IrArena * a = ctx -> rewriter .dst_arena ;
46
- BodyBuilder * bb = begin_body (a );
47
46
const Type * original_t = t ;
48
47
t = get_maybe_nominal_type_body (t );
49
48
switch (is_type (t )) {
@@ -56,11 +55,7 @@ static void build_fn_body(Context* ctx, Node* fn, const Node* param, const Type*
56
55
const Node * e = gen_extract (bb , param , singleton (uint32_literal (a , i )));
57
56
elements [i ] = build_subgroup_first (ctx , bb , e );
58
57
}
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 ));
64
59
}
65
60
case Type_Int_TAG : {
66
61
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*
73
68
hi = convert_int_zero_extend (bb , it , hi );
74
69
lo = convert_int_zero_extend (bb , it , lo );
75
70
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 ));
82
72
}
83
73
break ;
84
74
}
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
+ }
85
79
default : break ;
86
80
}
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
+ }
87
95
88
96
log_string (ERROR , "subgroup_first emulation is not supported for " );
89
97
log_node (ERROR , t );
0 commit comments