Clean up signed/unsigned in vectorizer.

Rationale:
Currently we have some remaining ugliness around signed and unsigned
SIMD operations due to lack of kUint32 and kUint64 in the HIR. By
"softly" introducing these types, ABS/MIN/MAX/HALVING_ADD/SAD_ACCUMULATE
operations can solely rely on the packed data types to distinguish
between signed and unsigned operations. Cleaner, and also allows for
some code removal in the current loop optimizer.

Bug: 72709770

Test: test-art-host test-art-target
Change-Id: I68e4cdfba325f622a7256adbe649735569cab2a3
diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h
index 87dff84..ecabdf3 100644
--- a/compiler/optimizing/nodes_vector.h
+++ b/compiler/optimizing/nodes_vector.h
@@ -131,8 +131,6 @@
   }
 
   // Maps an integral type to the same-size signed type and leaves other types alone.
-  // Can be used to test relaxed type consistency in which packed same-size integral
-  // types can co-exist, but other type mixes are an error.
   static DataType::Type ToSignedType(DataType::Type type) {
     switch (type) {
       case DataType::Type::kBool:  // 1-byte storage unit
@@ -160,6 +158,11 @@
     }
   }
 
+  // Maps an integral type to the same-size (un)signed type. Leaves other types alone.
+  static DataType::Type ToProperType(DataType::Type type, bool is_unsigned) {
+    return is_unsigned ? ToUnsignedType(type) : ToSignedType(type);
+  }
+
   // Helper method to determine if an instruction returns a SIMD value.
   // TODO: This method is needed until we introduce SIMD as proper type.
   static bool ReturnsSIMDValue(HInstruction* instruction) {
@@ -286,6 +289,8 @@
 };
 
 // Packed type consistency checker ("same vector length" integral types may mix freely).
