@@ -263,6 +263,37 @@ void BinaryOpExpression::flatten(FlattenContext *ctx) {
263
263
stmt = ctx->back_stmt ();
264
264
}
265
265
266
+ void make_ifte (Expression::FlattenContext *ctx,
267
+ DataType ret_type,
268
+ Expr cond,
269
+ Expr true_val,
270
+ Expr false_val) {
271
+ auto result = ctx->push_back <AllocaStmt>(ret_type);
272
+ flatten_rvalue (cond, ctx);
273
+ auto if_stmt = ctx->push_back <IfStmt>(cond->stmt );
274
+
275
+ Expression::FlattenContext lctx;
276
+ lctx.current_block = ctx->current_block ;
277
+ flatten_rvalue (true_val, &lctx);
278
+ lctx.push_back <LocalStoreStmt>(result, true_val->stmt );
279
+
280
+ Expression::FlattenContext rctx;
281
+ rctx.current_block = ctx->current_block ;
282
+ flatten_rvalue (false_val, &rctx);
283
+ rctx.push_back <LocalStoreStmt>(result, false_val->stmt );
284
+
285
+ auto true_block = std::make_unique<Block>();
286
+ true_block->set_statements (std::move (lctx.stmts ));
287
+ if_stmt->set_true_statements (std::move (true_block));
288
+
289
+ auto false_block = std::make_unique<Block>();
290
+ false_block->set_statements (std::move (rctx.stmts ));
291
+ if_stmt->set_false_statements (std::move (false_block));
292
+
293
+ ctx->push_back <LocalLoadStmt>(LocalAddress (result, 0 ));
294
+ return ;
295
+ }
296
+
266
297
void TernaryOpExpression::type_check (CompileConfig *) {
267
298
TI_ASSERT_TYPE_CHECKED (op1);
268
299
TI_ASSERT_TYPE_CHECKED (op2);
@@ -276,21 +307,27 @@ void TernaryOpExpression::type_check(CompileConfig *) {
276
307
ternary_type_name (type), op1->ret_type ->to_string (),
277
308
op2->ret_type ->to_string (), op3->ret_type ->to_string ()));
278
309
};
279
- if (!is_integral (op1_type) || !op2_type->is <PrimitiveType>() ||
280
- !op3_type->is <PrimitiveType>())
310
+ if (op1_type != PrimitiveType::i32)
311
+ error ();
312
+ if (!op2_type->is <PrimitiveType>() || !op3_type->is <PrimitiveType>())
281
313
error ();
282
314
ret_type = promoted_type (op2_type, op3_type);
283
315
}
284
316
285
317
void TernaryOpExpression::flatten (FlattenContext *ctx) {
286
318
// if (stmt)
287
319
// return;
288
- flatten_rvalue (op1, ctx);
289
- flatten_rvalue (op2, ctx);
290
- flatten_rvalue (op3, ctx);
291
- ctx->push_back (
292
- std::make_unique<TernaryOpStmt>(type, op1->stmt , op2->stmt , op3->stmt ));
320
+ if (type == TernaryOpType::select ) {
321
+ flatten_rvalue (op1, ctx);
322
+ flatten_rvalue (op2, ctx);
323
+ flatten_rvalue (op3, ctx);
324
+ ctx->push_back (
325
+ std::make_unique<TernaryOpStmt>(type, op1->stmt , op2->stmt , op3->stmt ));
326
+ } else if (type == TernaryOpType::ifte) {
327
+ make_ifte (ctx, ret_type, op1, op2, op3);
328
+ }
293
329
stmt = ctx->back_stmt ();
330
+ stmt->tb = tb;
294
331
}
295
332
296
333
void InternalFuncCallExpression::type_check (CompileConfig *) {
0 commit comments