Skip to content

Revert "[mlir] Make single value ValueRanges memory safer" #123187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 16, 2025

Conversation

cota
Copy link
Contributor

@cota cota commented Jan 16, 2025

Reverts #121996 because it broke an emscripten build with --target=wasm32-unknown-emscripten:

llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:17: error: static assertion failed due to requirement '3U <= PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>::NumLowBitsAvailable': PointerIntPair with integer size too large for pointer
  172 |   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:111:13: note: in instantiation of template class 'llvm::PointerIntPairInfo<void *, 3, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>' requested here
  111 |     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
      |             ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:89:5: note: in instantiation of member function 'llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>::setPointerAndInt' requested here
   89 |     setPointerAndInt(PtrVal, IntVal);
      |     ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:77:16: note: in instantiation of member function 'llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>::PointerIntPair' requested here
   77 |         : Base(ValTy(const_cast<void *>(
      |                ^
llvm/llvm-project/mlir/include/mlir/IR/TypeRange.h:49:36: note: in instantiation of member function 'llvm::pointer_union_detail::PointerUnionMembers<llvm::PointerUnion<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>, llvm::PointerIntPair<void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits<const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type>>, 4, mlir::Type>::PointerUnionMembers' requested here
   49 |   TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
      |                                    ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:25: note: expression evaluates to '3 <= 2'
  172 |   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
      |                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir labels Jan 16, 2025
@cota cota merged commit 628976c into main Jan 16, 2025
6 of 7 checks passed
@cota cota deleted the revert-121996-safer-value-range branch January 16, 2025 11:33
@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2025

@llvm/pr-subscribers-mlir

Author: Emilio Cota (cota)

Changes

Reverts llvm/llvm-project#121996 because it broke an emscripten build with --target=wasm32-unknown-emscripten:

llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:17: error: static assertion failed due to requirement '3U &lt;= PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;::NumLowBitsAvailable': PointerIntPair with integer size too large for pointer
  172 |   static_assert(IntBits &lt;= PtrTraits::NumLowBitsAvailable,
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:111:13: note: in instantiation of template class 'llvm::PointerIntPairInfo&lt;void *, 3, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;' requested here
  111 |     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
      |             ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:89:5: note: in instantiation of member function 'llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;::setPointerAndInt' requested here
   89 |     setPointerAndInt(PtrVal, IntVal);
      |     ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:77:16: note: in instantiation of member function 'llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;::PointerIntPair' requested here
   77 |         : Base(ValTy(const_cast&lt;void *&gt;(
      |                ^
llvm/llvm-project/mlir/include/mlir/IR/TypeRange.h:49:36: note: in instantiation of member function 'llvm::pointer_union_detail::PointerUnionMembers&lt;llvm::PointerUnion&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;, llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;, 4, mlir::Type&gt;::PointerUnionMembers' requested here
   49 |   TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
      |                                    ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:25: note: expression evaluates to '3 &lt;= 2'
  172 |   static_assert(IntBits &lt;= PtrTraits::NumLowBitsAvailable,
      |                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Full diff: https://github.com/llvm/llvm-project/pull/123187.diff

5 Files Affected:

  • (modified) mlir/include/mlir/IR/TypeRange.h (+8-13)
  • (modified) mlir/include/mlir/IR/ValueRange.h (+8-8)
  • (modified) mlir/lib/IR/OperationSupport.cpp (-13)
  • (modified) mlir/lib/IR/TypeRange.cpp (-15)
  • (modified) mlir/unittests/IR/OperationSupportTest.cpp (-17)
diff --git a/mlir/include/mlir/IR/TypeRange.h b/mlir/include/mlir/IR/TypeRange.h
index fa63435b188e98..99fabab334f922 100644
--- a/mlir/include/mlir/IR/TypeRange.h
+++ b/mlir/include/mlir/IR/TypeRange.h
@@ -29,12 +29,11 @@ namespace mlir {
 /// a SmallVector/std::vector. This class should be used in places that are not
 /// suitable for a more derived type (e.g. ArrayRef) or a template range
 /// parameter.
-class TypeRange
-    : public llvm::detail::indexed_accessor_range_base<
-          TypeRange,
-          llvm::PointerUnion<const Value *, const Type *, OpOperand *,
-                             detail::OpResultImpl *, Type>,
-          Type, Type, Type> {
+class TypeRange : public llvm::detail::indexed_accessor_range_base<
+                      TypeRange,
+                      llvm::PointerUnion<const Value *, const Type *,
+                                         OpOperand *, detail::OpResultImpl *>,
+                      Type, Type, Type> {
 public:
   using RangeBaseT::RangeBaseT;
   TypeRange(ArrayRef<Type> types = std::nullopt);
@@ -45,11 +44,8 @@ class TypeRange
   TypeRange(ValueTypeRange<ValueRangeT> values)
       : TypeRange(ValueRange(ValueRangeT(values.begin().getCurrent(),
                                          values.end().getCurrent()))) {}
-
-  TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
-  template <typename Arg, typename = std::enable_if_t<
-                              std::is_constructible_v<ArrayRef<Type>, Arg> &&
-                              !std::is_constructible_v<Type, Arg>>>
+  template <typename Arg, typename = std::enable_if_t<std::is_constructible<
+                              ArrayRef<Type>, Arg>::value>>
   TypeRange(Arg &&arg) : TypeRange(ArrayRef<Type>(std::forward<Arg>(arg))) {}
   TypeRange(std::initializer_list<Type> types)
       : TypeRange(ArrayRef<Type>(types)) {}
@@ -60,9 +56,8 @@ class TypeRange
   /// * A pointer to the first element of an array of types.
   /// * A pointer to the first element of an array of operands.
   /// * A pointer to the first element of an array of results.
-  /// * A single 'Type' instance.
   using OwnerT = llvm::PointerUnion<const Value *, const Type *, OpOperand *,
-                                    detail::OpResultImpl *, Type>;
+                                    detail::OpResultImpl *>;
 
   /// See `llvm::detail::indexed_accessor_range_base` for details.
   static OwnerT offset_base(OwnerT object, ptrdiff_t index);
diff --git a/mlir/include/mlir/IR/ValueRange.h b/mlir/include/mlir/IR/ValueRange.h
index d5b067a79200d8..4b421c08d8418e 100644
--- a/mlir/include/mlir/IR/ValueRange.h
+++ b/mlir/include/mlir/IR/ValueRange.h
@@ -374,16 +374,16 @@ class ResultRange::UseIterator final
 /// SmallVector/std::vector. This class should be used in places that are not
 /// suitable for a more derived type (e.g. ArrayRef) or a template range
 /// parameter.
-class ValueRange final : public llvm::detail::indexed_accessor_range_base<
-                             ValueRange,
-                             PointerUnion<const Value *, OpOperand *,
-                                          detail::OpResultImpl *, Value>,
-                             Value, Value, Value> {
+class ValueRange final
+    : public llvm::detail::indexed_accessor_range_base<
+          ValueRange,
+          PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
+          Value, Value, Value> {
 public:
   /// The type representing the owner of a ValueRange. This is either a list of
-  /// values, operands, or results or a single value.
+  /// values, operands, or results.
   using OwnerT =
-      PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *, Value>;
+      PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>;
 
   using RangeBaseT::RangeBaseT;
 
@@ -392,7 +392,7 @@ class ValueRange final : public llvm::detail::indexed_accessor_range_base<
                 std::is_constructible<ArrayRef<Value>, Arg>::value &&
                 !std::is_convertible<Arg, Value>::value>>
   ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
-  ValueRange(Value value) : ValueRange(value, /*count=*/1) {}
+  ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
   ValueRange(const std::initializer_list<Value> &values)
       : ValueRange(ArrayRef<Value>(values)) {}
   ValueRange(iterator_range<OperandRange::iterator> values)
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 803fcd8d18fbd5..957195202d78d2 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -653,15 +653,6 @@ ValueRange::ValueRange(ResultRange values)
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 ValueRange::OwnerT ValueRange::offset_base(const OwnerT &owner,
                                            ptrdiff_t index) {
-  if (llvm::isa_and_nonnull<Value>(owner)) {
-    // Prevent out-of-bounds indexing for single values.
-    // Note that we do allow an index of 1 as is required by 'slice'ing that
-    // returns an empty range. This also matches the usual rules of C++ of being
-    // allowed to index past the last element of an array.
-    assert(index <= 1 && "out-of-bound offset into single-value 'ValueRange'");
-    // Return nullptr to quickly cause segmentation faults on misuse.
-    return index == 0 ? owner : nullptr;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(owner))
     return {value + index};
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
@@ -670,10 +661,6 @@ ValueRange::OwnerT ValueRange::offset_base(const OwnerT &owner,
 }
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 Value ValueRange::dereference_iterator(const OwnerT &owner, ptrdiff_t index) {
-  if (auto value = llvm::dyn_cast_if_present<Value>(owner)) {
-    assert(index == 0 && "cannot offset into single-value 'ValueRange'");
-    return value;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(owner))
     return value[index];
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
diff --git a/mlir/lib/IR/TypeRange.cpp b/mlir/lib/IR/TypeRange.cpp
index 7e5f99c884512e..f8878303727d4f 100644
--- a/mlir/lib/IR/TypeRange.cpp
+++ b/mlir/lib/IR/TypeRange.cpp
@@ -31,23 +31,12 @@ TypeRange::TypeRange(ValueRange values) : TypeRange(OwnerT(), values.size()) {
     this->base = result;
   else if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
     this->base = operand;
-  else if (auto value = llvm::dyn_cast_if_present<Value>(owner))
-    this->base = value.getType();
   else
     this->base = cast<const Value *>(owner);
 }
 
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 TypeRange::OwnerT TypeRange::offset_base(OwnerT object, ptrdiff_t index) {
-  if (llvm::isa_and_nonnull<Type>(object)) {
-    // Prevent out-of-bounds indexing for single values.
-    // Note that we do allow an index of 1 as is required by 'slice'ing that
-    // returns an empty range. This also matches the usual rules of C++ of being
-    // allowed to index past the last element of an array.
-    assert(index <= 1 && "out-of-bound offset into single-value 'ValueRange'");
-    // Return nullptr to quickly cause segmentation faults on misuse.
-    return index == 0 ? object : nullptr;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(object))
     return {value + index};
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(object))
@@ -59,10 +48,6 @@ TypeRange::OwnerT TypeRange::offset_base(OwnerT object, ptrdiff_t index) {
 
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 Type TypeRange::dereference_iterator(OwnerT object, ptrdiff_t index) {
-  if (auto type = llvm::dyn_cast_if_present<Type>(object)) {
-    assert(index == 0 && "cannot offset into single-value 'TypeRange'");
-    return type;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(object))
     return (value + index)->getType();
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(object))
diff --git a/mlir/unittests/IR/OperationSupportTest.cpp b/mlir/unittests/IR/OperationSupportTest.cpp
index 2a1b8d2ef7f55b..f94dc784458077 100644
--- a/mlir/unittests/IR/OperationSupportTest.cpp
+++ b/mlir/unittests/IR/OperationSupportTest.cpp
@@ -313,21 +313,4 @@ TEST(OperationEquivalenceTest, HashWorksWithFlags) {
   op2->destroy();
 }
 
-TEST(ValueRangeTest, ValueConstructable) {
-  MLIRContext context;
-  Builder builder(&context);
-
-  Operation *useOp =
-      createOp(&context, /*operands=*/std::nullopt, builder.getIntegerType(16));
-  // Valid construction despite a temporary 'OpResult'.
-  ValueRange operands = useOp->getResult(0);
-
-  useOp->setOperands(operands);
-  EXPECT_EQ(useOp->getNumOperands(), 1u);
-  EXPECT_EQ(useOp->getOperand(0), useOp->getResult(0));
-
-  useOp->dropAllUses();
-  useOp->destroy();
-}
-
 } // namespace

@llvmbot
Copy link
Member

llvmbot commented Jan 16, 2025

@llvm/pr-subscribers-mlir-core

Author: Emilio Cota (cota)

Changes

Reverts llvm/llvm-project#121996 because it broke an emscripten build with --target=wasm32-unknown-emscripten:

llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:17: error: static assertion failed due to requirement '3U &lt;= PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;::NumLowBitsAvailable': PointerIntPair with integer size too large for pointer
  172 |   static_assert(IntBits &lt;= PtrTraits::NumLowBitsAvailable,
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:111:13: note: in instantiation of template class 'llvm::PointerIntPairInfo&lt;void *, 3, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;' requested here
  111 |     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
      |             ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:89:5: note: in instantiation of member function 'llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;::setPointerAndInt' requested here
   89 |     setPointerAndInt(PtrVal, IntVal);
      |     ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerUnion.h:77:16: note: in instantiation of member function 'llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;::PointerIntPair' requested here
   77 |         : Base(ValTy(const_cast&lt;void *&gt;(
      |                ^
llvm/llvm-project/mlir/include/mlir/IR/TypeRange.h:49:36: note: in instantiation of member function 'llvm::pointer_union_detail::PointerUnionMembers&lt;llvm::PointerUnion&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;, llvm::PointerIntPair&lt;void *, 3, int, llvm::pointer_union_detail::PointerUnionUIntTraits&lt;const mlir::Value *, const mlir::Type *, mlir::OpOperand *, mlir::detail::OpResultImpl *, mlir::Type&gt;&gt;, 4, mlir::Type&gt;::PointerUnionMembers' requested here
   49 |   TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
      |                                    ^
llvm/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h:172:25: note: expression evaluates to '3 &lt;= 2'
  172 |   static_assert(IntBits &lt;= PtrTraits::NumLowBitsAvailable,
      |                 ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Full diff: https://github.com/llvm/llvm-project/pull/123187.diff

5 Files Affected:

  • (modified) mlir/include/mlir/IR/TypeRange.h (+8-13)
  • (modified) mlir/include/mlir/IR/ValueRange.h (+8-8)
  • (modified) mlir/lib/IR/OperationSupport.cpp (-13)
  • (modified) mlir/lib/IR/TypeRange.cpp (-15)
  • (modified) mlir/unittests/IR/OperationSupportTest.cpp (-17)
diff --git a/mlir/include/mlir/IR/TypeRange.h b/mlir/include/mlir/IR/TypeRange.h
index fa63435b188e98..99fabab334f922 100644
--- a/mlir/include/mlir/IR/TypeRange.h
+++ b/mlir/include/mlir/IR/TypeRange.h
@@ -29,12 +29,11 @@ namespace mlir {
 /// a SmallVector/std::vector. This class should be used in places that are not
 /// suitable for a more derived type (e.g. ArrayRef) or a template range
 /// parameter.
-class TypeRange
-    : public llvm::detail::indexed_accessor_range_base<
-          TypeRange,
-          llvm::PointerUnion<const Value *, const Type *, OpOperand *,
-                             detail::OpResultImpl *, Type>,
-          Type, Type, Type> {
+class TypeRange : public llvm::detail::indexed_accessor_range_base<
+                      TypeRange,
+                      llvm::PointerUnion<const Value *, const Type *,
+                                         OpOperand *, detail::OpResultImpl *>,
+                      Type, Type, Type> {
 public:
   using RangeBaseT::RangeBaseT;
   TypeRange(ArrayRef<Type> types = std::nullopt);
@@ -45,11 +44,8 @@ class TypeRange
   TypeRange(ValueTypeRange<ValueRangeT> values)
       : TypeRange(ValueRange(ValueRangeT(values.begin().getCurrent(),
                                          values.end().getCurrent()))) {}
-
-  TypeRange(Type type) : TypeRange(type, /*count=*/1) {}
-  template <typename Arg, typename = std::enable_if_t<
-                              std::is_constructible_v<ArrayRef<Type>, Arg> &&
-                              !std::is_constructible_v<Type, Arg>>>
+  template <typename Arg, typename = std::enable_if_t<std::is_constructible<
+                              ArrayRef<Type>, Arg>::value>>
   TypeRange(Arg &&arg) : TypeRange(ArrayRef<Type>(std::forward<Arg>(arg))) {}
   TypeRange(std::initializer_list<Type> types)
       : TypeRange(ArrayRef<Type>(types)) {}
@@ -60,9 +56,8 @@ class TypeRange
   /// * A pointer to the first element of an array of types.
   /// * A pointer to the first element of an array of operands.
   /// * A pointer to the first element of an array of results.
-  /// * A single 'Type' instance.
   using OwnerT = llvm::PointerUnion<const Value *, const Type *, OpOperand *,
-                                    detail::OpResultImpl *, Type>;
+                                    detail::OpResultImpl *>;
 
   /// See `llvm::detail::indexed_accessor_range_base` for details.
   static OwnerT offset_base(OwnerT object, ptrdiff_t index);
diff --git a/mlir/include/mlir/IR/ValueRange.h b/mlir/include/mlir/IR/ValueRange.h
index d5b067a79200d8..4b421c08d8418e 100644
--- a/mlir/include/mlir/IR/ValueRange.h
+++ b/mlir/include/mlir/IR/ValueRange.h
@@ -374,16 +374,16 @@ class ResultRange::UseIterator final
 /// SmallVector/std::vector. This class should be used in places that are not
 /// suitable for a more derived type (e.g. ArrayRef) or a template range
 /// parameter.
-class ValueRange final : public llvm::detail::indexed_accessor_range_base<
-                             ValueRange,
-                             PointerUnion<const Value *, OpOperand *,
-                                          detail::OpResultImpl *, Value>,
-                             Value, Value, Value> {
+class ValueRange final
+    : public llvm::detail::indexed_accessor_range_base<
+          ValueRange,
+          PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
+          Value, Value, Value> {
 public:
   /// The type representing the owner of a ValueRange. This is either a list of
-  /// values, operands, or results or a single value.
+  /// values, operands, or results.
   using OwnerT =
-      PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *, Value>;
+      PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>;
 
   using RangeBaseT::RangeBaseT;
 
@@ -392,7 +392,7 @@ class ValueRange final : public llvm::detail::indexed_accessor_range_base<
                 std::is_constructible<ArrayRef<Value>, Arg>::value &&
                 !std::is_convertible<Arg, Value>::value>>
   ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
-  ValueRange(Value value) : ValueRange(value, /*count=*/1) {}
+  ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
   ValueRange(const std::initializer_list<Value> &values)
       : ValueRange(ArrayRef<Value>(values)) {}
   ValueRange(iterator_range<OperandRange::iterator> values)
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 803fcd8d18fbd5..957195202d78d2 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -653,15 +653,6 @@ ValueRange::ValueRange(ResultRange values)
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 ValueRange::OwnerT ValueRange::offset_base(const OwnerT &owner,
                                            ptrdiff_t index) {
-  if (llvm::isa_and_nonnull<Value>(owner)) {
-    // Prevent out-of-bounds indexing for single values.
-    // Note that we do allow an index of 1 as is required by 'slice'ing that
-    // returns an empty range. This also matches the usual rules of C++ of being
-    // allowed to index past the last element of an array.
-    assert(index <= 1 && "out-of-bound offset into single-value 'ValueRange'");
-    // Return nullptr to quickly cause segmentation faults on misuse.
-    return index == 0 ? owner : nullptr;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(owner))
     return {value + index};
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
@@ -670,10 +661,6 @@ ValueRange::OwnerT ValueRange::offset_base(const OwnerT &owner,
 }
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 Value ValueRange::dereference_iterator(const OwnerT &owner, ptrdiff_t index) {
-  if (auto value = llvm::dyn_cast_if_present<Value>(owner)) {
-    assert(index == 0 && "cannot offset into single-value 'ValueRange'");
-    return value;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(owner))
     return value[index];
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
diff --git a/mlir/lib/IR/TypeRange.cpp b/mlir/lib/IR/TypeRange.cpp
index 7e5f99c884512e..f8878303727d4f 100644
--- a/mlir/lib/IR/TypeRange.cpp
+++ b/mlir/lib/IR/TypeRange.cpp
@@ -31,23 +31,12 @@ TypeRange::TypeRange(ValueRange values) : TypeRange(OwnerT(), values.size()) {
     this->base = result;
   else if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(owner))
     this->base = operand;
-  else if (auto value = llvm::dyn_cast_if_present<Value>(owner))
-    this->base = value.getType();
   else
     this->base = cast<const Value *>(owner);
 }
 
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 TypeRange::OwnerT TypeRange::offset_base(OwnerT object, ptrdiff_t index) {
-  if (llvm::isa_and_nonnull<Type>(object)) {
-    // Prevent out-of-bounds indexing for single values.
-    // Note that we do allow an index of 1 as is required by 'slice'ing that
-    // returns an empty range. This also matches the usual rules of C++ of being
-    // allowed to index past the last element of an array.
-    assert(index <= 1 && "out-of-bound offset into single-value 'ValueRange'");
-    // Return nullptr to quickly cause segmentation faults on misuse.
-    return index == 0 ? object : nullptr;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(object))
     return {value + index};
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(object))
@@ -59,10 +48,6 @@ TypeRange::OwnerT TypeRange::offset_base(OwnerT object, ptrdiff_t index) {
 
 /// See `llvm::detail::indexed_accessor_range_base` for details.
 Type TypeRange::dereference_iterator(OwnerT object, ptrdiff_t index) {
-  if (auto type = llvm::dyn_cast_if_present<Type>(object)) {
-    assert(index == 0 && "cannot offset into single-value 'TypeRange'");
-    return type;
-  }
   if (const auto *value = llvm::dyn_cast_if_present<const Value *>(object))
     return (value + index)->getType();
   if (auto *operand = llvm::dyn_cast_if_present<OpOperand *>(object))
diff --git a/mlir/unittests/IR/OperationSupportTest.cpp b/mlir/unittests/IR/OperationSupportTest.cpp
index 2a1b8d2ef7f55b..f94dc784458077 100644
--- a/mlir/unittests/IR/OperationSupportTest.cpp
+++ b/mlir/unittests/IR/OperationSupportTest.cpp
@@ -313,21 +313,4 @@ TEST(OperationEquivalenceTest, HashWorksWithFlags) {
   op2->destroy();
 }
 
-TEST(ValueRangeTest, ValueConstructable) {
-  MLIRContext context;
-  Builder builder(&context);
-
-  Operation *useOp =
-      createOp(&context, /*operands=*/std::nullopt, builder.getIntegerType(16));
-  // Valid construction despite a temporary 'OpResult'.
-  ValueRange operands = useOp->getResult(0);
-
-  useOp->setOperands(operands);
-  EXPECT_EQ(useOp->getNumOperands(), 1u);
-  EXPECT_EQ(useOp->getOperand(0), useOp->getResult(0));
-
-  useOp->dropAllUses();
-  useOp->destroy();
-}
-
 } // namespace

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mlir:core MLIR Core Infrastructure mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants