[ir] select expression

This commit is contained in:
Dzmitry Malyshau 2020-11-12 11:34:25 -05:00 committed by Timo de Kort
parent 8b56f3ef96
commit 5e77653c55
6 changed files with 71 additions and 0 deletions

View File

@ -1208,6 +1208,22 @@ fn write_expression<'a, 'b>(
Cow::Owned(format!("({} {} {})", left_expr, op_str, right_expr))
}
Expression::Select {
condition,
accept,
reject,
} => {
let cond_expr =
write_expression(&builder.expressions[condition], module, builder, manager)?;
let accept_expr =
write_expression(&builder.expressions[accept], module, builder, manager)?;
let reject_expr =
write_expression(&builder.expressions[reject], module, builder, manager)?;
Cow::Owned(format!(
"({} ? {} : {})",
cond_expr, accept_expr, reject_expr
))
}
Expression::Intrinsic { fun, argument } => {
let expr = write_expression(&builder.expressions[argument], module, builder, manager)?;

View File

@ -524,6 +524,19 @@ impl<W: Write> Writer<W> {
//write!(self.out, ")")?;
}
}
crate::Expression::Select {
condition,
accept,
reject,
} => {
write!(self.out, "(")?;
self.put_expression(condition, context)?;
write!(self.out, " ? ")?;
self.put_expression(accept, context)?;
write!(self.out, " : ")?;
self.put_expression(reject, context)?;
write!(self.out, ")")?;
}
crate::Expression::Intrinsic { fun, argument } => {
let op = match fun {
crate::IntrinsicFunction::Any => "any",

View File

@ -1067,6 +1067,31 @@ impl<I: Iterator<Item = u32>> Parser<I> {
},
);
}
Op::Select => {
inst.expect(6)?;
let result_type_id = self.next()?;
let result_id = self.next()?;
let condition = self.next()?;
let o1_id = self.next()?;
let o2_id = self.next()?;
let cond_lexp = self.lookup_expression.lookup(condition)?;
let o1_lexp = self.lookup_expression.lookup(o1_id)?;
let o2_lexp = self.lookup_expression.lookup(o2_id)?;
let expr = crate::Expression::Select {
condition: cond_lexp.handle,
accept: o1_lexp.handle,
reject: o2_lexp.handle,
};
self.lookup_expression.insert(
result_id,
LookupExpression {
handle: expressions.append(expr),
type_id: result_type_id,
},
);
}
Op::VectorShuffle => {
inst.expect_at_least(5)?;
let result_type_id = self.next()?;

View File

@ -619,6 +619,13 @@ pub enum Expression {
left: Handle<Expression>,
right: Handle<Expression>,
},
/// Select between two values based on a condition.
Select {
/// Boolean expression
condition: Handle<Expression>,
accept: Handle<Expression>,
reject: Handle<Expression>,
},
/// Call an intrinsic function.
Intrinsic {
fun: IntrinsicFunction,

View File

@ -79,6 +79,15 @@ where
self.traverse_expr(left);
self.traverse_expr(right);
}
E::Select {
condition,
accept,
reject,
} => {
self.traverse_expr(condition);
self.traverse_expr(accept);
self.traverse_expr(reject);
}
E::Intrinsic { argument, .. } => {
self.traverse_expr(argument);
}

View File

@ -245,6 +245,7 @@ impl Typifier {
| crate::BinaryOperator::ShiftLeft
| crate::BinaryOperator::ShiftRight => self.resolutions[left.index()].clone(),
},
crate::Expression::Select { accept, .. } => self.resolutions[accept.index()].clone(),
crate::Expression::Intrinsic { .. } => unimplemented!(),
crate::Expression::Transpose(expr) => match *self.get(expr, types) {
crate::TypeInner::Matrix {