+// Tests relaxed type consistency in which packed same-size integral types can co-exist,
+// but other type mixes are an error.
 inline static bool HasConsistentPackedTypes(HInstruction* input, DataType::Type type) {
   if (input->IsPhi()) {
     return input->GetType() == HVecOperation::kSIMDType;  // carries SIMD
@@ -518,7 +523,7 @@
 // Performs halving add on every component in the two vectors, viz.
 // rounded   [ x1, .. , xn ] hradd [ y1, .. , yn ] = [ (x1 + y1 + 1) >> 1, .. , (xn + yn + 1) >> 1 ]
 // truncated [ x1, .. , xn ] hadd  [ y1, .. , yn ] = [ (x1 + y1)     >> 1, .. , (xn + yn )    >> 1 ]
-// for either both signed or both unsigned operands x, y.
+// for either both signed or both unsigned operands x, y (reflected in packed_type).
 class HVecHalvingAdd FINAL : public HVecBinaryOperation {
  public:
   HVecHalvingAdd(ArenaAllocator* allocator,
@@ -527,21 +532,13 @@
                  DataType::Type packed_type,
                  size_t vector_length,
                  bool is_rounded,
-                 bool is_unsigned,
                  uint32_t dex_pc)
       : HVecBinaryOperation(allocator, left, right, packed_type, vector_length, dex_pc) {
-    // The `is_unsigned` flag should be used exclusively with the Int32 or Int64.
-    // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types.
-    DCHECK(!is_unsigned ||
-           packed_type == DataType::Type::kInt32 ||
-           packed_type == DataType::Type::kInt64) << packed_type;
     DCHECK(HasConsistentPackedTypes(left, packed_type));
     DCHECK(HasConsistentPackedTypes(right, packed_type));
-    SetPackedFlag<kFieldHAddIsUnsigned>(is_unsigned);
     SetPackedFlag<kFieldHAddIsRounded>(is_rounded);
   }
 
-  bool IsUnsigned() const { return GetPackedFlag<kFieldHAddIsUnsigned>(); }
   bool IsRounded() const { return GetPackedFlag<kFieldHAddIsRounded>(); }
 
   bool CanBeMoved() const OVERRIDE { return true; }
@@ -549,9 +546,7 @@
   bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
     DCHECK(other->IsVecHalvingAdd());
     const HVecHalvingAdd* o = other->AsVecHalvingAdd();
-    return HVecOperation::InstructionDataEquals(o) &&
-        IsUnsigned() == o->IsUnsigned() &&
-        IsRounded() == o->IsRounded();
+    return HVecOperation::InstructionDataEquals(o) && IsRounded() == o->IsRounded();
   }
 
   DECLARE_INSTRUCTION(VecHalvingAdd);
@@ -561,8 +556,7 @@
 
  private:
   // Additional packed bits.
-  static constexpr size_t kFieldHAddIsUnsigned = HVecOperation::kNumberOfVectorOpPackedBits;
-  static constexpr size_t kFieldHAddIsRounded = kFieldHAddIsUnsigned + 1;
+  static constexpr size_t kFieldHAddIsRounded = HVecOperation::kNumberOfVectorOpPackedBits;
   static constexpr size_t kNumberOfHAddPackedBits = kFieldHAddIsRounded + 1;
   static_assert(kNumberOfHAddPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
 };
@@ -638,7 +632,7 @@
 
 // Takes minimum of every component in the two vectors,
 // viz. MIN( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ min(x1, y1), .. , min(xn, yn) ]
-// for either both signed or both unsigned operands x, y.
+// for either both signed or both unsigned operands x, y (reflected in packed_type).
 class HVecMin FINAL : public HVecBinaryOperation {
  public:
   HVecMin(ArenaAllocator* allocator,
@@ -646,44 +640,23 @@
           HInstruction* right,
           DataType::Type packed_type,
           size_t vector_length,
-          bool is_unsigned,
           uint32_t dex_pc)
       : HVecBinaryOperation(allocator, left, right, packed_type, vector_length, dex_pc) {
-    // The `is_unsigned` flag should be used exclusively with the Int32 or Int64.
-    // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types.
-    DCHECK(!is_unsigned ||
-           packed_type == DataType::Type::kInt32 ||
-           packed_type == DataType::Type::kInt64) << packed_type;
     DCHECK(HasConsistentPackedTypes(left, packed_type));
     DCHECK(HasConsistentPackedTypes(right, packed_type));
-    SetPackedFlag<kFieldMinOpIsUnsigned>(is_unsigned);
   }
 
-  bool IsUnsigned() const { return GetPackedFlag<kFieldMinOpIsUnsigned>(); }
-
   bool CanBeMoved() const OVERRIDE { return true; }
 
-  bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
-    DCHECK(other->IsVecMin());
-    const HVecMin* o = other->AsVecMin();
-    return HVecOperation::InstructionDataEquals(o) && IsUnsigned() == o->IsUnsigned();
-  }
-
   DECLARE_INSTRUCTION(VecMin);
 
  protected:
   DEFAULT_COPY_CONSTRUCTOR(VecMin);
-
- private:
-  // Additional packed bits.
-  static constexpr size_t kFieldMinOpIsUnsigned = HVecOperation::kNumberOfVectorOpPackedBits;
-  static constexpr size_t kNumberOfMinOpPackedBits = kFieldMinOpIsUnsigned + 1;
-  static_assert(kNumberOfMinOpPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
 };
 
 // Takes maximum of every component in the two vectors,
 // viz. MAX( [ x1, .. , xn ] , [ y1, .. , yn ]) = [ max(x1, y1), .. , max(xn, yn) ]
-// for either both signed or both unsigned operands x, y.
+// for either both signed or both unsigned operands x, y (reflected in packed_type).
 class HVecMax FINAL : public HVecBinaryOperation {
  public:
   HVecMax(ArenaAllocator* allocator,
@@ -691,39 +664,18 @@
           HInstruction* right,
           DataType::Type packed_type,
           size_t vector_length,
-          bool is_unsigned,
           uint32_t dex_pc)
       : HVecBinaryOperation(allocator, left, right, packed_type, vector_length, dex_pc) {
-    // The `is_unsigned` flag should be used exclusively with the Int32 or Int64.
-    // This flag is a temporary measure while we do not have the Uint32 and Uint64 data types.
-    DCHECK(!is_unsigned ||
-           packed_type == DataType::Type::kInt32 ||
-           packed_type == DataType::Type::kInt64) << packed_type;
     DCHECK(HasConsistentPackedTypes(left, packed_type));
     DCHECK(HasConsistentPackedTypes(right, packed_type));
-    SetPackedFlag<kFieldMaxOpIsUnsigned>(is_unsigned);
   }
 
-  bool IsUnsigned() const { return GetPackedFlag<kFieldMaxOpIsUnsigned>(); }
-
   bool CanBeMoved() const OVERRIDE { return true; }
 
-  bool InstructionDataEquals(const HInstruction* other) const OVERRIDE {
-    DCHECK(other->IsVecMax());
-    const HVecMax* o = other->AsVecMax();
-    return HVecOperation::InstructionDataEquals(o) && IsUnsigned() == o->IsUnsigned();
-  }
-
   DECLARE_INSTRUCTION(VecMax);
 
  protected:
   DEFAULT_COPY_CONSTRUCTOR(VecMax);
-
- private:
-  // Additional packed bits.
-  static constexpr size_t kFieldMaxOpIsUnsigned = HVecOperation::kNumberOfVectorOpPackedBits;
-  static constexpr size_t kNumberOfMaxOpPackedBits = kFieldMaxOpIsUnsigned + 1;
-  static_assert(kNumberOfMaxOpPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
 };
 
 // Bitwise-ands every component in the two vectors,