[mlir] Refactor BoolAttr to be a special case of IntegerAttr
authorRiver Riddle <riddleriver@gmail.com>
Wed, 3 Jun 2020 01:20:38 +0000 (18:20 -0700)
committerRiver Riddle <riddleriver@gmail.com>
Thu, 4 Jun 2020 23:41:24 +0000 (16:41 -0700)
This simplifies a lot of handling of BoolAttr/IntegerAttr. For example, a lot of places currently have to handle both IntegerAttr and BoolAttr. In other places, a decision is made to pick one which can lead to surprising results for users. For example, DenseElementsAttr currently uses BoolAttr for i1 even if the user initialized it with an Array of i1 IntegerAttrs.

Differential Revision: https://reviews.llvm.org/D81047

25 files changed:
mlir/include/mlir/IR/Attributes.h
mlir/lib/Dialect/SCF/SCF.cpp
mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp
mlir/lib/Dialect/StandardOps/IR/Ops.cpp
mlir/lib/IR/AsmPrinter.cpp
mlir/lib/IR/AttributeDetail.h
mlir/lib/IR/Attributes.cpp
mlir/lib/IR/Builders.cpp
mlir/lib/IR/MLIRContext.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Conversion/SCFToStandard/convert-to-cfg.mlir
mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir
mlir/test/Dialect/Standard/canonicalize-cf.mlir
mlir/test/Dialect/Vector/vector-contract-transforms.mlir
mlir/test/EDSC/builder-api-test.cpp
mlir/test/IR/invalid.mlir
mlir/test/IR/parser.mlir
mlir/test/Target/import.ll
mlir/test/Transforms/constant-fold.mlir
mlir/test/Transforms/cse.mlir
mlir/test/Transforms/inlining.mlir
mlir/test/Transforms/sccp-callgraph.mlir
mlir/test/Transforms/sccp.mlir

index cb9fc16..f0e8c5c 100644 (file)
@@ -30,7 +30,6 @@ namespace detail {
 
 struct AffineMapAttributeStorage;
 struct ArrayAttributeStorage;
-struct BoolAttributeStorage;
 struct DictionaryAttributeStorage;
 struct IntegerAttributeStorage;
 struct IntegerSetAttributeStorage;
@@ -131,7 +130,6 @@ namespace StandardAttributes {
 enum Kind {
   AffineMap = Attribute::FIRST_STANDARD_ATTR,
   Array,
-  Bool,
   Dictionary,
   Float,
   Integer,
@@ -243,24 +241,6 @@ public:
 };
 
 //===----------------------------------------------------------------------===//
-// BoolAttr
-//===----------------------------------------------------------------------===//
-
-class BoolAttr : public Attribute::AttrBase<BoolAttr, Attribute,
-                                            detail::BoolAttributeStorage> {
-public:
-  using Base::Base;
-  using ValueType = bool;
-
-  static BoolAttr get(bool value, MLIRContext *context);
-
-  bool getValue() const;
-
-  /// Methods for support type inquiry through isa, cast, and dyn_cast.
-  static bool kindof(unsigned kind) { return kind == StandardAttributes::Bool; }
-};
-
-//===----------------------------------------------------------------------===//
 // DictionaryAttr
 //===----------------------------------------------------------------------===//
 
@@ -410,6 +390,29 @@ public:
 };
 
 //===----------------------------------------------------------------------===//
+// BoolAttr
+
+/// Special case of IntegerAttr to represent boolean integers, i.e., signless i1
+/// integers.
+class BoolAttr : public Attribute {
+public:
+  using Attribute::Attribute;
+  using ValueType = bool;
+
+  static BoolAttr get(bool value, MLIRContext *context);
+
+  /// Enable conversion to IntegerAttr. This uses conversion vs. inheritance to
+  /// avoid bringing in all of IntegerAttrs methods.
+  operator IntegerAttr() const { return IntegerAttr(impl); }
+
+  /// Return the boolean value of this attribute.
+  bool getValue() const;
+
+  /// Methods for support type inquiry through isa, cast, and dyn_cast.
+  static bool classof(Attribute attr);
+};
+
+//===----------------------------------------------------------------------===//
 // IntegerSetAttr
 //===----------------------------------------------------------------------===//
 
index 58edd92..b883bad 100644 (file)
@@ -480,8 +480,6 @@ void IfOp::getSuccessorRegions(Optional<unsigned> index,
   bool condition;
   if (auto condAttr = operands.front().dyn_cast_or_null<IntegerAttr>()) {
     condition = condAttr.getValue().isOneValue();
-  } else if (auto condAttr = operands.front().dyn_cast_or_null<BoolAttr>()) {
-    condition = condAttr.getValue();
   } else {
     // If the condition isn't constant, both regions may be executed.
     regions.push_back(RegionSuccessor(&thenRegion()));
index ac8fee8..aee22c4 100644 (file)
@@ -1302,7 +1302,6 @@ static LogicalResult verify(spirv::ConstantOp constOp) {
   // need to additionally check that the value's attribute type is consistent
   // with the result type.
   switch (value.getKind()) {
-  case StandardAttributes::Bool:
   case StandardAttributes::Integer:
   case StandardAttributes::Float: {
     if (valueType != opType)
@@ -2449,7 +2448,6 @@ static LogicalResult verify(spirv::SpecConstantOp constOp) {
   auto value = constOp.default_value();
 
   switch (value.getKind()) {
-  case StandardAttributes::Bool:
   case StandardAttributes::Integer:
   case StandardAttributes::Float: {
     // Make sure bitwidth is allowed.
index 67d9912..a594c12 100644 (file)
@@ -1269,12 +1269,12 @@ uint32_t Serializer::prepareConstantScalar(Location loc, Attribute valueAttr,
   if (auto floatAttr = valueAttr.dyn_cast<FloatAttr>()) {
     return prepareConstantFp(loc, floatAttr, isSpec);
   }
-  if (auto intAttr = valueAttr.dyn_cast<IntegerAttr>()) {
-    return prepareConstantInt(loc, intAttr, isSpec);
-  }
   if (auto boolAttr = valueAttr.dyn_cast<BoolAttr>()) {
     return prepareConstantBool(loc, boolAttr, isSpec);
   }
+  if (auto intAttr = valueAttr.dyn_cast<IntegerAttr>()) {
+    return prepareConstantInt(loc, intAttr, isSpec);
+  }
 
   return 0;
 }
index 118a111..4f72996 100644 (file)
@@ -1028,8 +1028,6 @@ CondBranchOp::getMutableSuccessorOperands(unsigned index) {
 }
 
 Block *CondBranchOp::getSuccessorForOperands(ArrayRef<Attribute> operands) {
-  if (BoolAttr condAttr = operands.front().dyn_cast_or_null<BoolAttr>())
-    return condAttr.getValue() ? trueDest() : falseDest();
   if (IntegerAttr condAttr = operands.front().dyn_cast_or_null<IntegerAttr>())
     return condAttr.getValue().isOneValue() ? trueDest() : falseDest();
   return nullptr;
@@ -1172,9 +1170,8 @@ bool ConstantOp::isBuildableWith(Attribute value, Type type) {
   if (value.getType() != type)
     return false;
   // Finally, check that the attribute kind is handled.
-  return value.isa<BoolAttr>() || value.isa<IntegerAttr>() ||
-         value.isa<FloatAttr>() || value.isa<ElementsAttr>() ||
-         value.isa<UnitAttr>();
+  return value.isa<IntegerAttr>() || value.isa<FloatAttr>() ||
+         value.isa<ElementsAttr>() || value.isa<UnitAttr>();
 }
 
 void ConstantFloatOp::build(OpBuilder &builder, OperationState &result,
index f586560..111ab4d 100644 (file)
@@ -1318,11 +1318,6 @@ void ModulePrinter::printAttribute(Attribute attr,
   case StandardAttributes::Unit:
     os << "unit";
     break;
-  case StandardAttributes::Bool:
-    os << (attr.cast<BoolAttr>().getValue() ? "true" : "false");
-
-    // BoolAttr always elides the type.
-    return;
   case StandardAttributes::Dictionary:
     os << '{';
     interleaveComma(attr.cast<DictionaryAttr>().getValue(),
@@ -1331,6 +1326,13 @@ void ModulePrinter::printAttribute(Attribute attr,
     break;
   case StandardAttributes::Integer: {
     auto intAttr = attr.cast<IntegerAttr>();
+    if (attrType.isSignlessInteger(1)) {
+      os << (intAttr.getValue().getBoolValue() ? "true" : "false");
+
+      // Boolean integer attributes always elides the type.
+      return;
+    }
+
     // Only print attributes as unsigned if they are explicitly unsigned or are
     // signless 1-bit values.  Indexes, signed values, and multi-bit signless
     // values print as signed.
index ffd1b34..f0b7794 100644 (file)
@@ -65,28 +65,6 @@ struct ArrayAttributeStorage : public AttributeStorage {
   ArrayRef<Attribute> value;
 };
 
-/// An attribute representing a boolean value.
-struct BoolAttributeStorage : public AttributeStorage {
-  using KeyTy = std::pair<MLIRContext *, bool>;
-
-  BoolAttributeStorage(Type type, bool value)
-      : AttributeStorage(type), value(value) {}
-
-  /// We only check equality for and hash with the boolean key parameter.
-  bool operator==(const KeyTy &key) const { return key.second == value; }
-  static unsigned hashKey(const KeyTy &key) {
-    return llvm::hash_value(key.second);
-  }
-
-  static BoolAttributeStorage *construct(AttributeStorageAllocator &allocator,
-                                         const KeyTy &key) {
-    return new (allocator.allocate<BoolAttributeStorage>())
-        BoolAttributeStorage(IntegerType::get(1, key.first), key.second);
-  }
-
-  bool value;
-};
-
 /// An attribute representing a dictionary of sorted named attributes.
 struct DictionaryAttributeStorage final
     : public AttributeStorage,
index 12fd087..bc929bc 100644 (file)
@@ -75,12 +75,6 @@ Attribute ArrayAttr::operator[](unsigned idx) const {
 }
 
 //===----------------------------------------------------------------------===//
-// BoolAttr
-//===----------------------------------------------------------------------===//
-
-bool BoolAttr::getValue() const { return getImpl()->value; }
-
-//===----------------------------------------------------------------------===//
 // DictionaryAttr
 //===----------------------------------------------------------------------===//
 
@@ -308,6 +302,8 @@ ArrayRef<FlatSymbolRefAttr> SymbolRefAttr::getNestedReferences() const {
 //===----------------------------------------------------------------------===//
 
 IntegerAttr IntegerAttr::get(Type type, const APInt &value) {
+  if (type.isSignlessInteger(1))
+    return BoolAttr::get(value.getBoolValue(), type.getContext());
   return Base::get(type.getContext(), StandardAttributes::Integer, type, value);
 }
 
@@ -364,6 +360,19 @@ LogicalResult IntegerAttr::verifyConstructionInvariants(Location loc, Type type,
 }
 
 //===----------------------------------------------------------------------===//
+// BoolAttr
+
+bool BoolAttr::getValue() const {
+  auto *storage = reinterpret_cast<IntegerAttributeStorage *>(impl);
+  return storage->getValue().getBoolValue();
+}
+
+bool BoolAttr::classof(Attribute attr) {
+  IntegerAttr intAttr = attr.dyn_cast<IntegerAttr>();
+  return intAttr && intAttr.getType().isSignlessInteger(1);
+}
+
+//===----------------------------------------------------------------------===//
 // IntegerSetAttr
 //===----------------------------------------------------------------------===//
 
@@ -618,12 +627,8 @@ DenseElementsAttr::AttributeElementIterator::AttributeElementIterator(
 Attribute DenseElementsAttr::AttributeElementIterator::operator*() const {
   auto owner = getFromOpaquePointer(base).cast<DenseElementsAttr>();
   Type eltTy = owner.getType().getElementType();
-  if (auto intEltTy = eltTy.dyn_cast<IntegerType>()) {
-    if (intEltTy.getWidth() == 1)
-      return BoolAttr::get((*IntElementIterator(owner, index)).isOneValue(),
-                           owner.getContext());
+  if (auto intEltTy = eltTy.dyn_cast<IntegerType>())
     return IntegerAttr::get(eltTy, *IntElementIterator(owner, index));
-  }
   if (eltTy.isa<IndexType>())
     return IntegerAttr::get(eltTy, *IntElementIterator(owner, index));
   if (auto floatEltTy = eltTy.dyn_cast<FloatType>()) {
@@ -750,9 +755,7 @@ DenseElementsAttr DenseElementsAttr::get(ShapedType type,
       break;
     case StandardTypes::Integer:
     case StandardTypes::Index:
-      intVal = values[i].isa<BoolAttr>()
-                   ? APInt(1, values[i].cast<BoolAttr>().getValue() ? 1 : 0)
-                   : values[i].cast<IntegerAttr>().getValue();
+      intVal = values[i].cast<IntegerAttr>().getValue();
       break;
     default:
       llvm_unreachable("unexpected element type");
@@ -1321,9 +1324,7 @@ Attribute SparseElementsAttr::getZeroAttr() const {
     return FloatAttr::get(eltType, 0);
 
   // Otherwise, this is an integer.
-  auto intEltTy = eltType.cast<IntegerType>();
-  if (intEltTy.getWidth() == 1)
-    return BoolAttr::get(false, eltType.getContext());
+  // TODO: Handle StringAttr here.
   return IntegerAttr::get(eltType, 0);
 }
 
index 0648897..0ca3bd8 100644 (file)
@@ -269,12 +269,8 @@ Attribute Builder::getZeroAttr(Type type) {
   case StandardTypes::F32:
   case StandardTypes::F64:
     return getFloatAttr(type, 0.0);
-  case StandardTypes::Integer: {
-    auto width = type.cast<IntegerType>().getWidth();
-    if (width == 1)
-      return getBoolAttr(false);
-    return getIntegerAttr(type, APInt(width, 0));
-  }
+  case StandardTypes::Integer:
+    return getIntegerAttr(type, APInt(type.cast<IntegerType>().getWidth(), 0));
   case StandardTypes::Vector:
   case StandardTypes::RankedTensor: {
     auto vtType = type.cast<ShapedType>();
index da607a2..e72330b 100644 (file)
@@ -86,7 +86,7 @@ namespace {
 /// the IR.
 struct BuiltinDialect : public Dialect {
   BuiltinDialect(MLIRContext *context) : Dialect(/*name=*/"", context) {
-    addAttributes<AffineMapAttr, ArrayAttr, BoolAttr, DenseIntOrFPElementsAttr,
+    addAttributes<AffineMapAttr, ArrayAttr, DenseIntOrFPElementsAttr,
                   DenseStringElementsAttr, DictionaryAttr, FloatAttr,
                   SymbolRefAttr, IntegerAttr, IntegerSetAttr, OpaqueAttr,
                   OpaqueElementsAttr, SparseElementsAttr, StringAttr, TypeAttr,
@@ -378,11 +378,14 @@ MLIRContext::MLIRContext() : impl(new MLIRContextImpl()) {
   //// Note: These must be registered after the types as they may generate one
   //// of the above types internally.
   /// Bool Attributes.
-  // Note: The context is also used within the BoolAttrStorage.
-  impl->falseAttr = AttributeUniquer::get<BoolAttr>(
-      this, StandardAttributes::Bool, this, false);
-  impl->trueAttr = AttributeUniquer::get<BoolAttr>(
-      this, StandardAttributes::Bool, this, true);
+  impl->falseAttr = AttributeUniquer::get<IntegerAttr>(
+                        this, StandardAttributes::Integer, impl->int1Ty,
+                        APInt(/*numBits=*/1, false))
+                        .cast<BoolAttr>();
+  impl->trueAttr = AttributeUniquer::get<IntegerAttr>(
+                       this, StandardAttributes::Integer, impl->int1Ty,
+                       APInt(/*numBits=*/1, true))
+                       .cast<BoolAttr>();
   /// Unit Attribute.
   impl->unitAttr =
       AttributeUniquer::get<UnitAttr>(this, StandardAttributes::Unit);
index 9609869..fea50ce 100644 (file)
@@ -109,8 +109,6 @@ llvm::Constant *ModuleTranslation::getLLVMConstant(llvm::Type *llvmType,
     return llvm::ConstantInt::get(
         llvmType,
         intAttr.getValue().sextOrTrunc(llvmType->getIntegerBitWidth()));
-  if (auto boolAttr = attr.dyn_cast<BoolAttr>())
-    return llvm::ConstantInt::get(llvmType, boolAttr.getValue());
   if (auto floatAttr = attr.dyn_cast<FloatAttr>())
     return llvm::ConstantFP::get(llvmType, floatAttr.getValue());
   if (auto funcAttr = attr.dyn_cast<FlatSymbolRefAttr>())
index e4fc2a9..a6d22d9 100644 (file)
@@ -153,19 +153,19 @@ func @simple_if_yield(%arg0: i1) -> (i1, i1) {
 // CHECK:   cond_br %{{.*}}, ^[[then:.*]], ^[[else:.*]]
   %0:2 = scf.if %arg0 -> (i1, i1) {
 // CHECK: ^[[then]]:
-// CHECK:   %[[v0:.*]] = constant 0
-// CHECK:   %[[v1:.*]] = constant 1
+// CHECK:   %[[v0:.*]] = constant false
+// CHECK:   %[[v1:.*]] = constant true
 // CHECK:   br ^[[dom:.*]](%[[v0]], %[[v1]] : i1, i1)
-    %c0 = constant 0 : i1
-    %c1 = constant 1 : i1
+    %c0 = constant false
+    %c1 = constant true
     scf.yield %c0, %c1 : i1, i1
   } else {
 // CHECK: ^[[else]]:
-// CHECK:   %[[v2:.*]] = constant 0
-// CHECK:   %[[v3:.*]] = constant 1
+// CHECK:   %[[v2:.*]] = constant false
+// CHECK:   %[[v3:.*]] = constant true
 // CHECK:   br ^[[dom]](%[[v3]], %[[v2]] : i1, i1)
-    %c0 = constant 0 : i1
-    %c1 = constant 1 : i1
+    %c0 = constant false
+    %c1 = constant true
     scf.yield %c1, %c0 : i1, i1
   }
 // CHECK: ^[[dom]](%[[arg1:.*]]: i1, %[[arg2:.*]]: i1):
@@ -180,12 +180,12 @@ func @nested_if_yield(%arg0: i1) -> (index) {
 // CHECK:   cond_br %{{.*}}, ^[[first_then:.*]], ^[[first_else:.*]]
   %0 = scf.if %arg0 -> i1 {
 // CHECK: ^[[first_then]]:
-    %1 = constant 1 : i1
+    %1 = constant true
 // CHECK:   br ^[[first_dom:.*]]({{.*}})
     scf.yield %1 : i1
   } else {
 // CHECK: ^[[first_else]]:
-    %2 = constant 0 : i1
+    %2 = constant false
 // CHECK:   br ^[[first_dom]]({{.*}})
     scf.yield %2 : i1
   }
index 0948832..c232395 100644 (file)
@@ -447,9 +447,9 @@ func @corner_cases() {
 
 
   // CHECK: spv.constant false
-  %9 = constant 0 : i1
+  %9 = constant false
   // CHECK: spv.constant true
-  %10 = constant 1 : i1
+  %10 = constant true
 
   return
 }
index 3662c24..b61dc17 100644 (file)
@@ -941,7 +941,7 @@ func @genbool_1d() -> vector<8xi1> {
   return %0 : vector<8xi1>
 }
 // CHECK-LABEL: func @genbool_1d
-// CHECK: %[[T0:.*]] = llvm.mlir.constant(1 : i1) : !llvm.i1
+// CHECK: %[[T0:.*]] = llvm.mlir.constant(true) : !llvm.i1
 // CHECK: %[[T1:.*]] = llvm.mlir.constant(dense<false> : vector<8xi1>) : !llvm<"<8 x i1>">
 // CHECK: %[[T2:.*]] = llvm.mlir.constant(0 : i64) : !llvm.i64
 // CHECK: %[[T3:.*]] = llvm.insertelement %[[T0]], %[[T1]][%[[T2]] : !llvm.i64] : !llvm<"<8 x i1>">
index b0fd844..c22bd28 100644 (file)
@@ -38,8 +38,8 @@ func @br_passthrough(%arg0 : i32, %arg1 : i32) -> (i32, i32) {
 func @cond_br_folding(%cond : i1, %a : i32) {
   // CHECK-NEXT: return
 
-  %false_cond = constant 0 : i1
-  %true_cond = constant 1 : i1
+  %false_cond = constant false
+  %true_cond = constant true
   cond_br %cond, ^bb1, ^bb2(%a : i32)
 
 ^bb1:
@@ -89,8 +89,8 @@ func @cond_br_same_successor_insert_select(
 func @cond_br_and_br_folding(%a : i32) {
   // CHECK-NEXT: return
 
-  %false_cond = constant 0 : i1
-  %true_cond = constant 1 : i1
+  %false_cond = constant false
+  %true_cond = constant true
   cond_br %true_cond, ^bb2, ^bb1(%a : i32)
 
 ^bb1(%x : i32):
index 491f18f..76d7a9a 100644 (file)
@@ -611,7 +611,7 @@ func @broadcast_stretch_in_middle(%arg0: vector<4x1x2xf32>) -> vector<4x3x2xf32>
 }
 
 // CHECK-LABEL: func @genbool_1d
-// CHECK: %[[TT:.*]] = constant 1 : i1
+// CHECK: %[[TT:.*]] = constant true
 // CHECK: %[[C1:.*]] = constant dense<false> : vector<8xi1>
 // CHECK: %[[T0.*]] = vector.insert %[[TT]], %[[C1]] [0] : i1 into vector<8xi1>
 // CHECK: %[[T1.*]] = vector.insert %[[TT]], %[[T0]] [1] : i1 into vector<8xi1>
@@ -625,7 +625,7 @@ func @genbool_1d() -> vector<8xi1> {
 }
 
 // CHECK-LABEL: func @genbool_2d
-// CHECK: %[[TT:.*]] = constant 1 : i1
+// CHECK: %[[TT:.*]] = constant true
 // CHECK: %[[C1:.*]] = constant dense<false> : vector<4xi1>
 // CHECK: %[[C2:.*]] = constant dense<false> : vector<4x4xi1>
 // CHECK: %[[T0:.*]] = vector.insert %[[TT]], %[[C1]] [0] : i1 into vector<4xi1>
@@ -640,7 +640,7 @@ func @genbool_2d() -> vector<4x4xi1> {
 }
 
 // CHECK-LABEL: func @genbool_3d
-// CHECK: %[[Tt:.*]] = constant 1 : i1
+// CHECK: %[[Tt:.*]] = constant true
 // CHECK: %[[C1:.*]] = constant dense<false> : vector<4xi1>
 // CHECK: %[[C2:.*]] = constant dense<false> : vector<3x4xi1>
 // CHECK: %[[C3:.*]] = constant dense<false> : vector<2x3x4xi1>
index 6a6ad1c..b48fd99 100644 (file)
@@ -510,7 +510,7 @@ TEST_FUNC(operator_and) {
   // CHECK-LABEL: @operator_and
   //       CHECK: [[ARG0:%.*]]: i1, [[ARG1:%.*]]: i1
   //       CHECK: [[AND:%.*]] = and [[ARG0]], [[ARG1]]
-  //       CHECK: [[TRUE:%.*]] = constant 1 : i1
+  //       CHECK: [[TRUE:%.*]] = constant true
   //       CHECK: subi [[TRUE]], [[AND]] : i1
   f.print(llvm::outs());
   f.erase();
index d51d7d8..9af96f2 100644 (file)
@@ -1531,7 +1531,7 @@ func @forward_reference_type_check() -> (i8) {
 // -----
 
 func @dominance_error_in_unreachable_op() -> i1 {
-  %c = constant 0 : i1
+  %c = constant false
   return %c : i1
 ^bb0:
   "dummy" () ({  // unreachable
index 34acb5e..ba44f99 100644 (file)
@@ -446,7 +446,7 @@ func @verbose_terminators() -> (i1, i17) {
   "std.cond_br"(%x, %y, %x, %y) [^bb2, ^bb3] {operand_segment_sizes = dense<[1, 1, 2]>: vector<3xi32>} : (i1, i17, i1, i17) -> ()
 
 ^bb2(%a : i17):
-  %true = constant 1 : i1
+  %true = constant true
 // CHECK:  return %{{.*}}, %{{.*}} : i1, i17
   "std.return"(%true, %a) : (i1, i17) -> ()
 
@@ -502,10 +502,10 @@ func @constants() -> (i32, i23, i23, i1, i1) {
   // CHECK: %{{.*}} = constant 17 : i23
   %z = constant 17 : i23
 
-  // CHECK: %{{.*}} = constant 1 : i1
-  %t = constant 1 : i1
-  // CHECK: %{{.*}} = constant 0 : i1
-  %f = constant 0 : i1
+  // CHECK: %{{.*}} = constant true
+  %t = constant true
+  // CHECK: %{{.*}} = constant false
+  %f = constant false
 
   // The trick to parse type declarations should not interfere with hex
   // literals.
@@ -1245,7 +1245,7 @@ func @pretty_names() {
 }
 
 func @unreachable_dominance_violation_ok() -> i1 {
-  %c = constant 0 : i1       // CHECK: [[VAL:%.*]] = constant 0 : i1
+  %c = constant false       // CHECK: [[VAL:%.*]] = constant false
   return %c : i1    // CHECK:   return [[VAL]] : i1
 ^bb1:         // CHECK: ^bb1:   // no predecessors
   // %1 is not dominated by it's definition, but block is not reachable.
index 23fc219..7606132 100644 (file)
@@ -71,7 +71,7 @@ declare float @fe(i32)
 ; CHECK-LABEL: llvm.func @f1(%arg0: !llvm.i64) -> !llvm.i32 {
 ; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : !llvm.i32
 ; CHECK-DAG: %[[c42:[0-9]+]] = llvm.mlir.constant(42 : i32) : !llvm.i32
-; CHECK-DAG: %[[c1:[0-9]+]] = llvm.mlir.constant(1 : i1) : !llvm.i1
+; CHECK-DAG: %[[c1:[0-9]+]] = llvm.mlir.constant(true) : !llvm.i1
 ; CHECK-DAG: %[[c43:[0-9]+]] = llvm.mlir.constant(43 : i32) : !llvm.i32
 define internal dso_local i32 @f1(i64 %a) norecurse {
 entry:
index 304c987..801d591 100644 (file)
@@ -394,8 +394,8 @@ func @dim(%x : tensor<8x4xf32>) -> index {
 func @cmpi() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
   %c42 = constant 42 : i32
   %cm1 = constant -1 : i32
-  // CHECK-DAG: [[F:%.+]] = constant 0 : i1
-  // CHECK-DAG: [[T:%.+]] = constant 1 : i1
+  // CHECK-DAG: [[F:%.+]] = constant false
+  // CHECK-DAG: [[T:%.+]] = constant true
   // CHECK-NEXT: return [[F]],
   %0 = cmpi "eq", %c42, %cm1 : i32
   // CHECK-SAME: [[T]],
@@ -425,8 +425,8 @@ func @cmpi() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
 func @cmpf_normal_numbers() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
   %c42 = constant 42. : f32
   %cm1 = constant -1. : f32
-  // CHECK-DAG: [[F:%.+]] = constant 0 : i1
-  // CHECK-DAG: [[T:%.+]] = constant 1 : i1
+  // CHECK-DAG: [[F:%.+]] = constant false
+  // CHECK-DAG: [[T:%.+]] = constant true
   // CHECK-NEXT: return [[F]],
   %0 = cmpf "false", %c42, %cm1 : f32
   // CHECK-SAME: [[F]],
@@ -468,8 +468,8 @@ func @cmpf_normal_numbers() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1,
 func @cmpf_nan() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
   %c42 = constant 42. : f32
   %cqnan = constant 0xFFFFFFFF : f32
-  // CHECK-DAG: [[F:%.+]] = constant 0 : i1
-  // CHECK-DAG: [[T:%.+]] = constant 1 : i1
+  // CHECK-DAG: [[F:%.+]] = constant false
+  // CHECK-DAG: [[T:%.+]] = constant true
   // CHECK-NEXT: return [[F]],
   %0 = cmpf "false", %c42, %cqnan : f32
   // CHECK-SAME: [[F]]
@@ -511,8 +511,8 @@ func @cmpf_nan() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1,
 func @cmpf_inf() -> (i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1, i1) {
   %c42 = constant 42. : f32
   %cpinf = constant 0x7F800000 : f32
-  // CHECK-DAG: [[F:%.+]] = constant 0 : i1
-  // CHECK-DAG: [[T:%.+]] = constant 1 : i1
+  // CHECK-DAG: [[F:%.+]] = constant false
+  // CHECK-DAG: [[T:%.+]] = constant true
   // CHECK-NEXT: return [[F]],
   %0 = cmpf "false", %c42, %cpinf: f32
   // CHECK-SAME: [[F]]
index 9be014d..78b6e88 100644 (file)
@@ -127,8 +127,8 @@ func @down_propagate() -> i32 {
   // CHECK-NEXT: %c1_i32 = constant 1 : i32
   %0 = constant 1 : i32
 
-  // CHECK-NEXT: %true = constant 1 : i1
-  %cond = constant 1 : i1
+  // CHECK-NEXT: %true = constant true
+  %cond = constant true
 
   // CHECK-NEXT: cond_br %true, ^bb1, ^bb2(%c1_i32 : i32)
   cond_br %cond, ^bb1, ^bb2(%0 : i32)
@@ -164,8 +164,8 @@ func @up_propagate() -> i32 {
   // CHECK-NEXT:  %c0_i32 = constant 0 : i32
   %0 = constant 0 : i32
 
-  // CHECK-NEXT: %true = constant 1 : i1
-  %cond = constant 1 : i1
+  // CHECK-NEXT: %true = constant true
+  %cond = constant true
 
   // CHECK-NEXT: cond_br %true, ^bb1, ^bb2(%c0_i32 : i32)
   cond_br %cond, ^bb1, ^bb2(%0 : i32)
@@ -195,11 +195,11 @@ func @up_propagate_region() -> i32 {
   // CHECK-NEXT: %0 = "foo.region"
   %0 = "foo.region"() ({
     // CHECK-NEXT:  %c0_i32 = constant 0 : i32
-    // CHECK-NEXT: %true = constant 1 : i1
+    // CHECK-NEXT: %true = constant true
     // CHECK-NEXT: cond_br
 
     %1 = constant 0 : i32
-    %true = constant 1 : i1
+    %true = constant true
     cond_br %true, ^bb1, ^bb2(%1 : i32)
 
   ^bb1: // CHECK: ^bb1:
index 0b98d76..9c9ed70 100644 (file)
@@ -32,7 +32,7 @@ func @func_with_multi_return(%a : i1) -> (i32) {
 
 // CHECK-LABEL: func @inline_with_multi_return() -> i32
 func @inline_with_multi_return() -> i32 {
-// CHECK-NEXT:    [[VAL_7:%.*]] = constant 0 : i1
+// CHECK-NEXT:    [[VAL_7:%.*]] = constant false
 // CHECK-NEXT:    cond_br [[VAL_7]], ^bb1, ^bb2
 // CHECK:       ^bb1:
 // CHECK-NEXT:    [[VAL_8:%.*]] = constant 0 : i32
@@ -43,7 +43,7 @@ func @inline_with_multi_return() -> i32 {
 // CHECK:       ^bb3([[VAL_10:%.*]]: i32):
 // CHECK-NEXT:    return [[VAL_10]] : i32
 
-  %false = constant 0 : i1
+  %false = constant false
   %x = call @func_with_multi_return(%false) : (i1) -> i32
   return %x : i32
 }
index 5d47a27..add65d9 100644 (file)
@@ -183,7 +183,7 @@ func @conflicting_constant(%arg0 : i32) -> (i32, i32) {
 
 // CHECK-LABEL: func @complex_inner_if(
 func @complex_inner_if(%arg0 : i32) -> i32 attributes { sym_visibility = "private" } {
-  // CHECK-DAG: %[[TRUE:.*]] = constant 1 : i1
+  // CHECK-DAG: %[[TRUE:.*]] = constant true
   // CHECK-DAG: %[[CST:.*]] = constant 1 : i32
   // CHECK: cond_br %[[TRUE]], ^bb1
 
index 2ec13b8..43a6ff5 100644 (file)
@@ -7,7 +7,7 @@ func @no_control_flow(%arg0: i32) -> i32 {
   // CHECK: %[[CST:.*]] = constant 1 : i32
   // CHECK: return %[[CST]] : i32
 
-  %cond = constant 1 : i1
+  %cond = constant true
   %cst_1 = constant 1 : i32
   %select = select %cond, %cst_1, %arg0 : i32
   return %select : i32
@@ -123,7 +123,7 @@ func @simple_loop(%arg0 : i32, %cond1 : i1) -> i32 {
 // CHECK-LABEL: func @simple_loop_inner_control_flow
 func @simple_loop_inner_control_flow(%arg0 : i32) -> i32 {
   // CHECK-DAG: %[[CST:.*]] = constant 1 : i32
-  // CHECK-DAG: %[[TRUE:.*]] = constant 1 : i1
+  // CHECK-DAG: %[[TRUE:.*]] = constant true
 
   %cst_1 = constant 1 : i32
   br ^bb1(%cst_1 : i32)