mirror of https://github.com/llvm/torch-mlir
NFC: Prefactor some basicpy ops in advance of more type work.
* Organizes the BasicPyOps.td file by function. * Renamed `to_boolean` -> `as_predicate_value` (trying to consistently use "predicate" to refer to i1/low-level types and Bool/Boolean to refer to Python bool types).pull/128/head
parent
b0623b7793
commit
bea0af419d
|
@ -90,61 +90,19 @@ def CompareOperationAttr : StrEnumAttr<
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Operations
|
// Constant and constructor operations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def Basicpy_BinaryCompareOp : Basicpy_Op<"binary_compare", []> {
|
|
||||||
let summary = "Performs a comparison between two operands";
|
|
||||||
let description = [{
|
|
||||||
This op performs only one step of a potentially multi-step short
|
|
||||||
circuit comparison.
|
|
||||||
See: https://docs.python.org/3/reference/expressions.html#comparisons
|
|
||||||
}];
|
|
||||||
let arguments = (ins
|
|
||||||
AnyType:$left,
|
|
||||||
AnyType:$right,
|
|
||||||
CompareOperationAttr:$operation
|
|
||||||
);
|
|
||||||
let results = (outs
|
|
||||||
Basicpy_BoolType:$result
|
|
||||||
);
|
|
||||||
let assemblyFormat = "$left $operation $right attr-dict `:` type(operands)";
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_BinaryExprOp : Basicpy_Op<"binary_expr", []> {
|
|
||||||
let summary = "Binary expression";
|
|
||||||
let description = [{
|
|
||||||
An expression between two operands as generated by the AST BinOp node.
|
|
||||||
}];
|
|
||||||
let arguments = (ins
|
|
||||||
AnyType:$left,
|
|
||||||
AnyType:$right,
|
|
||||||
BinaryOperationAttr:$operation
|
|
||||||
);
|
|
||||||
let results = (outs
|
|
||||||
AnyType:$result
|
|
||||||
);
|
|
||||||
let assemblyFormat = "$left $operation $right attr-dict `:` functional-type(operands, results)";
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_BoolCastOp : Basicpy_Op<"bool_cast", [NoSideEffect]> {
|
|
||||||
let summary = "Casts between BoolType and i1";
|
|
||||||
let description = [{
|
|
||||||
When interfacing with lower level dialect or progressively lowering
|
|
||||||
the Python BoolType away, it is often necessary to cast between it and
|
|
||||||
i1, which is used to represent bool-ness at lower levels.
|
|
||||||
}];
|
|
||||||
let arguments = (ins BoolOrI1Type:$operand);
|
|
||||||
let results = (outs BoolOrI1Type:$result);
|
|
||||||
let assemblyFormat = "$operand attr-dict `:` type(operands) `->` type(results)";
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_BoolConstantOp : Basicpy_Op<"bool_constant", [
|
def Basicpy_BoolConstantOp : Basicpy_Op<"bool_constant", [
|
||||||
ConstantLike, NoSideEffect]> {
|
ConstantLike, NoSideEffect]> {
|
||||||
let summary = "A boolean constant";
|
let summary = "A boolean constant";
|
||||||
let description = [{
|
let description = [{
|
||||||
A constant of type !basicpy.BoolType that can take either an i1 value
|
A constant of type !basicpy.BoolType that can take either an i1 value
|
||||||
of 0 (False) or 1 (True).
|
of 0 (False) or 1 (True).
|
||||||
|
|
||||||
|
Note that as in Python a BoolType can be thought of as an object, whereas
|
||||||
|
the corresponding i1 is a numeric type suitable for use in contexts where
|
||||||
|
storage format matters (or for interop with lower level dialects).
|
||||||
}];
|
}];
|
||||||
let arguments = (ins I1Attr:$value);
|
let arguments = (ins I1Attr:$value);
|
||||||
let results = (outs
|
let results = (outs
|
||||||
|
@ -230,6 +188,115 @@ def Basicpy_BytesConstantOp : Basicpy_Op<"bytes_constant", [
|
||||||
let hasFolder = 1;
|
let hasFolder = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def Basicpy_SingletonOp : Basicpy_Op<"singleton", [
|
||||||
|
ConstantLike, NoSideEffect]> {
|
||||||
|
let summary = "Constant value for a singleton type";
|
||||||
|
let description = [{
|
||||||
|
Some types only have a single possible value, represented by the
|
||||||
|
SingletonAttr. This op allows creating constants of these types.
|
||||||
|
}];
|
||||||
|
let arguments = (ins);
|
||||||
|
let results = (outs
|
||||||
|
Basicpy_SingletonType:$result
|
||||||
|
);
|
||||||
|
let assemblyFormat = "attr-dict `:` type($result)";
|
||||||
|
let hasFolder = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
def Basicpy_StrConstantOp : Basicpy_Op<"str_constant", [
|
||||||
|
ConstantLike, NoSideEffect]> {
|
||||||
|
let summary = "Constant string value";
|
||||||
|
let description = [{
|
||||||
|
A string value of StrType. The value is represented by a StringAttr
|
||||||
|
that is UTF-8 encoded.
|
||||||
|
}];
|
||||||
|
let arguments = (ins
|
||||||
|
StrAttr:$value
|
||||||
|
);
|
||||||
|
let results = (outs
|
||||||
|
Basicpy_StrType:$result
|
||||||
|
);
|
||||||
|
let assemblyFormat = "$value attr-dict";
|
||||||
|
let hasFolder = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Casting and coercion operations
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def Basicpy_AsPredicateValueOp : Basicpy_Op<"as_predicate_value",
|
||||||
|
[NoSideEffect]> {
|
||||||
|
let summary = "Evaluates an input to an i1 predicate value";
|
||||||
|
let description = [{
|
||||||
|
Applies the rules for interpreting a type as a boolean, returning an i1
|
||||||
|
indicating the truthiness of the operand. Since the output of this op
|
||||||
|
is intended to drive lower-level control flow, the i1 type is used (not
|
||||||
|
the user level BoolType).
|
||||||
|
}];
|
||||||
|
let arguments = (ins AnyType:$operand);
|
||||||
|
let results = (outs I1:$result);
|
||||||
|
let assemblyFormat = "$operand attr-dict `:` type($operand)";
|
||||||
|
}
|
||||||
|
|
||||||
|
def Basicpy_BoolCastOp : Basicpy_Op<"bool_cast", [NoSideEffect]> {
|
||||||
|
let summary = "Casts between BoolType and i1 (predicate value)";
|
||||||
|
let description = [{
|
||||||
|
When interfacing with lower level dialect or progressively lowering
|
||||||
|
the Python BoolType away, it is often necessary to cast between it and
|
||||||
|
i1, which is used to represent bool-ness at lower levels.
|
||||||
|
}];
|
||||||
|
let arguments = (ins BoolOrI1Type:$operand);
|
||||||
|
let results = (outs BoolOrI1Type:$result);
|
||||||
|
let assemblyFormat = "$operand attr-dict `:` type(operands) `->` type(results)";
|
||||||
|
}
|
||||||
|
|
||||||
|
def Basicpy_UnknownCastOp : Basicpy_Op<"unknown_cast", [NoSideEffect]> {
|
||||||
|
let summary = "Casts to and from the UnknownType";
|
||||||
|
let arguments = (ins AnyType:$operand);
|
||||||
|
let results = (outs AnyType:$result);
|
||||||
|
let assemblyFormat = "operands attr-dict `:` type(operands) `->` type(results)";
|
||||||
|
|
||||||
|
let hasCanonicalizer = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Operations
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def Basicpy_BinaryCompareOp : Basicpy_Op<"binary_compare", []> {
|
||||||
|
let summary = "Performs a comparison between two operands";
|
||||||
|
let description = [{
|
||||||
|
This op performs only one step of a potentially multi-step short
|
||||||
|
circuit comparison.
|
||||||
|
See: https://docs.python.org/3/reference/expressions.html#comparisons
|
||||||
|
}];
|
||||||
|
let arguments = (ins
|
||||||
|
AnyType:$left,
|
||||||
|
AnyType:$right,
|
||||||
|
CompareOperationAttr:$operation
|
||||||
|
);
|
||||||
|
let results = (outs
|
||||||
|
Basicpy_BoolType:$result
|
||||||
|
);
|
||||||
|
let assemblyFormat = "$left $operation $right attr-dict `:` type(operands)";
|
||||||
|
}
|
||||||
|
|
||||||
|
def Basicpy_BinaryExprOp : Basicpy_Op<"binary_expr", []> {
|
||||||
|
let summary = "Binary expression";
|
||||||
|
let description = [{
|
||||||
|
An expression between two operands as generated by the AST BinOp node.
|
||||||
|
}];
|
||||||
|
let arguments = (ins
|
||||||
|
AnyType:$left,
|
||||||
|
AnyType:$right,
|
||||||
|
BinaryOperationAttr:$operation
|
||||||
|
);
|
||||||
|
let results = (outs
|
||||||
|
AnyType:$result
|
||||||
|
);
|
||||||
|
let assemblyFormat = "$left $operation $right attr-dict `:` functional-type(operands, results)";
|
||||||
|
}
|
||||||
|
|
||||||
def Basicpy_ExecOp : Basicpy_Op<"exec", [
|
def Basicpy_ExecOp : Basicpy_Op<"exec", [
|
||||||
SingleBlockImplicitTerminator<"ExecDiscardOp">]> {
|
SingleBlockImplicitTerminator<"ExecDiscardOp">]> {
|
||||||
let summary = "Evaluates an expression being executed as a statement";
|
let summary = "Evaluates an expression being executed as a statement";
|
||||||
|
@ -427,58 +494,4 @@ def Basicpy_SlotObjectGetOp : Basicpy_Op<"slot_object_get", [
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
def Basicpy_StrConstantOp : Basicpy_Op<"str_constant", [
|
|
||||||
ConstantLike, NoSideEffect]> {
|
|
||||||
let summary = "Constant string value";
|
|
||||||
let description = [{
|
|
||||||
A string value of StrType. The value is represented by a StringAttr
|
|
||||||
that is UTF-8 encoded.
|
|
||||||
}];
|
|
||||||
let arguments = (ins
|
|
||||||
StrAttr:$value
|
|
||||||
);
|
|
||||||
let results = (outs
|
|
||||||
Basicpy_StrType:$result
|
|
||||||
);
|
|
||||||
let assemblyFormat = "$value attr-dict";
|
|
||||||
let hasFolder = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_SingletonOp : Basicpy_Op<"singleton", [
|
|
||||||
ConstantLike, NoSideEffect]> {
|
|
||||||
let summary = "Constant value for a singleton type";
|
|
||||||
let description = [{
|
|
||||||
Some types only have a single possible value, represented by the
|
|
||||||
SingletonAttr. This op allows creating constants of these types.
|
|
||||||
}];
|
|
||||||
let arguments = (ins);
|
|
||||||
let results = (outs
|
|
||||||
Basicpy_SingletonType:$result
|
|
||||||
);
|
|
||||||
let assemblyFormat = "attr-dict `:` type($result)";
|
|
||||||
let hasFolder = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_ToBooleanOp : Basicpy_Op<"to_boolean", [NoSideEffect]> {
|
|
||||||
let summary = "Evaluates an input to an i1 boolean value";
|
|
||||||
let description = [{
|
|
||||||
Applies the rules for interpreting a type as a boolean, returning an i1
|
|
||||||
indicating the truthiness of the operand. Since the output of this op
|
|
||||||
is intended to drive lower-level control flow, the i1 type is used (not
|
|
||||||
the user level BoolType).
|
|
||||||
}];
|
|
||||||
let arguments = (ins AnyType:$operand);
|
|
||||||
let results = (outs I1:$result);
|
|
||||||
let assemblyFormat = "$operand attr-dict `:` type($operand)";
|
|
||||||
}
|
|
||||||
|
|
||||||
def Basicpy_UnknownCastOp : Basicpy_Op<"unknown_cast", [NoSideEffect]> {
|
|
||||||
let summary = "Casts to and from the UnknownType";
|
|
||||||
let arguments = (ins AnyType:$operand);
|
|
||||||
let results = (outs AnyType:$result);
|
|
||||||
let assemblyFormat = "operands attr-dict `:` type(operands) `->` type(results)";
|
|
||||||
|
|
||||||
let hasCanonicalizer = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NPCOMP_DIALECT_BASICPY_IR_BASICPY_OPS
|
#endif // NPCOMP_DIALECT_BASICPY_IR_BASICPY_OPS
|
||||||
|
|
|
@ -215,11 +215,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converts the to_boolean op for numeric types.
|
// Converts the as_predicate_value op for numeric types.
|
||||||
class NumericToBoolean : public OpRewritePattern<Basicpy::ToBooleanOp> {
|
class NumericToPredicateValue : public OpRewritePattern<Basicpy::AsPredicateValueOp> {
|
||||||
public:
|
public:
|
||||||
using OpRewritePattern::OpRewritePattern;
|
using OpRewritePattern::OpRewritePattern;
|
||||||
LogicalResult matchAndRewrite(Basicpy::ToBooleanOp op,
|
LogicalResult matchAndRewrite(Basicpy::AsPredicateValueOp op,
|
||||||
PatternRewriter &rewriter) const override {
|
PatternRewriter &rewriter) const override {
|
||||||
auto loc = op.getLoc();
|
auto loc = op.getLoc();
|
||||||
auto operandType = op.operand().getType();
|
auto operandType = op.operand().getType();
|
||||||
|
@ -245,5 +245,5 @@ void mlir::NPCOMP::populateBasicpyToStdPrimitiveOpPatterns(
|
||||||
MLIRContext *context, OwningRewritePatternList &patterns) {
|
MLIRContext *context, OwningRewritePatternList &patterns) {
|
||||||
patterns.insert<NumericBinaryExpr>(context);
|
patterns.insert<NumericBinaryExpr>(context);
|
||||||
patterns.insert<NumericCompare>(context);
|
patterns.insert<NumericCompare>(context);
|
||||||
patterns.insert<NumericToBoolean>(context);
|
patterns.insert<NumericToPredicateValue>(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ public:
|
||||||
op);
|
op);
|
||||||
return WalkResult::advance();
|
return WalkResult::advance();
|
||||||
}
|
}
|
||||||
if (auto op = dyn_cast<ToBooleanOp>(childOp)) {
|
if (auto op = dyn_cast<AsPredicateValueOp>(childOp)) {
|
||||||
// Note that the result is always i1 and not subject to type
|
// Note that the result is always i1 and not subject to type
|
||||||
// inference.
|
// inference.
|
||||||
equations.getTypeNode(op.operand());
|
equations.getTypeNode(op.operand());
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
// addSubtypeConstraint(op.false_value(), op.true_value(), op);
|
// addSubtypeConstraint(op.false_value(), op.true_value(), op);
|
||||||
return WalkResult::advance();
|
return WalkResult::advance();
|
||||||
}
|
}
|
||||||
if (auto op = dyn_cast<ToBooleanOp>(childOp)) {
|
if (auto op = dyn_cast<AsPredicateValueOp>(childOp)) {
|
||||||
// Note that the result is always i1 and not subject to type
|
// Note that the result is always i1 and not subject to type
|
||||||
// inference.
|
// inference.
|
||||||
resolveValueType(op.operand());
|
resolveValueType(op.operand());
|
||||||
|
|
|
@ -255,7 +255,7 @@ class ExpressionImporter(BaseNodeVisitor):
|
||||||
next_value = self.sub_evaluate(next_node)
|
next_value = self.sub_evaluate(next_node)
|
||||||
if not next_nodes:
|
if not next_nodes:
|
||||||
return next_value
|
return next_value
|
||||||
condition_value = ir_h.basicpy_to_boolean_op(next_value).result
|
condition_value = ir_h.basicpy_as_predicate_value_op(next_value).result
|
||||||
if_op, then_ip, else_ip = ir_h.scf_if_op([ir_h.basicpy_UnknownType],
|
if_op, then_ip, else_ip = ir_h.scf_if_op([ir_h.basicpy_UnknownType],
|
||||||
condition_value, True)
|
condition_value, True)
|
||||||
orig_ip = ir_h.builder.insertion_point
|
orig_ip = ir_h.builder.insertion_point
|
||||||
|
@ -347,7 +347,7 @@ class ExpressionImporter(BaseNodeVisitor):
|
||||||
|
|
||||||
def visit_IfExp(self, ast_node):
|
def visit_IfExp(self, ast_node):
|
||||||
ir_h = self.fctx.ir_h
|
ir_h = self.fctx.ir_h
|
||||||
test_result = ir_h.basicpy_to_boolean_op(self.sub_evaluate(
|
test_result = ir_h.basicpy_as_predicate_value_op(self.sub_evaluate(
|
||||||
ast_node.test)).result
|
ast_node.test)).result
|
||||||
if_op, then_ip, else_ip = ir_h.scf_if_op([ir_h.basicpy_UnknownType],
|
if_op, then_ip, else_ip = ir_h.scf_if_op([ir_h.basicpy_UnknownType],
|
||||||
test_result, True)
|
test_result, True)
|
||||||
|
@ -386,7 +386,7 @@ class ExpressionImporter(BaseNodeVisitor):
|
||||||
operand_value = self.sub_evaluate(ast_node.operand)
|
operand_value = self.sub_evaluate(ast_node.operand)
|
||||||
if isinstance(op, ast.Not):
|
if isinstance(op, ast.Not):
|
||||||
# Special handling for logical-not.
|
# Special handling for logical-not.
|
||||||
condition_value = ir_h.basicpy_to_boolean_op(operand_value).result
|
condition_value = ir_h.basicpy_as_predicate_value_op(operand_value).result
|
||||||
true_value = ir_h.basicpy_bool_constant_op(True).result
|
true_value = ir_h.basicpy_bool_constant_op(True).result
|
||||||
false_value = ir_h.basicpy_bool_constant_op(False).result
|
false_value = ir_h.basicpy_bool_constant_op(False).result
|
||||||
self.value = ir_h.select_op(condition_value, false_value,
|
self.value = ir_h.select_op(condition_value, false_value,
|
||||||
|
|
|
@ -90,8 +90,8 @@ class DialectHelper(_BaseDialectHelper):
|
||||||
attrs = c.dictionary_attr({"value": c.string_attr(value.encode("utf-8"))})
|
attrs = c.dictionary_attr({"value": c.string_attr(value.encode("utf-8"))})
|
||||||
return self.op("basicpy.str_constant", [self.basicpy_StrType], [], attrs)
|
return self.op("basicpy.str_constant", [self.basicpy_StrType], [], attrs)
|
||||||
|
|
||||||
def basicpy_to_boolean_op(self, value):
|
def basicpy_as_predicate_value_op(self, value):
|
||||||
return self.op("basicpy.to_boolean", [self.i1_type], [value])
|
return self.op("basicpy.as_predicate_value", [self.i1_type], [value])
|
||||||
|
|
||||||
def basicpy_unknown_cast_op(self, result_type, operand):
|
def basicpy_unknown_cast_op(self, result_type, operand):
|
||||||
return self.op("basicpy.unknown_cast", [result_type], [operand])
|
return self.op("basicpy.unknown_cast", [result_type], [operand])
|
||||||
|
|
|
@ -14,9 +14,9 @@ def logical_and():
|
||||||
x = 1
|
x = 1
|
||||||
y = 0
|
y = 0
|
||||||
z = 2
|
z = 2
|
||||||
# CHECK: %[[XBOOL:.*]] = basicpy.to_boolean %[[X]]
|
# CHECK: %[[XBOOL:.*]] = basicpy.as_predicate_value %[[X]]
|
||||||
# CHECK: %[[IF0:.*]] = scf.if %[[XBOOL]] -> (!basicpy.UnknownType) {
|
# CHECK: %[[IF0:.*]] = scf.if %[[XBOOL]] -> (!basicpy.UnknownType) {
|
||||||
# CHECK: %[[YBOOL:.*]] = basicpy.to_boolean %[[Y]]
|
# CHECK: %[[YBOOL:.*]] = basicpy.as_predicate_value %[[Y]]
|
||||||
# CHECK: %[[IF1:.*]] = scf.if %[[YBOOL]] -> (!basicpy.UnknownType) {
|
# CHECK: %[[IF1:.*]] = scf.if %[[YBOOL]] -> (!basicpy.UnknownType) {
|
||||||
# CHECK: %[[ZCAST:.*]] = basicpy.unknown_cast %[[Z]]
|
# CHECK: %[[ZCAST:.*]] = basicpy.unknown_cast %[[Z]]
|
||||||
# CHECK: scf.yield %[[ZCAST]]
|
# CHECK: scf.yield %[[ZCAST]]
|
||||||
|
@ -39,12 +39,12 @@ def logical_or():
|
||||||
# CHECK: %[[X:.*]] = constant 0
|
# CHECK: %[[X:.*]] = constant 0
|
||||||
# CHECK: %[[Y:.*]] = constant 1
|
# CHECK: %[[Y:.*]] = constant 1
|
||||||
# CHECK: %[[Z:.*]] = constant 2
|
# CHECK: %[[Z:.*]] = constant 2
|
||||||
# CHECK: %[[XBOOL:.*]] = basicpy.to_boolean %[[X]]
|
# CHECK: %[[XBOOL:.*]] = basicpy.as_predicate_value %[[X]]
|
||||||
# CHECK: %[[IF0:.*]] = scf.if %[[XBOOL]] -> (!basicpy.UnknownType) {
|
# CHECK: %[[IF0:.*]] = scf.if %[[XBOOL]] -> (!basicpy.UnknownType) {
|
||||||
# CHECK: %[[XCAST:.*]] = basicpy.unknown_cast %[[X]]
|
# CHECK: %[[XCAST:.*]] = basicpy.unknown_cast %[[X]]
|
||||||
# CHECK: scf.yield %[[XCAST]]
|
# CHECK: scf.yield %[[XCAST]]
|
||||||
# CHECK: } else {
|
# CHECK: } else {
|
||||||
# CHECK: %[[YBOOL:.*]] = basicpy.to_boolean %[[Y]]
|
# CHECK: %[[YBOOL:.*]] = basicpy.as_predicate_value %[[Y]]
|
||||||
# CHECK: %[[IF1:.*]] = scf.if %[[YBOOL]] -> (!basicpy.UnknownType) {
|
# CHECK: %[[IF1:.*]] = scf.if %[[YBOOL]] -> (!basicpy.UnknownType) {
|
||||||
# CHECK: %[[YCAST:.*]] = basicpy.unknown_cast %[[Y]]
|
# CHECK: %[[YCAST:.*]] = basicpy.unknown_cast %[[Y]]
|
||||||
# CHECK: scf.yield %[[YCAST]]
|
# CHECK: scf.yield %[[YCAST]]
|
||||||
|
@ -68,7 +68,7 @@ def logical_not():
|
||||||
x = 1
|
x = 1
|
||||||
# CHECK-DAG: %[[TRUE:.*]] = basicpy.bool_constant true
|
# CHECK-DAG: %[[TRUE:.*]] = basicpy.bool_constant true
|
||||||
# CHECK-DAG: %[[FALSE:.*]] = basicpy.bool_constant false
|
# CHECK-DAG: %[[FALSE:.*]] = basicpy.bool_constant false
|
||||||
# CHECK-DAG: %[[CONDITION:.*]] = basicpy.to_boolean %[[X]]
|
# CHECK-DAG: %[[CONDITION:.*]] = basicpy.as_predicate_value %[[X]]
|
||||||
# CHECK-DAG: %{{.*}} = select %[[CONDITION]], %[[FALSE]], %[[TRUE]] : !basicpy.BoolType
|
# CHECK-DAG: %{{.*}} = select %[[CONDITION]], %[[FALSE]], %[[TRUE]] : !basicpy.BoolType
|
||||||
return not x
|
return not x
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ def logical_not():
|
||||||
def conditional():
|
def conditional():
|
||||||
# CHECK: %[[X:.*]] = constant 1
|
# CHECK: %[[X:.*]] = constant 1
|
||||||
x = 1
|
x = 1
|
||||||
# CHECK: %[[CONDITION:.*]] = basicpy.to_boolean %[[X]]
|
# CHECK: %[[CONDITION:.*]] = basicpy.as_predicate_value %[[X]]
|
||||||
# CHECK: %[[IF0:.*]] = scf.if %[[CONDITION]] -> (!basicpy.UnknownType) {
|
# CHECK: %[[IF0:.*]] = scf.if %[[CONDITION]] -> (!basicpy.UnknownType) {
|
||||||
# CHECK: %[[TWO:.*]] = constant 2 : i64
|
# CHECK: %[[TWO:.*]] = constant 2 : i64
|
||||||
# CHECK: %[[TWO_CAST:.*]] = basicpy.unknown_cast %[[TWO]]
|
# CHECK: %[[TWO_CAST:.*]] = basicpy.unknown_cast %[[TWO]]
|
||||||
|
|
Loading…
Reference in New Issue