diff options
41 files changed, 1499 insertions, 1227 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 42e9f68a76..468e93a8c0 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -1929,17 +1929,18 @@ void CodeGeneratorARM64::Load(DataType::Type type, const MemOperand& src) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: __ Ldrb(Register(dst), src); break; case DataType::Type::kInt8: __ Ldrsb(Register(dst), src); break; - case DataType::Type::kInt16: - __ Ldrsh(Register(dst), src); - break; case DataType::Type::kUint16: __ Ldrh(Register(dst), src); break; + case DataType::Type::kInt16: + __ Ldrsh(Register(dst), src); + break; case DataType::Type::kInt32: case DataType::Type::kReference: case DataType::Type::kInt64: @@ -1972,14 +1973,7 @@ void CodeGeneratorARM64::LoadAcquire(HInstruction* instruction, MemOperand base = MemOperand(temp_base); switch (type) { case DataType::Type::kBool: - { - ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); - __ ldarb(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } - } - break; + case DataType::Type::kUint8: case DataType::Type::kInt8: { ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); @@ -1988,17 +1982,11 @@ void CodeGeneratorARM64::LoadAcquire(HInstruction* instruction, MaybeRecordImplicitNullCheck(instruction); } } - __ Sbfx(Register(dst), Register(dst), 0, DataType::Size(type) * kBitsPerByte); - break; - case DataType::Type::kUint16: - { - ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); - __ ldarh(Register(dst), base); - if (needs_null_check) { - MaybeRecordImplicitNullCheck(instruction); - } + if (type == DataType::Type::kInt8) { + __ Sbfx(Register(dst), Register(dst), 0, DataType::Size(type) * kBitsPerByte); } break; + case DataType::Type::kUint16: case DataType::Type::kInt16: { ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); @@ -2007,7 +1995,9 @@ void CodeGeneratorARM64::LoadAcquire(HInstruction* instruction, MaybeRecordImplicitNullCheck(instruction); } } - __ Sbfx(Register(dst), Register(dst), 0, DataType::Size(type) * kBitsPerByte); + if (type == DataType::Type::kInt16) { + __ Sbfx(Register(dst), Register(dst), 0, DataType::Size(type) * kBitsPerByte); + } break; case DataType::Type::kInt32: case DataType::Type::kReference: @@ -2048,6 +2038,7 @@ void CodeGeneratorARM64::Store(DataType::Type type, const MemOperand& dst) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: __ Strb(Register(src), dst); break; @@ -2087,6 +2078,7 @@ void CodeGeneratorARM64::StoreRelease(HInstruction* instruction, // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted. switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize); @@ -3222,9 +3214,10 @@ void LocationsBuilderARM64::VisitCompare(HCompare* compare) { DataType::Type in_type = compare->InputAt(0)->GetType(); switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); @@ -3255,9 +3248,10 @@ void InstructionCodeGeneratorARM64::VisitCompare(HCompare* compare) { // -1 if: left < right switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { Register result = OutputRegister(compare); @@ -5744,7 +5738,8 @@ void LocationsBuilderARM64::VisitTypeConversion(HTypeConversion* conversion) { new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall); DataType::Type input_type = conversion->GetInputType(); DataType::Type result_type = conversion->GetResultType(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; if ((input_type == DataType::Type::kReference) || (input_type == DataType::Type::kVoid) || (result_type == DataType::Type::kReference) || (result_type == DataType::Type::kVoid)) { LOG(FATAL) << "Unexpected type conversion from " << input_type << " to " << result_type; @@ -5767,7 +5762,8 @@ void InstructionCodeGeneratorARM64::VisitTypeConversion(HTypeConversion* convers DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; if (DataType::IsIntegralType(result_type) && DataType::IsIntegralType(input_type)) { int result_size = DataType::Size(result_type); @@ -5784,11 +5780,9 @@ void InstructionCodeGeneratorARM64::VisitTypeConversion(HTypeConversion* convers // 32bit input value as a 64bit value assuming that the top 32 bits are // zero. __ Mov(output.W(), source.W()); - } else if (result_type == DataType::Type::kUint16 || - (input_type == DataType::Type::kUint16 && input_size < result_size)) { - __ Ubfx(output, - output.IsX() ? source.X() : source.W(), - 0, DataType::Size(DataType::Type::kUint16) * kBitsPerByte); + } else if (DataType::IsUnsignedType(result_type) || + (DataType::IsUnsignedType(input_type) && input_size < result_size)) { + __ Ubfx(output, output.IsX() ? source.X() : source.W(), 0, result_size * kBitsPerByte); } else { __ Sbfx(output, output.IsX() ? source.X() : source.W(), 0, min_size * kBitsPerByte); } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 2b9e0febe8..d4fb064107 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -282,6 +282,58 @@ static size_t RestoreContiguousSRegisterList(size_t first, return stack_offset; } +static LoadOperandType GetLoadOperandType(DataType::Type type) { + switch (type) { + case DataType::Type::kReference: + return kLoadWord; + case DataType::Type::kBool: + case DataType::Type::kUint8: + return kLoadUnsignedByte; + case DataType::Type::kInt8: + return kLoadSignedByte; + case DataType::Type::kUint16: + return kLoadUnsignedHalfword; + case DataType::Type::kInt16: + return kLoadSignedHalfword; + case DataType::Type::kInt32: + return kLoadWord; + case DataType::Type::kInt64: + return kLoadWordPair; + case DataType::Type::kFloat32: + return kLoadSWord; + case DataType::Type::kFloat64: + return kLoadDWord; + default: + LOG(FATAL) << "Unreachable type " << type; + UNREACHABLE(); + } +} + +static StoreOperandType GetStoreOperandType(DataType::Type type) { + switch (type) { + case DataType::Type::kReference: + return kStoreWord; + case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + return kStoreByte; + case DataType::Type::kUint16: + case DataType::Type::kInt16: + return kStoreHalfword; + case DataType::Type::kInt32: + return kStoreWord; + case DataType::Type::kInt64: + return kStoreWordPair; + case DataType::Type::kFloat32: + return kStoreSWord; + case DataType::Type::kFloat64: + return kStoreDWord; + default: + LOG(FATAL) << "Unreachable type " << type; + UNREACHABLE(); + } +} + void SlowPathCodeARMVIXL::SaveLiveRegisters(CodeGenerator* codegen, LocationSummary* locations) { size_t stack_offset = codegen->GetFirstRegisterSlotInSlowPath(); size_t orig_offset = stack_offset; @@ -2598,12 +2650,13 @@ void CodeGeneratorARMVIXL::Bind(HBasicBlock* block) { Location InvokeDexCallingConventionVisitorARMVIXL::GetNextLocation(DataType::Type type) { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kReference: { + case DataType::Type::kInt32: { uint32_t index = gp_index_++; uint32_t stack_index = stack_index_++; if (index < calling_convention.GetNumberOfRegisters()) { @@ -2674,12 +2727,13 @@ Location InvokeDexCallingConventionVisitorARMVIXL::GetNextLocation(DataType::Typ Location InvokeDexCallingConventionVisitorARMVIXL::GetReturnLocation(DataType::Type type) const { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kReference: { + case DataType::Type::kInt32: { return LocationFrom(r0); } @@ -3728,7 +3782,8 @@ void InstructionCodeGeneratorARMVIXL::VisitNeg(HNeg* neg) { void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; // The float-to-long, double-to-long and long-to-float type conversions // rely on a call to the runtime. @@ -3741,67 +3796,30 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(conversion, call_kind); - // The Java language does not allow treating boolean as an integral type but - // our bit representation makes it safe. - switch (result_type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to byte is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - + case DataType::Type::kUint16: case DataType::Type::kInt16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } + DCHECK(DataType::IsIntegralType(input_type)) << input_type; + locations->SetInAt(0, Location::RequiresRegister()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); locations->AddTemp(Location::RequiresFpuRegister()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); locations->AddTemp(Location::RequiresFpuRegister()); @@ -3816,18 +3834,16 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kFloat32: { - // Processing a Dex `float-to-long' instruction. InvokeRuntimeCallingConventionARMVIXL calling_convention; locations->SetInAt(0, LocationFrom(calling_convention.GetFpuRegisterAt(0))); locations->SetOut(LocationFrom(r0, r1)); @@ -3835,7 +3851,6 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { } case DataType::Type::kFloat64: { - // Processing a Dex `double-to-long' instruction. InvokeRuntimeCallingConventionARMVIXL calling_convention; locations->SetInAt(0, LocationFrom(calling_convention.GetFpuRegisterAt(0), calling_convention.GetFpuRegisterAt(1))); @@ -3849,41 +3864,19 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to char is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `int-to-char' instruction. - locations->SetInAt(0, Location::RequiresRegister()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-float' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: { - // Processing a Dex `long-to-float' instruction. InvokeRuntimeCallingConventionARMVIXL calling_convention; locations->SetInAt(0, LocationFrom(calling_convention.GetRegisterAt(0), calling_convention.GetRegisterAt(1))); @@ -3892,7 +3885,6 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { } case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -3906,18 +3898,16 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-double' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: - // Processing a Dex `long-to-double' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresFpuRegister()); locations->AddTemp(Location::RequiresFpuRegister()); @@ -3925,7 +3915,6 @@ void LocationsBuilderARMVIXL::VisitTypeConversion(HTypeConversion* conversion) { break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -3948,22 +3937,38 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve Location in = locations->InAt(0); DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; switch (result_type) { - case DataType::Type::kInt8: + case DataType::Type::kUint8: switch (input_type) { + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + __ Ubfx(OutputRegister(conversion), InputRegisterAt(conversion, 0), 0, 8); + break; case DataType::Type::kInt64: - // Type conversion from long to byte is a result of code transformations. - __ Sbfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 8); + __ Ubfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 8); break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt8: + switch (input_type) { + case DataType::Type::kUint8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. __ Sbfx(OutputRegister(conversion), InputRegisterAt(conversion, 0), 0, 8); break; + case DataType::Type::kInt64: + __ Sbfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 8); + break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type @@ -3971,20 +3976,32 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve } break; - case DataType::Type::kInt16: + case DataType::Type::kUint16: switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - __ Sbfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 16); - break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. case DataType::Type::kInt8: + case DataType::Type::kInt16: case DataType::Type::kInt32: + __ Ubfx(OutputRegister(conversion), InputRegisterAt(conversion, 0), 0, 16); + break; + case DataType::Type::kInt64: + __ Ubfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 16); + break; + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt16: + switch (input_type) { case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. + case DataType::Type::kInt32: __ Sbfx(OutputRegister(conversion), InputRegisterAt(conversion, 0), 0, 16); break; + case DataType::Type::kInt64: + __ Sbfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 16); + break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type @@ -3995,7 +4012,6 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. DCHECK(out.IsRegister()); if (in.IsRegisterPair()) { __ Mov(OutputRegister(conversion), LowRegisterFrom(in)); @@ -4013,7 +4029,6 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve break; case DataType::Type::kFloat32: { - // Processing a Dex `float-to-int' instruction. vixl32::SRegister temp = LowSRegisterFrom(locations->GetTemp(0)); __ Vcvt(S32, F32, temp, InputSRegisterAt(conversion, 0)); __ Vmov(OutputRegister(conversion), temp); @@ -4021,7 +4036,6 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve } case DataType::Type::kFloat64: { - // Processing a Dex `double-to-int' instruction. vixl32::SRegister temp_s = LowSRegisterFrom(locations->GetTemp(0)); __ Vcvt(S32, F64, temp_s, DRegisterFrom(in)); __ Vmov(OutputRegister(conversion), temp_s); @@ -4037,12 +4051,11 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. DCHECK(out.IsRegisterPair()); DCHECK(in.IsRegister()); __ Mov(LowRegisterFrom(out), InputRegisterAt(conversion, 0)); @@ -4051,13 +4064,11 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-long' instruction. codegen_->InvokeRuntime(kQuickF2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickF2l, int64_t, float>(); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-long' instruction. codegen_->InvokeRuntime(kQuickD2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickD2l, int64_t, double>(); break; @@ -4068,49 +4079,24 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to char is a result of code transformations. - __ Ubfx(OutputRegister(conversion), LowRegisterFrom(in), 0, 16); - break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `int-to-char' instruction. - __ Ubfx(OutputRegister(conversion), InputRegisterAt(conversion, 0), 0, 16); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: { - // Processing a Dex `int-to-float' instruction. __ Vmov(OutputSRegister(conversion), InputRegisterAt(conversion, 0)); __ Vcvt(F32, S32, OutputSRegister(conversion), OutputSRegister(conversion)); break; - } case DataType::Type::kInt64: - // Processing a Dex `long-to-float' instruction. codegen_->InvokeRuntime(kQuickL2f, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickL2f, float, int64_t>(); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. __ Vcvt(F32, F64, OutputSRegister(conversion), DRegisterFrom(in)); break; @@ -4123,19 +4109,16 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: { - // Processing a Dex `int-to-double' instruction. __ Vmov(LowSRegisterFrom(out), InputRegisterAt(conversion, 0)); __ Vcvt(F64, S32, DRegisterFrom(out), LowSRegisterFrom(out)); break; - } case DataType::Type::kInt64: { - // Processing a Dex `long-to-double' instruction. vixl32::Register low = LowRegisterFrom(in); vixl32::Register high = HighRegisterFrom(in); vixl32::SRegister out_s = LowSRegisterFrom(out); @@ -4158,7 +4141,6 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve } case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. __ Vcvt(F64, F32, DRegisterFrom(out), InputSRegisterAt(conversion, 0)); break; @@ -4760,6 +4742,7 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi switch (instruction->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -5288,9 +5271,10 @@ void LocationsBuilderARMVIXL::VisitCompare(HCompare* compare) { new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); @@ -5323,9 +5307,10 @@ void InstructionCodeGeneratorARMVIXL::VisitCompare(HCompare* compare) { vixl32::Condition less_cond = vixl32::Condition(kNone); switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { // Emit move to `out` before the `Cmp`, as `Mov` might affect the status flags. __ Mov(out, 0); @@ -5513,18 +5498,16 @@ void InstructionCodeGeneratorARMVIXL::HandleFieldSet(HInstruction* instruction, switch (field_type) { case DataType::Type::kBool: - case DataType::Type::kInt8: { - GetAssembler()->StoreToOffset(kStoreByte, RegisterFrom(value), base, offset); - break; - } - + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kUint16: { - GetAssembler()->StoreToOffset(kStoreHalfword, RegisterFrom(value), base, offset); + case DataType::Type::kInt32: { + StoreOperandType operand_type = GetStoreOperandType(field_type); + GetAssembler()->StoreToOffset(operand_type, RegisterFrom(value), base, offset); break; } - case DataType::Type::kInt32: case DataType::Type::kReference: { if (kPoisonHeapReferences && needs_write_barrier) { // Note that in the case where `value` is a null reference, @@ -5764,24 +5747,15 @@ void InstructionCodeGeneratorARMVIXL::HandleFieldGet(HInstruction* instruction, switch (field_type) { case DataType::Type::kBool: - GetAssembler()->LoadFromOffset(kLoadUnsignedByte, RegisterFrom(out), base, offset); - break; - + case DataType::Type::kUint8: case DataType::Type::kInt8: - GetAssembler()->LoadFromOffset(kLoadSignedByte, RegisterFrom(out), base, offset); - break; - - case DataType::Type::kInt16: - GetAssembler()->LoadFromOffset(kLoadSignedHalfword, RegisterFrom(out), base, offset); - break; - case DataType::Type::kUint16: - GetAssembler()->LoadFromOffset(kLoadUnsignedHalfword, RegisterFrom(out), base, offset); - break; - - case DataType::Type::kInt32: - GetAssembler()->LoadFromOffset(kLoadWord, RegisterFrom(out), base, offset); + case DataType::Type::kInt16: + case DataType::Type::kInt32: { + LoadOperandType operand_type = GetLoadOperandType(field_type); + GetAssembler()->LoadFromOffset(operand_type, RegisterFrom(out), base, offset); break; + } case DataType::Type::kReference: { // /* HeapReference<Object> */ out = *(base + offset) @@ -5995,56 +5969,6 @@ void InstructionCodeGeneratorARMVIXL::VisitNullCheck(HNullCheck* instruction) { codegen_->GenerateNullCheck(instruction); } -static LoadOperandType GetLoadOperandType(DataType::Type type) { - switch (type) { - case DataType::Type::kReference: - return kLoadWord; - case DataType::Type::kBool: - return kLoadUnsignedByte; - case DataType::Type::kInt8: - return kLoadSignedByte; - case DataType::Type::kUint16: - return kLoadUnsignedHalfword; - case DataType::Type::kInt16: - return kLoadSignedHalfword; - case DataType::Type::kInt32: - return kLoadWord; - case DataType::Type::kInt64: - return kLoadWordPair; - case DataType::Type::kFloat32: - return kLoadSWord; - case DataType::Type::kFloat64: - return kLoadDWord; - default: - LOG(FATAL) << "Unreachable type " << type; - UNREACHABLE(); - } -} - -static StoreOperandType GetStoreOperandType(DataType::Type type) { - switch (type) { - case DataType::Type::kReference: - return kStoreWord; - case DataType::Type::kBool: - case DataType::Type::kInt8: - return kStoreByte; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - return kStoreHalfword; - case DataType::Type::kInt32: - return kStoreWord; - case DataType::Type::kInt64: - return kStoreWordPair; - case DataType::Type::kFloat32: - return kStoreSWord; - case DataType::Type::kFloat64: - return kStoreDWord; - default: - LOG(FATAL) << "Unreachable type " << type; - UNREACHABLE(); - } -} - void CodeGeneratorARMVIXL::LoadFromShiftedRegOffset(DataType::Type type, Location out_loc, vixl32::Register base, @@ -6054,18 +5978,19 @@ void CodeGeneratorARMVIXL::LoadFromShiftedRegOffset(DataType::Type type, MemOperand mem_address(base, reg_index, vixl32::LSL, shift_count); switch (type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: __ Ldrsb(cond, RegisterFrom(out_loc), mem_address); break; case DataType::Type::kBool: __ Ldrb(cond, RegisterFrom(out_loc), mem_address); break; - case DataType::Type::kInt16: - __ Ldrsh(cond, RegisterFrom(out_loc), mem_address); - break; case DataType::Type::kUint16: __ Ldrh(cond, RegisterFrom(out_loc), mem_address); break; + case DataType::Type::kInt16: + __ Ldrsh(cond, RegisterFrom(out_loc), mem_address); + break; case DataType::Type::kReference: case DataType::Type::kInt32: __ Ldr(cond, RegisterFrom(out_loc), mem_address); @@ -6089,12 +6014,13 @@ void CodeGeneratorARMVIXL::StoreToShiftedRegOffset(DataType::Type type, MemOperand mem_address(base, reg_index, vixl32::LSL, shift_count); switch (type) { - case DataType::Type::kInt8: case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: __ Strb(cond, RegisterFrom(loc), mem_address); break; - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: __ Strh(cond, RegisterFrom(loc), mem_address); break; case DataType::Type::kReference: @@ -6182,9 +6108,10 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { vixl32::Register length; if (maybe_compressed_char_at) { @@ -6434,9 +6361,10 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { if (index.IsConstant()) { int32_t const_index = Int32ConstantFrom(index); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index a7c85574ee..70c8a5b523 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -51,12 +51,13 @@ constexpr bool kBakerReadBarrierThunksEnableForGcRoots = true; Location MipsReturnLocation(DataType::Type return_type) { switch (return_type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: return Location::RegisterLocation(V0); case DataType::Type::kInt64: @@ -84,12 +85,13 @@ Location InvokeDexCallingConventionVisitorMIPS::GetNextLocation(DataType::Type t Location next_location; switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kReference: { + case DataType::Type::kInt32: { uint32_t gp_index = gp_index_++; if (gp_index < calling_convention.GetNumberOfRegisters()) { next_location = Location::RegisterLocation(calling_convention.GetRegisterAt(gp_index)); @@ -2592,7 +2594,8 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { const bool maybe_compressed_char_at = mirror::kUseStringCompression && instruction->IsStringCharAt(); switch (type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { Register out = out_loc.AsRegister<Register>(); if (index.IsConstant()) { size_t offset = @@ -2618,19 +2621,6 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { break; } - case DataType::Type::kInt16: { - Register out = out_loc.AsRegister<Register>(); - if (index.IsConstant()) { - size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; - __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset, null_checker); - } else { - __ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_2, TMP); - __ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker); - } - break; - } - case DataType::Type::kUint16: { Register out = out_loc.AsRegister<Register>(); if (maybe_compressed_char_at) { @@ -2683,6 +2673,19 @@ void InstructionCodeGeneratorMIPS::VisitArrayGet(HArrayGet* instruction) { break; } + case DataType::Type::kInt16: { + Register out = out_loc.AsRegister<Register>(); + if (index.IsConstant()) { + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; + __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset, null_checker); + } else { + __ ShiftAndAdd(TMP, index.AsRegister<Register>(), obj, TIMES_2, TMP); + __ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker); + } + break; + } + case DataType::Type::kInt32: { DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Object>), sizeof(int32_t)); Register out = out_loc.AsRegister<Register>(); @@ -2880,6 +2883,7 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); if (index.IsConstant()) { @@ -2897,8 +2901,8 @@ void InstructionCodeGeneratorMIPS::VisitArraySet(HArraySet* instruction) { break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); if (index.IsConstant()) { data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2; @@ -3390,9 +3394,10 @@ void LocationsBuilderMIPS::VisitCompare(HCompare* compare) { switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::RequiresRegister()); @@ -3429,9 +3434,10 @@ void InstructionCodeGeneratorMIPS::VisitCompare(HCompare* instruction) { // -1 if: left < right switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { Register lhs = locations->InAt(0).AsRegister<Register>(); Register rhs = locations->InAt(1).AsRegister<Register>(); @@ -3833,6 +3839,7 @@ void InstructionCodeGeneratorMIPS::VisitDivZeroCheck(HDivZeroCheck* instruction) switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -6159,17 +6166,18 @@ void InstructionCodeGeneratorMIPS::HandleFieldGet(HInstruction* instruction, switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: load_type = kLoadUnsignedByte; break; case DataType::Type::kInt8: load_type = kLoadSignedByte; break; - case DataType::Type::kInt16: - load_type = kLoadSignedHalfword; - break; case DataType::Type::kUint16: load_type = kLoadUnsignedHalfword; break; + case DataType::Type::kInt16: + load_type = kLoadSignedHalfword; + break; case DataType::Type::kInt32: case DataType::Type::kFloat32: case DataType::Type::kReference: @@ -6312,11 +6320,12 @@ void InstructionCodeGeneratorMIPS::HandleFieldSet(HInstruction* instruction, switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: store_type = kStoreByte; break; - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: store_type = kStoreHalfword; break; case DataType::Type::kInt32: @@ -8601,7 +8610,8 @@ void InstructionCodeGeneratorMIPS::VisitThrow(HThrow* instruction) { void LocationsBuilderMIPS::VisitTypeConversion(HTypeConversion* conversion) { DataType::Type input_type = conversion->GetInputType(); DataType::Type result_type = conversion->GetResultType(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; bool isR6 = codegen_->GetInstructionSetFeatures().IsR6(); if ((input_type == DataType::Type::kReference) || (input_type == DataType::Type::kVoid) || @@ -8652,7 +8662,8 @@ void InstructionCodeGeneratorMIPS::VisitTypeConversion(HTypeConversion* conversi bool has_sign_extension = codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2(); bool isR6 = codegen_->GetInstructionSetFeatures().IsR6(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; if (result_type == DataType::Type::kInt64 && DataType::IsIntegralType(input_type)) { Register dst_high = locations->Out().AsRegisterPairHigh<Register>(); @@ -8670,8 +8681,8 @@ void InstructionCodeGeneratorMIPS::VisitTypeConversion(HTypeConversion* conversi : locations->InAt(0).AsRegister<Register>(); switch (result_type) { - case DataType::Type::kUint16: - __ Andi(dst, src, 0xFFFF); + case DataType::Type::kUint8: + __ Andi(dst, src, 0xFF); break; case DataType::Type::kInt8: if (has_sign_extension) { @@ -8681,6 +8692,9 @@ void InstructionCodeGeneratorMIPS::VisitTypeConversion(HTypeConversion* conversi __ Sra(dst, dst, 24); } break; + case DataType::Type::kUint16: + __ Andi(dst, src, 0xFFFF); + break; case DataType::Type::kInt16: if (has_sign_extension) { __ Seh(dst, src); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 7051ccefdc..687700380b 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -50,6 +50,7 @@ constexpr bool kBakerReadBarrierThunksEnableForGcRoots = true; Location Mips64ReturnLocation(DataType::Type return_type) { switch (return_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -2170,7 +2171,8 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { const bool maybe_compressed_char_at = mirror::kUseStringCompression && instruction->IsStringCharAt(); switch (type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { GpuRegister out = out_loc.AsRegister<GpuRegister>(); if (index.IsConstant()) { size_t offset = @@ -2196,19 +2198,6 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { break; } - case DataType::Type::kInt16: { - GpuRegister out = out_loc.AsRegister<GpuRegister>(); - if (index.IsConstant()) { - size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; - __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset, null_checker); - } else { - __ Dlsa(TMP, index.AsRegister<GpuRegister>(), obj, TIMES_2); - __ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker); - } - break; - } - case DataType::Type::kUint16: { GpuRegister out = out_loc.AsRegister<GpuRegister>(); if (maybe_compressed_char_at) { @@ -2261,6 +2250,19 @@ void InstructionCodeGeneratorMIPS64::VisitArrayGet(HArrayGet* instruction) { break; } + case DataType::Type::kInt16: { + GpuRegister out = out_loc.AsRegister<GpuRegister>(); + if (index.IsConstant()) { + size_t offset = + (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset; + __ LoadFromOffset(kLoadSignedHalfword, out, obj, offset, null_checker); + } else { + __ Dlsa(TMP, index.AsRegister<GpuRegister>(), obj, TIMES_2); + __ LoadFromOffset(kLoadSignedHalfword, out, TMP, data_offset, null_checker); + } + break; + } + case DataType::Type::kInt32: { DCHECK_EQ(sizeof(mirror::HeapReference<mirror::Object>), sizeof(int32_t)); GpuRegister out = out_loc.AsRegister<GpuRegister>(); @@ -2460,6 +2462,7 @@ void InstructionCodeGeneratorMIPS64::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); if (index.IsConstant()) { @@ -2477,8 +2480,8 @@ void InstructionCodeGeneratorMIPS64::VisitArraySet(HArraySet* instruction) { break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { uint32_t data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); if (index.IsConstant()) { data_offset += index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2; @@ -2969,9 +2972,10 @@ void LocationsBuilderMIPS64::VisitCompare(HCompare* compare) { switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: locations->SetInAt(0, Location::RequiresRegister()); @@ -3001,9 +3005,10 @@ void InstructionCodeGeneratorMIPS64::VisitCompare(HCompare* instruction) { // -1 if: left < right switch (in_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { GpuRegister lhs = locations->InAt(0).AsRegister<GpuRegister>(); @@ -4681,17 +4686,18 @@ void InstructionCodeGeneratorMIPS64::HandleFieldGet(HInstruction* instruction, switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: load_type = kLoadUnsignedByte; break; case DataType::Type::kInt8: load_type = kLoadSignedByte; break; - case DataType::Type::kInt16: - load_type = kLoadSignedHalfword; - break; case DataType::Type::kUint16: load_type = kLoadUnsignedHalfword; break; + case DataType::Type::kInt16: + load_type = kLoadSignedHalfword; + break; case DataType::Type::kInt32: case DataType::Type::kFloat32: load_type = kLoadWord; @@ -4779,11 +4785,12 @@ void InstructionCodeGeneratorMIPS64::HandleFieldSet(HInstruction* instruction, switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: store_type = kStoreByte; break; - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: store_type = kStoreHalfword; break; case DataType::Type::kInt32: @@ -6767,7 +6774,8 @@ void InstructionCodeGeneratorMIPS64::VisitThrow(HThrow* instruction) { void LocationsBuilderMIPS64::VisitTypeConversion(HTypeConversion* conversion) { DataType::Type input_type = conversion->GetInputType(); DataType::Type result_type = conversion->GetResultType(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; if ((input_type == DataType::Type::kReference) || (input_type == DataType::Type::kVoid) || (result_type == DataType::Type::kReference) || (result_type == DataType::Type::kVoid)) { @@ -6794,15 +6802,16 @@ void InstructionCodeGeneratorMIPS64::VisitTypeConversion(HTypeConversion* conver DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(input_type, result_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; if (DataType::IsIntegralType(result_type) && DataType::IsIntegralType(input_type)) { GpuRegister dst = locations->Out().AsRegister<GpuRegister>(); GpuRegister src = locations->InAt(0).AsRegister<GpuRegister>(); switch (result_type) { - case DataType::Type::kUint16: - __ Andi(dst, src, 0xFFFF); + case DataType::Type::kUint8: + __ Andi(dst, src, 0xFF); break; case DataType::Type::kInt8: if (input_type == DataType::Type::kInt64) { @@ -6815,6 +6824,9 @@ void InstructionCodeGeneratorMIPS64::VisitTypeConversion(HTypeConversion* conver __ Seb(dst, src); } break; + case DataType::Type::kUint16: + __ Andi(dst, src, 0xFFFF); + break; case DataType::Type::kInt16: if (input_type == DataType::Type::kInt64) { // Type conversion from long to types narrower than int is a result of code diff --git a/compiler/optimizing/code_generator_vector_arm64.cc b/compiler/optimizing/code_generator_vector_arm64.cc index 5d5623bbe7..b2aec1e66d 100644 --- a/compiler/optimizing/code_generator_vector_arm64.cc +++ b/compiler/optimizing/code_generator_vector_arm64.cc @@ -42,6 +42,7 @@ void LocationsBuilderARM64::VisitVecReplicateScalar(HVecReplicateScalar* instruc HInstruction* input = instruction->InputAt(0); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -73,6 +74,7 @@ void InstructionCodeGeneratorARM64::VisitVecReplicateScalar(HVecReplicateScalar* VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); if (src_loc.IsConstant()) { @@ -132,6 +134,7 @@ void LocationsBuilderARM64::VisitVecExtractScalar(HVecExtractScalar* instruction LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -185,6 +188,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in instruction->IsVecNot() ? Location::kOutputOverlap : Location::kNoOutputOverlap); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -268,6 +272,7 @@ void InstructionCodeGeneratorARM64::VisitVecNeg(HVecNeg* instruction) { VRegister src = VRegisterFrom(locations->InAt(0)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Neg(dst.V16B(), src.V16B()); @@ -312,7 +317,6 @@ void InstructionCodeGeneratorARM64::VisitVecAbs(HVecAbs* instruction) { DCHECK_EQ(16u, instruction->GetVectorLength()); __ Abs(dst.V16B(), src.V16B()); break; - case DataType::Type::kUint16: case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Abs(dst.V8H(), src.V8H()); @@ -353,6 +357,7 @@ void InstructionCodeGeneratorARM64::VisitVecNot(HVecNot* instruction) { __ Movi(dst.V16B(), 1); __ Eor(dst.V16B(), dst.V16B(), src.V16B()); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -371,6 +376,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -398,6 +404,7 @@ void InstructionCodeGeneratorARM64::VisitVecAdd(HVecAdd* instruction) { VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Add(dst.V16B(), lhs.V16B(), rhs.V16B()); @@ -439,30 +446,29 @@ void InstructionCodeGeneratorARM64::VisitVecHalvingAdd(HVecHalvingAdd* instructi VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Urhadd(dst.V16B(), lhs.V16B(), rhs.V16B()) + : __ Uhadd(dst.V16B(), lhs.V16B(), rhs.V16B()); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Urhadd(dst.V16B(), lhs.V16B(), rhs.V16B()) - : __ Uhadd(dst.V16B(), lhs.V16B(), rhs.V16B()); - } else { - instruction->IsRounded() - ? __ Srhadd(dst.V16B(), lhs.V16B(), rhs.V16B()) - : __ Shadd(dst.V16B(), lhs.V16B(), rhs.V16B()); - } + instruction->IsRounded() + ? __ Srhadd(dst.V16B(), lhs.V16B(), rhs.V16B()) + : __ Shadd(dst.V16B(), lhs.V16B(), rhs.V16B()); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Urhadd(dst.V8H(), lhs.V8H(), rhs.V8H()) + : __ Uhadd(dst.V8H(), lhs.V8H(), rhs.V8H()); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Urhadd(dst.V8H(), lhs.V8H(), rhs.V8H()) - : __ Uhadd(dst.V8H(), lhs.V8H(), rhs.V8H()); - } else { - instruction->IsRounded() - ? __ Srhadd(dst.V8H(), lhs.V8H(), rhs.V8H()) - : __ Shadd(dst.V8H(), lhs.V8H(), rhs.V8H()); - } + instruction->IsRounded() + ? __ Srhadd(dst.V8H(), lhs.V8H(), rhs.V8H()) + : __ Shadd(dst.V8H(), lhs.V8H(), rhs.V8H()); break; default: LOG(FATAL) << "Unsupported SIMD type"; @@ -480,6 +486,7 @@ void InstructionCodeGeneratorARM64::VisitVecSub(HVecSub* instruction) { VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Sub(dst.V16B(), lhs.V16B(), rhs.V16B()); @@ -521,6 +528,7 @@ void InstructionCodeGeneratorARM64::VisitVecMul(HVecMul* instruction) { VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Mul(dst.V16B(), lhs.V16B(), rhs.V16B()); @@ -582,22 +590,21 @@ void InstructionCodeGeneratorARM64::VisitVecMin(HVecMin* instruction) { VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Umin(dst.V16B(), lhs.V16B(), rhs.V16B()); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Umin(dst.V16B(), lhs.V16B(), rhs.V16B()); - } else { - __ Smin(dst.V16B(), lhs.V16B(), rhs.V16B()); - } + __ Smin(dst.V16B(), lhs.V16B(), rhs.V16B()); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Umin(dst.V8H(), lhs.V8H(), rhs.V8H()); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Umin(dst.V8H(), lhs.V8H(), rhs.V8H()); - } else { - __ Smin(dst.V8H(), lhs.V8H(), rhs.V8H()); - } + __ Smin(dst.V8H(), lhs.V8H(), rhs.V8H()); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -633,22 +640,21 @@ void InstructionCodeGeneratorARM64::VisitVecMax(HVecMax* instruction) { VRegister rhs = VRegisterFrom(locations->InAt(1)); VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Umax(dst.V16B(), lhs.V16B(), rhs.V16B()); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Umax(dst.V16B(), lhs.V16B(), rhs.V16B()); - } else { - __ Smax(dst.V16B(), lhs.V16B(), rhs.V16B()); - } + __ Smax(dst.V16B(), lhs.V16B(), rhs.V16B()); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Umax(dst.V8H(), lhs.V8H(), rhs.V8H()); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Umax(dst.V8H(), lhs.V8H(), rhs.V8H()); - } else { - __ Smax(dst.V8H(), lhs.V8H(), rhs.V8H()); - } + __ Smax(dst.V8H(), lhs.V8H(), rhs.V8H()); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -675,6 +681,7 @@ void InstructionCodeGeneratorARM64::VisitVecMax(HVecMax* instruction) { } void LocationsBuilderARM64::VisitVecAnd(HVecAnd* instruction) { + // TODO: Allow constants supported by BIC (vector, immediate). CreateVecBinOpLocations(GetGraph()->GetArena(), instruction); } @@ -685,6 +692,7 @@ void InstructionCodeGeneratorARM64::VisitVecAnd(HVecAnd* instruction) { VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -705,6 +713,7 @@ void LocationsBuilderARM64::VisitVecAndNot(HVecAndNot* instruction) { } void InstructionCodeGeneratorARM64::VisitVecAndNot(HVecAndNot* instruction) { + // TODO: Use BIC (vector, register). LOG(FATAL) << "Unsupported SIMD instruction " << instruction->GetId(); } @@ -719,6 +728,7 @@ void InstructionCodeGeneratorARM64::VisitVecOr(HVecOr* instruction) { VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -745,6 +755,7 @@ void InstructionCodeGeneratorARM64::VisitVecXor(HVecXor* instruction) { VRegister dst = VRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -764,6 +775,7 @@ void InstructionCodeGeneratorARM64::VisitVecXor(HVecXor* instruction) { static void CreateVecShiftLocations(ArenaAllocator* arena, HVecBinaryOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -789,6 +801,7 @@ void InstructionCodeGeneratorARM64::VisitVecShl(HVecShl* instruction) { VRegister dst = VRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Shl(dst.V16B(), lhs.V16B(), value); @@ -822,6 +835,7 @@ void InstructionCodeGeneratorARM64::VisitVecShr(HVecShr* instruction) { VRegister dst = VRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Sshr(dst.V16B(), lhs.V16B(), value); @@ -855,6 +869,7 @@ void InstructionCodeGeneratorARM64::VisitVecUShr(HVecUShr* instruction) { VRegister dst = VRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Ushr(dst.V16B(), lhs.V16B(), value); @@ -888,6 +903,7 @@ void LocationsBuilderARM64::VisitVecSetScalars(HVecSetScalars* instruction) { switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -926,6 +942,7 @@ void InstructionCodeGeneratorARM64::VisitVecSetScalars(HVecSetScalars* instructi // Set required elements. switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ Mov(dst.V16B(), 0, InputRegisterAt(instruction, 0)); @@ -953,6 +970,7 @@ void InstructionCodeGeneratorARM64::VisitVecSetScalars(HVecSetScalars* instructi static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -985,6 +1003,7 @@ void InstructionCodeGeneratorARM64::VisitVecMultiplyAccumulate(HVecMultiplyAccum DCHECK(locations->InAt(0).Equals(locations->Out())); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); if (instruction->GetOpKind() == HInstruction::kAdd) { @@ -1024,6 +1043,7 @@ void LocationsBuilderARM64::VisitVecSADAccumulate(HVecSADAccumulate* instruction HVecOperation* b = instruction->InputAt(2)->AsVecOperation(); DCHECK_EQ(a->GetPackedType(), b->GetPackedType()); switch (a->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: switch (instruction->GetPackedType()) { case DataType::Type::kInt64: @@ -1069,10 +1089,10 @@ void InstructionCodeGeneratorARM64::VisitVecSADAccumulate(HVecSADAccumulate* ins HVecOperation* b = instruction->InputAt(2)->AsVecOperation(); DCHECK_EQ(a->GetPackedType(), b->GetPackedType()); switch (a->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, a->GetVectorLength()); switch (instruction->GetPackedType()) { - case DataType::Type::kUint16: case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Sabal(acc.V8H(), left.V8B(), right.V8B()); @@ -1202,6 +1222,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1300,6 +1321,7 @@ void InstructionCodeGeneratorARM64::VisitVecLoad(HVecLoad* instruction) { } FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kInt16: case DataType::Type::kInt32: @@ -1329,6 +1351,7 @@ void InstructionCodeGeneratorARM64::VisitVecStore(HVecStore* instruction) { switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/code_generator_vector_arm_vixl.cc b/compiler/optimizing/code_generator_vector_arm_vixl.cc index 333d108f2c..df757524a1 100644 --- a/compiler/optimizing/code_generator_vector_arm_vixl.cc +++ b/compiler/optimizing/code_generator_vector_arm_vixl.cc @@ -36,6 +36,7 @@ void LocationsBuilderARMVIXL::VisitVecReplicateScalar(HVecReplicateScalar* instr LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -54,6 +55,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecReplicateScalar(HVecReplicateScala vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vdup(Untyped8, dst, InputRegisterAt(instruction, 0)); @@ -91,6 +93,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in instruction->IsVecNot() ? Location::kOutputOverlap : Location::kNoOutputOverlap); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -129,6 +132,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecNeg(HVecNeg* instruction) { vixl32::DRegister src = DRegisterFrom(locations->InAt(0)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vneg(DataTypeValue::S8, dst, src); @@ -161,7 +165,6 @@ void InstructionCodeGeneratorARMVIXL::VisitVecAbs(HVecAbs* instruction) { DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vabs(DataTypeValue::S8, dst, src); break; - case DataType::Type::kUint16: case DataType::Type::kInt16: DCHECK_EQ(4u, instruction->GetVectorLength()); __ Vabs(DataTypeValue::S16, dst, src); @@ -190,6 +193,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecNot(HVecNot* instruction) { __ Vmov(I8, dst, 1); __ Veor(dst, dst, src); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -207,6 +211,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -231,6 +236,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecAdd(HVecAdd* instruction) { vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vadd(I8, dst, lhs, rhs); @@ -260,30 +266,29 @@ void InstructionCodeGeneratorARMVIXL::VisitVecHalvingAdd(HVecHalvingAdd* instruc vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(8u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Vrhadd(DataTypeValue::U8, dst, lhs, rhs) + : __ Vhadd(DataTypeValue::U8, dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Vrhadd(DataTypeValue::U8, dst, lhs, rhs) - : __ Vhadd(DataTypeValue::U8, dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Vrhadd(DataTypeValue::S8, dst, lhs, rhs) - : __ Vhadd(DataTypeValue::S8, dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Vrhadd(DataTypeValue::S8, dst, lhs, rhs) + : __ Vhadd(DataTypeValue::S8, dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(4u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Vrhadd(DataTypeValue::U16, dst, lhs, rhs) + : __ Vhadd(DataTypeValue::U16, dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(4u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Vrhadd(DataTypeValue::U16, dst, lhs, rhs) - : __ Vhadd(DataTypeValue::U16, dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Vrhadd(DataTypeValue::S16, dst, lhs, rhs) - : __ Vhadd(DataTypeValue::S16, dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Vrhadd(DataTypeValue::S16, dst, lhs, rhs) + : __ Vhadd(DataTypeValue::S16, dst, lhs, rhs); break; default: LOG(FATAL) << "Unsupported SIMD type"; @@ -301,6 +306,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecSub(HVecSub* instruction) { vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vsub(I8, dst, lhs, rhs); @@ -330,6 +336,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecMul(HVecMul* instruction) { vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vmul(I8, dst, lhs, rhs); @@ -367,22 +374,21 @@ void InstructionCodeGeneratorARMVIXL::VisitVecMin(HVecMin* instruction) { vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Vmin(DataTypeValue::U8, dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Vmin(DataTypeValue::U8, dst, lhs, rhs); - } else { - __ Vmin(DataTypeValue::S8, dst, lhs, rhs); - } + __ Vmin(DataTypeValue::S8, dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(4u, instruction->GetVectorLength()); + __ Vmin(DataTypeValue::U16, dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(4u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Vmin(DataTypeValue::U16, dst, lhs, rhs); - } else { - __ Vmin(DataTypeValue::S16, dst, lhs, rhs); - } + __ Vmin(DataTypeValue::S16, dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(2u, instruction->GetVectorLength()); @@ -408,22 +414,21 @@ void InstructionCodeGeneratorARMVIXL::VisitVecMax(HVecMax* instruction) { vixl32::DRegister rhs = DRegisterFrom(locations->InAt(1)); vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Vmax(DataTypeValue::U8, dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Vmax(DataTypeValue::U8, dst, lhs, rhs); - } else { - __ Vmax(DataTypeValue::S8, dst, lhs, rhs); - } + __ Vmax(DataTypeValue::S8, dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(4u, instruction->GetVectorLength()); + __ Vmax(DataTypeValue::U16, dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(4u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Vmax(DataTypeValue::U16, dst, lhs, rhs); - } else { - __ Vmax(DataTypeValue::S16, dst, lhs, rhs); - } + __ Vmax(DataTypeValue::S16, dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(2u, instruction->GetVectorLength()); @@ -440,6 +445,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecMax(HVecMax* instruction) { } void LocationsBuilderARMVIXL::VisitVecAnd(HVecAnd* instruction) { + // TODO: Allow constants supported by VAND (immediate). CreateVecBinOpLocations(GetGraph()->GetArena(), instruction); } @@ -450,6 +456,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecAnd(HVecAnd* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -481,6 +488,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecOr(HVecOr* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -504,6 +512,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecXor(HVecXor* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -520,6 +529,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecXor(HVecXor* instruction) { static void CreateVecShiftLocations(ArenaAllocator* arena, HVecBinaryOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -544,6 +554,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecShl(HVecShl* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vshl(I8, dst, lhs, value); @@ -573,6 +584,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecShr(HVecShr* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vshr(DataTypeValue::S8, dst, lhs, value); @@ -602,6 +614,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecUShr(HVecUShr* instruction) { vixl32::DRegister dst = DRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); __ Vshr(DataTypeValue::U8, dst, lhs, value); @@ -633,6 +646,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecSetScalars(HVecSetScalars* instruc static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -678,6 +692,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -764,6 +779,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecLoad(HVecLoad* instruction) { switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); if (IsWordAligned(instruction)) { @@ -811,6 +827,7 @@ void InstructionCodeGeneratorARMVIXL::VisitVecStore(HVecStore* instruction) { vixl32::Register scratch; switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(8u, instruction->GetVectorLength()); if (IsWordAligned(instruction)) { diff --git a/compiler/optimizing/code_generator_vector_mips.cc b/compiler/optimizing/code_generator_vector_mips.cc index c25f5acb7e..e8c515761c 100644 --- a/compiler/optimizing/code_generator_vector_mips.cc +++ b/compiler/optimizing/code_generator_vector_mips.cc @@ -27,6 +27,7 @@ void LocationsBuilderMIPS::VisitVecReplicateScalar(HVecReplicateScalar* instruct LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -51,6 +52,7 @@ void InstructionCodeGeneratorMIPS::VisitVecReplicateScalar(HVecReplicateScalar* VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ FillB(dst, locations->InAt(0).AsRegister<Register>()); @@ -106,6 +108,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in instruction->IsVecNot() ? Location::kOutputOverlap : Location::kNoOutputOverlap); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -160,6 +163,7 @@ void InstructionCodeGeneratorMIPS::VisitVecNeg(HVecNeg* instruction) { VectorRegister src = VectorRegisterFrom(locations->InAt(0)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ FillB(dst, ZERO); @@ -211,7 +215,6 @@ void InstructionCodeGeneratorMIPS::VisitVecAbs(HVecAbs* instruction) { __ FillB(dst, ZERO); // all zeroes __ Add_aB(dst, dst, src); // dst = abs(0) + abs(src) break; - case DataType::Type::kUint16: case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ FillH(dst, ZERO); // all zeroes @@ -259,6 +262,7 @@ void InstructionCodeGeneratorMIPS::VisitVecNot(HVecNot* instruction) { __ LdiB(dst, 1); __ XorV(dst, dst, src); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -281,6 +285,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -308,6 +313,7 @@ void InstructionCodeGeneratorMIPS::VisitVecAdd(HVecAdd* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ AddvB(dst, lhs, rhs); @@ -349,30 +355,29 @@ void InstructionCodeGeneratorMIPS::VisitVecHalvingAdd(HVecHalvingAdd* instructio VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Aver_uB(dst, lhs, rhs) + : __ Ave_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Aver_uB(dst, lhs, rhs) - : __ Ave_uB(dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Aver_sB(dst, lhs, rhs) - : __ Ave_sB(dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Aver_sB(dst, lhs, rhs) + : __ Ave_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Aver_uH(dst, lhs, rhs) + : __ Ave_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Aver_uH(dst, lhs, rhs) - : __ Ave_uH(dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Aver_sH(dst, lhs, rhs) - : __ Ave_sH(dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Aver_sH(dst, lhs, rhs) + : __ Ave_sH(dst, lhs, rhs); break; default: LOG(FATAL) << "Unsupported SIMD type"; @@ -390,6 +395,7 @@ void InstructionCodeGeneratorMIPS::VisitVecSub(HVecSub* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SubvB(dst, lhs, rhs); @@ -431,6 +437,7 @@ void InstructionCodeGeneratorMIPS::VisitVecMul(HVecMul* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ MulvB(dst, lhs, rhs); @@ -496,22 +503,21 @@ void InstructionCodeGeneratorMIPS::VisitVecMin(HVecMin* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Min_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Min_uB(dst, lhs, rhs); - } else { - __ Min_sB(dst, lhs, rhs); - } + __ Min_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Min_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Min_uH(dst, lhs, rhs); - } else { - __ Min_sH(dst, lhs, rhs); - } + __ Min_sH(dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -557,22 +563,21 @@ void InstructionCodeGeneratorMIPS::VisitVecMax(HVecMax* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Max_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Max_uB(dst, lhs, rhs); - } else { - __ Max_sB(dst, lhs, rhs); - } + __ Max_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Max_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Max_uH(dst, lhs, rhs); - } else { - __ Max_sH(dst, lhs, rhs); - } + __ Max_sH(dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -619,6 +624,7 @@ void InstructionCodeGeneratorMIPS::VisitVecAnd(HVecAnd* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -655,6 +661,7 @@ void InstructionCodeGeneratorMIPS::VisitVecOr(HVecOr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -683,6 +690,7 @@ void InstructionCodeGeneratorMIPS::VisitVecXor(HVecXor* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -704,6 +712,7 @@ void InstructionCodeGeneratorMIPS::VisitVecXor(HVecXor* instruction) { static void CreateVecShiftLocations(ArenaAllocator* arena, HVecBinaryOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -729,6 +738,7 @@ void InstructionCodeGeneratorMIPS::VisitVecShl(HVecShl* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SlliB(dst, lhs, value); @@ -762,6 +772,7 @@ void InstructionCodeGeneratorMIPS::VisitVecShr(HVecShr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SraiB(dst, lhs, value); @@ -795,6 +806,7 @@ void InstructionCodeGeneratorMIPS::VisitVecUShr(HVecUShr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SrliB(dst, lhs, value); @@ -830,6 +842,7 @@ void InstructionCodeGeneratorMIPS::VisitVecSetScalars(HVecSetScalars* instructio static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -856,6 +869,7 @@ void InstructionCodeGeneratorMIPS::VisitVecMultiplyAccumulate(HVecMultiplyAccumu VectorRegister left = VectorRegisterFrom(locations->InAt(1)); VectorRegister right = VectorRegisterFrom(locations->InAt(2)); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); if (instruction->GetOpKind() == HInstruction::kAdd) { @@ -911,6 +925,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -976,6 +991,7 @@ void InstructionCodeGeneratorMIPS::VisitVecLoad(HVecLoad* instruction) { int32_t offset = VecAddress(locations, size, &base); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ LdB(reg, base, offset); @@ -1018,6 +1034,7 @@ void InstructionCodeGeneratorMIPS::VisitVecStore(HVecStore* instruction) { int32_t offset = VecAddress(locations, size, &base); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ StB(reg, base, offset); diff --git a/compiler/optimizing/code_generator_vector_mips64.cc b/compiler/optimizing/code_generator_vector_mips64.cc index f60f708976..7d69773ae6 100644 --- a/compiler/optimizing/code_generator_vector_mips64.cc +++ b/compiler/optimizing/code_generator_vector_mips64.cc @@ -32,6 +32,7 @@ void LocationsBuilderMIPS64::VisitVecReplicateScalar(HVecReplicateScalar* instru LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -56,6 +57,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecReplicateScalar(HVecReplicateScalar VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ FillB(dst, locations->InAt(0).AsRegister<GpuRegister>()); @@ -109,6 +111,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in instruction->IsVecNot() ? Location::kOutputOverlap : Location::kNoOutputOverlap); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -164,6 +167,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecNeg(HVecNeg* instruction) { VectorRegister src = VectorRegisterFrom(locations->InAt(0)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ FillB(dst, ZERO); @@ -215,7 +219,6 @@ void InstructionCodeGeneratorMIPS64::VisitVecAbs(HVecAbs* instruction) { __ FillB(dst, ZERO); // all zeroes __ Add_aB(dst, dst, src); // dst = abs(0) + abs(src) break; - case DataType::Type::kUint16: case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ FillH(dst, ZERO); // all zeroes @@ -263,6 +266,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecNot(HVecNot* instruction) { __ LdiB(dst, 1); __ XorV(dst, dst, src); break; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -285,6 +289,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -312,6 +317,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecAdd(HVecAdd* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ AddvB(dst, lhs, rhs); @@ -353,30 +359,29 @@ void InstructionCodeGeneratorMIPS64::VisitVecHalvingAdd(HVecHalvingAdd* instruct VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Aver_uB(dst, lhs, rhs) + : __ Ave_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Aver_uB(dst, lhs, rhs) - : __ Ave_uB(dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Aver_sB(dst, lhs, rhs) - : __ Ave_sB(dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Aver_sB(dst, lhs, rhs) + : __ Ave_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + instruction->IsRounded() + ? __ Aver_uH(dst, lhs, rhs) + : __ Ave_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - instruction->IsRounded() - ? __ Aver_uH(dst, lhs, rhs) - : __ Ave_uH(dst, lhs, rhs); - } else { - instruction->IsRounded() - ? __ Aver_sH(dst, lhs, rhs) - : __ Ave_sH(dst, lhs, rhs); - } + instruction->IsRounded() + ? __ Aver_sH(dst, lhs, rhs) + : __ Ave_sH(dst, lhs, rhs); break; default: LOG(FATAL) << "Unsupported SIMD type"; @@ -394,6 +399,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecSub(HVecSub* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SubvB(dst, lhs, rhs); @@ -435,6 +441,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecMul(HVecMul* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ MulvB(dst, lhs, rhs); @@ -500,22 +507,21 @@ void InstructionCodeGeneratorMIPS64::VisitVecMin(HVecMin* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Min_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Min_uB(dst, lhs, rhs); - } else { - __ Min_sB(dst, lhs, rhs); - } + __ Min_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Min_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Min_uH(dst, lhs, rhs); - } else { - __ Min_sH(dst, lhs, rhs); - } + __ Min_sH(dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -561,22 +567,21 @@ void InstructionCodeGeneratorMIPS64::VisitVecMax(HVecMax* instruction) { VectorRegister rhs = VectorRegisterFrom(locations->InAt(1)); VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ Max_uB(dst, lhs, rhs); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Max_uB(dst, lhs, rhs); - } else { - __ Max_sB(dst, lhs, rhs); - } + __ Max_sB(dst, lhs, rhs); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ Max_uH(dst, lhs, rhs); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ Max_uH(dst, lhs, rhs); - } else { - __ Max_sH(dst, lhs, rhs); - } + __ Max_sH(dst, lhs, rhs); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -623,6 +628,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecAnd(HVecAnd* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -659,6 +665,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecOr(HVecOr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -687,6 +694,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecXor(HVecXor* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -708,6 +716,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecXor(HVecXor* instruction) { static void CreateVecShiftLocations(ArenaAllocator* arena, HVecBinaryOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -733,6 +742,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecShl(HVecShl* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SlliB(dst, lhs, value); @@ -766,6 +776,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecShr(HVecShr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SraiB(dst, lhs, value); @@ -799,6 +810,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecUShr(HVecUShr* instruction) { VectorRegister dst = VectorRegisterFrom(locations->Out()); int32_t value = locations->InAt(1).GetConstant()->AsIntConstant()->GetValue(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ SrliB(dst, lhs, value); @@ -834,6 +846,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecSetScalars(HVecSetScalars* instruct static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -860,6 +873,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecMultiplyAccumulate(HVecMultiplyAccu VectorRegister left = VectorRegisterFrom(locations->InAt(1)); VectorRegister right = VectorRegisterFrom(locations->InAt(2)); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); if (instruction->GetOpKind() == HInstruction::kAdd) { @@ -915,6 +929,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -980,6 +995,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecLoad(HVecLoad* instruction) { int32_t offset = VecAddress(locations, size, &base); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ LdB(reg, base, offset); @@ -1022,6 +1038,7 @@ void InstructionCodeGeneratorMIPS64::VisitVecStore(HVecStore* instruction) { int32_t offset = VecAddress(locations, size, &base); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ StB(reg, base, offset); diff --git a/compiler/optimizing/code_generator_vector_x86.cc b/compiler/optimizing/code_generator_vector_x86.cc index 6515dbe7b7..a2ef1b1be9 100644 --- a/compiler/optimizing/code_generator_vector_x86.cc +++ b/compiler/optimizing/code_generator_vector_x86.cc @@ -37,6 +37,7 @@ void LocationsBuilderX86::VisitVecReplicateScalar(HVecReplicateScalar* instructi } FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -70,6 +71,7 @@ void InstructionCodeGeneratorX86::VisitVecReplicateScalar(HVecReplicateScalar* i switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ movd(dst, locations->InAt(0).AsRegister<Register>()); @@ -122,6 +124,7 @@ void LocationsBuilderX86::VisitVecExtractScalar(HVecExtractScalar* instruction) locations->AddTemp(Location::RequiresFpuRegister()); FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -145,6 +148,7 @@ void InstructionCodeGeneratorX86::VisitVecExtractScalar(HVecExtractScalar* instr XmmRegister src = locations->InAt(0).AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: // TODO: up to here, and? @@ -180,6 +184,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -290,6 +295,7 @@ void InstructionCodeGeneratorX86::VisitVecNeg(HVecNeg* instruction) { XmmRegister src = locations->InAt(0).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ pxor(dst, dst); @@ -390,6 +396,7 @@ void InstructionCodeGeneratorX86::VisitVecNot(HVecNot* instruction) { __ pxor(dst, src); break; } + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -421,6 +428,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -448,6 +456,7 @@ void InstructionCodeGeneratorX86::VisitVecAdd(HVecAdd* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ paddb(dst, src); @@ -490,15 +499,13 @@ void InstructionCodeGeneratorX86::VisitVecHalvingAdd(HVecHalvingAdd* instruction XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); DCHECK(instruction->IsRounded()); - DCHECK(instruction->IsUnsigned()); switch (instruction->GetPackedType()) { - case DataType::Type::kInt8: + case DataType::Type::kUint8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ pavgb(dst, src); return; case DataType::Type::kUint16: - case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ pavgw(dst, src); return; @@ -518,6 +525,7 @@ void InstructionCodeGeneratorX86::VisitVecSub(HVecSub* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ psubb(dst, src); @@ -616,22 +624,21 @@ void InstructionCodeGeneratorX86::VisitVecMin(HVecMin* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ pminub(dst, src); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pminub(dst, src); - } else { - __ pminsb(dst, src); - } + __ pminsb(dst, src); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ pminuw(dst, src); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pminuw(dst, src); - } else { - __ pminsw(dst, src); - } + __ pminsw(dst, src); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -668,22 +675,21 @@ void InstructionCodeGeneratorX86::VisitVecMax(HVecMax* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ pmaxub(dst, src); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pmaxub(dst, src); - } else { - __ pmaxsb(dst, src); - } + __ pmaxsb(dst, src); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ pmaxuw(dst, src); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pmaxuw(dst, src); - } else { - __ pmaxsw(dst, src); - } + __ pmaxsw(dst, src); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -721,6 +727,7 @@ void InstructionCodeGeneratorX86::VisitVecAnd(HVecAnd* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -755,6 +762,7 @@ void InstructionCodeGeneratorX86::VisitVecAndNot(HVecAndNot* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -789,6 +797,7 @@ void InstructionCodeGeneratorX86::VisitVecOr(HVecOr* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -823,6 +832,7 @@ void InstructionCodeGeneratorX86::VisitVecXor(HVecXor* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -963,6 +973,7 @@ void LocationsBuilderX86::VisitVecSetScalars(HVecSetScalars* instruction) { } FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1000,6 +1011,7 @@ void InstructionCodeGeneratorX86::VisitVecSetScalars(HVecSetScalars* instruction // Set required elements. switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: // TODO: up to here, and? @@ -1036,6 +1048,7 @@ void InstructionCodeGeneratorX86::VisitVecSetScalars(HVecSetScalars* instruction static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1077,6 +1090,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1156,6 +1170,7 @@ void InstructionCodeGeneratorX86::VisitVecLoad(HVecLoad* instruction) { } FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kInt16: case DataType::Type::kInt32: @@ -1190,6 +1205,7 @@ void InstructionCodeGeneratorX86::VisitVecStore(HVecStore* instruction) { bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/code_generator_vector_x86_64.cc b/compiler/optimizing/code_generator_vector_x86_64.cc index 4241042574..2270f6b9c8 100644 --- a/compiler/optimizing/code_generator_vector_x86_64.cc +++ b/compiler/optimizing/code_generator_vector_x86_64.cc @@ -31,6 +31,7 @@ void LocationsBuilderX86_64::VisitVecReplicateScalar(HVecReplicateScalar* instru bool is_zero = IsZeroBitPattern(input); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -65,6 +66,7 @@ void InstructionCodeGeneratorX86_64::VisitVecReplicateScalar(HVecReplicateScalar switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ movd(dst, locations->InAt(0).AsRegister<CpuRegister>(), /*64-bit*/ false); @@ -109,6 +111,7 @@ void LocationsBuilderX86_64::VisitVecExtractScalar(HVecExtractScalar* instructio LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -133,6 +136,7 @@ void InstructionCodeGeneratorX86_64::VisitVecExtractScalar(HVecExtractScalar* in XmmRegister src = locations->InAt(0).AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: // TODO: up to here, and? @@ -163,6 +167,7 @@ static void CreateVecUnOpLocations(ArenaAllocator* arena, HVecUnaryOperation* in LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -273,6 +278,7 @@ void InstructionCodeGeneratorX86_64::VisitVecNeg(HVecNeg* instruction) { XmmRegister src = locations->InAt(0).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ pxor(dst, dst); @@ -373,6 +379,7 @@ void InstructionCodeGeneratorX86_64::VisitVecNot(HVecNot* instruction) { __ pxor(dst, src); break; } + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -404,6 +411,7 @@ static void CreateVecBinOpLocations(ArenaAllocator* arena, HVecBinaryOperation* LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -431,6 +439,7 @@ void InstructionCodeGeneratorX86_64::VisitVecAdd(HVecAdd* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ paddb(dst, src); @@ -473,15 +482,13 @@ void InstructionCodeGeneratorX86_64::VisitVecHalvingAdd(HVecHalvingAdd* instruct XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); DCHECK(instruction->IsRounded()); - DCHECK(instruction->IsUnsigned()); switch (instruction->GetPackedType()) { - case DataType::Type::kInt8: + case DataType::Type::kUint8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ pavgb(dst, src); return; case DataType::Type::kUint16: - case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); __ pavgw(dst, src); return; @@ -501,6 +508,7 @@ void InstructionCodeGeneratorX86_64::VisitVecSub(HVecSub* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); __ psubb(dst, src); @@ -599,22 +607,21 @@ void InstructionCodeGeneratorX86_64::VisitVecMin(HVecMin* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ pminub(dst, src); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pminub(dst, src); - } else { - __ pminsb(dst, src); - } + __ pminsb(dst, src); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ pminuw(dst, src); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pminuw(dst, src); - } else { - __ pminsw(dst, src); - } + __ pminsw(dst, src); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -651,22 +658,21 @@ void InstructionCodeGeneratorX86_64::VisitVecMax(HVecMax* instruction) { XmmRegister src = locations->InAt(1).AsFpuRegister<XmmRegister>(); XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: + DCHECK_EQ(16u, instruction->GetVectorLength()); + __ pmaxub(dst, src); + break; case DataType::Type::kInt8: DCHECK_EQ(16u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pmaxub(dst, src); - } else { - __ pmaxsb(dst, src); - } + __ pmaxsb(dst, src); break; case DataType::Type::kUint16: + DCHECK_EQ(8u, instruction->GetVectorLength()); + __ pmaxuw(dst, src); + break; case DataType::Type::kInt16: DCHECK_EQ(8u, instruction->GetVectorLength()); - if (instruction->IsUnsigned()) { - __ pmaxuw(dst, src); - } else { - __ pmaxsw(dst, src); - } + __ pmaxsw(dst, src); break; case DataType::Type::kInt32: DCHECK_EQ(4u, instruction->GetVectorLength()); @@ -704,6 +710,7 @@ void InstructionCodeGeneratorX86_64::VisitVecAnd(HVecAnd* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -738,6 +745,7 @@ void InstructionCodeGeneratorX86_64::VisitVecAndNot(HVecAndNot* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -772,6 +780,7 @@ void InstructionCodeGeneratorX86_64::VisitVecOr(HVecOr* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -806,6 +815,7 @@ void InstructionCodeGeneratorX86_64::VisitVecXor(HVecXor* instruction) { XmmRegister dst = locations->Out().AsFpuRegister<XmmRegister>(); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -940,6 +950,7 @@ void LocationsBuilderX86_64::VisitVecSetScalars(HVecSetScalars* instruction) { switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -978,6 +989,7 @@ void InstructionCodeGeneratorX86_64::VisitVecSetScalars(HVecSetScalars* instruct // Set required elements. switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: // TODO: up to here, and? @@ -1009,6 +1021,7 @@ void InstructionCodeGeneratorX86_64::VisitVecSetScalars(HVecSetScalars* instruct static void CreateVecAccumLocations(ArenaAllocator* arena, HVecOperation* instruction) { LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1050,6 +1063,7 @@ static void CreateVecMemLocations(ArenaAllocator* arena, LocationSummary* locations = new (arena) LocationSummary(instruction); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1129,6 +1143,7 @@ void InstructionCodeGeneratorX86_64::VisitVecLoad(HVecLoad* instruction) { } FALLTHROUGH_INTENDED; case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kInt16: case DataType::Type::kInt32: @@ -1163,6 +1178,7 @@ void InstructionCodeGeneratorX86_64::VisitVecStore(HVecStore* instruction) { bool is_aligned16 = instruction->GetAlignment().IsAlignedAt(16); switch (instruction->GetPackedType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 70e270e74d..35156491e8 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -1131,12 +1131,13 @@ void CodeGeneratorX86::Bind(HBasicBlock* block) { Location InvokeDexCallingConventionVisitorX86::GetReturnLocation(DataType::Type type) const { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: return Location::RegisterLocation(EAX); case DataType::Type::kInt64: @@ -1159,12 +1160,13 @@ Location InvokeDexCallingConventionVisitorX86::GetMethodLocation() const { Location InvokeDexCallingConventionVisitorX86::GetNextLocation(DataType::Type type) { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kReference: { + case DataType::Type::kInt32: { uint32_t index = gp_index_++; stack_index_++; if (index < calling_convention.GetNumberOfRegisters()) { @@ -2099,12 +2101,13 @@ void LocationsBuilderX86::VisitReturn(HReturn* ret) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(ret, LocationSummary::kNoCall); switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: locations->SetInAt(0, Location::RegisterLocation(EAX)); break; @@ -2127,12 +2130,13 @@ void LocationsBuilderX86::VisitReturn(HReturn* ret) { void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { if (kIsDebugBuild) { switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<Register>(), EAX); break; @@ -2408,7 +2412,8 @@ void InstructionCodeGeneratorX86::VisitX86FPNeg(HX86FPNeg* neg) { void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; // The float-to-long and double-to-long type conversions rely on a // call to the runtime. @@ -2420,14 +2425,21 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(conversion, call_kind); - // The Java language does not allow treating boolean as an integral type but - // our bit representation makes it safe. - switch (result_type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: switch (input_type) { + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + locations->SetInAt(0, Location::ByteRegisterOrConstant(ECX, conversion->InputAt(0))); + // Make the output overlap to please the register allocator. This greatly simplifies + // the validation of the linear scan implementation + locations->SetOut(Location::RequiresRegister(), Location::kOutputOverlap); + break; case DataType::Type::kInt64: { - // Type conversion from long to byte is a result of code transformations. HInstruction* input = conversion->InputAt(0); Location input_location = input->IsConstant() ? Location::ConstantLocation(input->AsConstant()) @@ -2438,17 +2450,6 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { locations->SetOut(Location::RequiresRegister(), Location::kOutputOverlap); break; } - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. - locations->SetInAt(0, Location::ByteRegisterOrConstant(ECX, conversion->InputAt(0))); - // Make the output overlap to please the register allocator. This greatly simplifies - // the validation of the linear scan implementation - locations->SetOut(Location::RequiresRegister(), Location::kOutputOverlap); - break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type @@ -2456,43 +2457,27 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { } break; + case DataType::Type::kUint16: case DataType::Type::kInt16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. - locations->SetInAt(0, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } + DCHECK(DataType::IsIntegralType(input_type)) << input_type; + locations->SetInAt(0, Location::Any()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); locations->AddTemp(Location::RequiresFpuRegister()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); locations->AddTemp(Location::RequiresFpuRegister()); @@ -2507,19 +2492,17 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. locations->SetInAt(0, Location::RegisterLocation(EAX)); locations->SetOut(Location::RegisterPairLocation(EAX, EDX)); break; case DataType::Type::kFloat32: case DataType::Type::kFloat64: { - // Processing a Dex `float-to-long' or 'double-to-long' instruction. InvokeRuntimeCallingConvention calling_convention; XmmRegister parameter = calling_convention.GetFpuRegisterAt(0); locations->SetInAt(0, Location::FpuRegisterLocation(parameter)); @@ -2535,47 +2518,24 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to char is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `int-to-char' instruction. - locations->SetInAt(0, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-float' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: - // Processing a Dex `long-to-float' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::Any()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -2589,24 +2549,21 @@ void LocationsBuilderX86::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-double' instruction. locations->SetInAt(0, Location::RequiresRegister()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: - // Processing a Dex `long-to-double' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::Any()); break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -2629,26 +2586,45 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio Location in = locations->InAt(0); DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; switch (result_type) { - case DataType::Type::kInt8: + case DataType::Type::kUint8: switch (input_type) { + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + if (in.IsRegister()) { + __ movzxb(out.AsRegister<Register>(), in.AsRegister<ByteRegister>()); + } else { + DCHECK(in.GetConstant()->IsIntConstant()); + int32_t value = in.GetConstant()->AsIntConstant()->GetValue(); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint8_t>(value))); + } + break; case DataType::Type::kInt64: - // Type conversion from long to byte is a result of code transformations. if (in.IsRegisterPair()) { - __ movsxb(out.AsRegister<Register>(), in.AsRegisterPairLow<ByteRegister>()); + __ movzxb(out.AsRegister<Register>(), in.AsRegisterPairLow<ByteRegister>()); } else { DCHECK(in.GetConstant()->IsLongConstant()); int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ movl(out.AsRegister<Register>(), Immediate(static_cast<int8_t>(value))); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint8_t>(value))); } break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt8: + switch (input_type) { + case DataType::Type::kUint8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. if (in.IsRegister()) { __ movsxb(out.AsRegister<Register>(), in.AsRegister<ByteRegister>()); } else { @@ -2657,6 +2633,15 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio __ movl(out.AsRegister<Register>(), Immediate(static_cast<int8_t>(value))); } break; + case DataType::Type::kInt64: + if (in.IsRegisterPair()) { + __ movsxb(out.AsRegister<Register>(), in.AsRegisterPairLow<ByteRegister>()); + } else { + DCHECK(in.GetConstant()->IsLongConstant()); + int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<int8_t>(value))); + } + break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type @@ -2664,26 +2649,43 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio } break; - case DataType::Type::kInt16: + case DataType::Type::kUint16: switch (input_type) { + case DataType::Type::kInt8: + case DataType::Type::kInt16: + case DataType::Type::kInt32: + if (in.IsRegister()) { + __ movzxw(out.AsRegister<Register>(), in.AsRegister<Register>()); + } else if (in.IsStackSlot()) { + __ movzxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); + } else { + DCHECK(in.GetConstant()->IsIntConstant()); + int32_t value = in.GetConstant()->AsIntConstant()->GetValue(); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint16_t>(value))); + } + break; case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. if (in.IsRegisterPair()) { - __ movsxw(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); + __ movzxw(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); } else if (in.IsDoubleStackSlot()) { - __ movsxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); + __ movzxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); } else { DCHECK(in.GetConstant()->IsLongConstant()); int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ movl(out.AsRegister<Register>(), Immediate(static_cast<int16_t>(value))); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint16_t>(value))); } break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt32: + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt16: + switch (input_type) { case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. + case DataType::Type::kInt32: if (in.IsRegister()) { __ movsxw(out.AsRegister<Register>(), in.AsRegister<Register>()); } else if (in.IsStackSlot()) { @@ -2694,6 +2696,17 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio __ movl(out.AsRegister<Register>(), Immediate(static_cast<int16_t>(value))); } break; + case DataType::Type::kInt64: + if (in.IsRegisterPair()) { + __ movsxw(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); + } else if (in.IsDoubleStackSlot()) { + __ movsxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); + } else { + DCHECK(in.GetConstant()->IsLongConstant()); + int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); + __ movl(out.AsRegister<Register>(), Immediate(static_cast<int16_t>(value))); + } + break; default: LOG(FATAL) << "Unexpected type conversion from " << input_type @@ -2704,7 +2717,6 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. if (in.IsRegisterPair()) { __ movl(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); } else if (in.IsDoubleStackSlot()) { @@ -2718,7 +2730,6 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio break; case DataType::Type::kFloat32: { - // Processing a Dex `float-to-int' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); Register output = out.AsRegister<Register>(); XmmRegister temp = locations->GetTemp(0).AsFpuRegister<XmmRegister>(); @@ -2743,7 +2754,6 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio } case DataType::Type::kFloat64: { - // Processing a Dex `double-to-int' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); Register output = out.AsRegister<Register>(); XmmRegister temp = locations->GetTemp(0).AsFpuRegister<XmmRegister>(); @@ -2776,12 +2786,11 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. DCHECK_EQ(out.AsRegisterPairLow<Register>(), EAX); DCHECK_EQ(out.AsRegisterPairHigh<Register>(), EDX); DCHECK_EQ(in.AsRegister<Register>(), EAX); @@ -2789,13 +2798,11 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-long' instruction. codegen_->InvokeRuntime(kQuickF2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickF2l, int64_t, float>(); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-long' instruction. codegen_->InvokeRuntime(kQuickD2l, conversion, conversion->GetDexPc()); CheckEntrypointTypes<kQuickD2l, int64_t, double>(); break; @@ -2806,57 +2813,18 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - if (in.IsRegisterPair()) { - __ movzxw(out.AsRegister<Register>(), in.AsRegisterPairLow<Register>()); - } else if (in.IsDoubleStackSlot()) { - __ movzxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); - } else { - DCHECK(in.GetConstant()->IsLongConstant()); - int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint16_t>(value))); - } - break; - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `Process a Dex `int-to-char'' instruction. - if (in.IsRegister()) { - __ movzxw(out.AsRegister<Register>(), in.AsRegister<Register>()); - } else if (in.IsStackSlot()) { - __ movzxw(out.AsRegister<Register>(), Address(ESP, in.GetStackIndex())); - } else { - DCHECK(in.GetConstant()->IsIntConstant()); - int32_t value = in.GetConstant()->AsIntConstant()->GetValue(); - __ movl(out.AsRegister<Register>(), Immediate(static_cast<uint16_t>(value))); - } - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-float' instruction. __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<Register>()); break; case DataType::Type::kInt64: { - // Processing a Dex `long-to-float' instruction. size_t adjustment = 0; // Create stack space for the call to @@ -2886,7 +2854,6 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio } case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. __ cvtsd2ss(out.AsFpuRegister<XmmRegister>(), in.AsFpuRegister<XmmRegister>()); break; @@ -2899,17 +2866,15 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-double' instruction. __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<Register>()); break; case DataType::Type::kInt64: { - // Processing a Dex `long-to-double' instruction. size_t adjustment = 0; // Create stack space for the call to @@ -2939,7 +2904,6 @@ void InstructionCodeGeneratorX86::VisitTypeConversion(HTypeConversion* conversio } case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. __ cvtss2sd(out.AsFpuRegister<XmmRegister>(), in.AsFpuRegister<XmmRegister>()); break; @@ -3832,6 +3796,7 @@ void LocationsBuilderX86::VisitDivZeroCheck(HDivZeroCheck* instruction) { LocationSummary* locations = codegen_->CreateThrowingSlowPathLocations(instruction); switch (instruction->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -3860,6 +3825,7 @@ void InstructionCodeGeneratorX86::VisitDivZeroCheck(HDivZeroCheck* instruction) switch (instruction->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -4349,9 +4315,10 @@ void LocationsBuilderX86::VisitCompare(HCompare* compare) { new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); @@ -4388,9 +4355,10 @@ void InstructionCodeGeneratorX86::VisitCompare(HCompare* compare) { switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { codegen_->GenerateIntCompare(left, right); break; @@ -4792,7 +4760,8 @@ void InstructionCodeGeneratorX86::HandleFieldGet(HInstruction* instruction, uint32_t offset = field_info.GetFieldOffset().Uint32Value(); switch (field_type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { __ movzxb(out.AsRegister<Register>(), Address(base, offset)); break; } @@ -4802,13 +4771,13 @@ void InstructionCodeGeneratorX86::HandleFieldGet(HInstruction* instruction, break; } - case DataType::Type::kInt16: { - __ movsxw(out.AsRegister<Register>(), Address(base, offset)); + case DataType::Type::kUint16: { + __ movzxw(out.AsRegister<Register>(), Address(base, offset)); break; } - case DataType::Type::kUint16: { - __ movzxw(out.AsRegister<Register>(), Address(base, offset)); + case DataType::Type::kInt16: { + __ movsxw(out.AsRegister<Register>(), Address(base, offset)); break; } @@ -4897,8 +4866,7 @@ void LocationsBuilderX86::HandleFieldSet(HInstruction* instruction, const FieldI locations->SetInAt(0, Location::RequiresRegister()); bool is_volatile = field_info.IsVolatile(); DataType::Type field_type = field_info.GetFieldType(); - bool is_byte_type = (field_type == DataType::Type::kBool) - || (field_type == DataType::Type::kInt8); + bool is_byte_type = DataType::Size(field_type) == 1u; // The register allocator does not support multiple // inputs that die at entry with one in a specific register. @@ -4957,13 +4925,14 @@ void InstructionCodeGeneratorX86::HandleFieldSet(HInstruction* instruction, switch (field_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { __ movb(Address(base, offset), value.AsRegister<ByteRegister>()); break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { if (value.IsConstant()) { __ movw(Address(base, offset), Immediate(CodeGenerator::GetInt16ValueOf(value.GetConstant()))); @@ -5242,7 +5211,8 @@ void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) { DataType::Type type = instruction->GetType(); switch (type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { Register out = out_loc.AsRegister<Register>(); __ movzxb(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_1, data_offset)); break; @@ -5254,12 +5224,6 @@ void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) { break; } - case DataType::Type::kInt16: { - Register out = out_loc.AsRegister<Register>(); - __ movsxw(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_2, data_offset)); - break; - } - case DataType::Type::kUint16: { Register out = out_loc.AsRegister<Register>(); if (mirror::kUseStringCompression && instruction->IsStringCharAt()) { @@ -5284,6 +5248,12 @@ void InstructionCodeGeneratorX86::VisitArrayGet(HArrayGet* instruction) { break; } + case DataType::Type::kInt16: { + Register out = out_loc.AsRegister<Register>(); + __ movsxw(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_2, data_offset)); + break; + } + case DataType::Type::kInt32: { Register out = out_loc.AsRegister<Register>(); __ movl(out, CodeGeneratorX86::ArrayAddress(obj, index, TIMES_4, data_offset)); @@ -5368,8 +5338,7 @@ void LocationsBuilderX86::VisitArraySet(HArraySet* instruction) { LocationSummary::kCallOnSlowPath : LocationSummary::kNoCall); - bool is_byte_type = (value_type == DataType::Type::kBool) - || (value_type == DataType::Type::kInt8); + bool is_byte_type = DataType::Size(value_type) == 1u; // We need the inputs to be different than the output in case of long operation. // In case of a byte operation, the register allocator does not support multiple // inputs that die at entry with one in a specific register. @@ -5407,6 +5376,7 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { uint32_t offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_1, offset); @@ -5419,8 +5389,8 @@ void InstructionCodeGeneratorX86::VisitArraySet(HArraySet* instruction) { break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { uint32_t offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); Address address = CodeGeneratorX86::ArrayAddress(array, index, TIMES_2, offset); if (value.IsRegister()) { diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 42704e9fe1..e8bfa66a58 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -1521,6 +1521,7 @@ void InstructionCodeGeneratorX86_64::GenerateCompareTest(HCondition* condition) DataType::Type type = condition->InputAt(0)->GetType(); switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -2036,9 +2037,10 @@ void LocationsBuilderX86_64::VisitCompare(HCompare* compare) { new (GetGraph()->GetArena()) LocationSummary(compare, LocationSummary::kNoCall); switch (compare->InputAt(0)->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: case DataType::Type::kInt64: { locations->SetInAt(0, Location::RequiresRegister()); @@ -2070,9 +2072,10 @@ void InstructionCodeGeneratorX86_64::VisitCompare(HCompare* compare) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { codegen_->GenerateIntCompare(left, right); break; @@ -2207,12 +2210,13 @@ void LocationsBuilderX86_64::VisitReturn(HReturn* ret) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(ret, LocationSummary::kNoCall); switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: case DataType::Type::kInt64: locations->SetInAt(0, Location::RegisterLocation(RAX)); break; @@ -2230,12 +2234,13 @@ void LocationsBuilderX86_64::VisitReturn(HReturn* ret) { void InstructionCodeGeneratorX86_64::VisitReturn(HReturn* ret) { if (kIsDebugBuild) { switch (ret->InputAt(0)->GetType()) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: case DataType::Type::kInt64: DCHECK_EQ(ret->GetLocations()->InAt(0).AsRegister<CpuRegister>().AsRegister(), RAX); break; @@ -2255,12 +2260,13 @@ void InstructionCodeGeneratorX86_64::VisitReturn(HReturn* ret) { Location InvokeDexCallingConventionVisitorX86_64::GetReturnLocation(DataType::Type type) const { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kReference: case DataType::Type::kInt64: return Location::RegisterLocation(RAX); @@ -2281,12 +2287,13 @@ Location InvokeDexCallingConventionVisitorX86_64::GetMethodLocation() const { Location InvokeDexCallingConventionVisitorX86_64::GetNextLocation(DataType::Type type) { switch (type) { + case DataType::Type::kReference: case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kReference: { + case DataType::Type::kInt32: { uint32_t index = gp_index_++; stack_index_++; if (index < calling_convention.GetNumberOfRegisters()) { @@ -2536,68 +2543,32 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { new (GetGraph()->GetArena()) LocationSummary(conversion, LocationSummary::kNoCall); DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); - - // The Java language does not allow treating boolean as an integral type but - // our bit representation makes it safe. + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; switch (result_type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to byte is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt16: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. - locations->SetInAt(0, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - + case DataType::Type::kUint16: case DataType::Type::kInt16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. - locations->SetInAt(0, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } + DCHECK(DataType::IsIntegralType(input_type)) << input_type; + locations->SetInAt(0, Location::Any()); + locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-int' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); break; @@ -2611,12 +2582,11 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. // TODO: We would benefit from a (to-be-implemented) // Location::RegisterOrStackSlot requirement for this input. locations->SetInAt(0, Location::RequiresRegister()); @@ -2624,13 +2594,11 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-long' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-long' instruction. locations->SetInAt(0, Location::RequiresFpuRegister()); locations->SetOut(Location::RequiresRegister()); break; @@ -2641,47 +2609,24 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to char is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `int-to-char' instruction. - locations->SetInAt(0, Location::Any()); - locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-float' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: - // Processing a Dex `long-to-float' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -2695,24 +2640,21 @@ void LocationsBuilderX86_64::VisitTypeConversion(HTypeConversion* conversion) { case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-double' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kInt64: - // Processing a Dex `long-to-double' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister()); break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. locations->SetInAt(0, Location::Any()); locations->SetOut(Location::RequiresFpuRegister(), Location::kNoOutputOverlap); break; @@ -2735,18 +2677,40 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver Location in = locations->InAt(0); DataType::Type result_type = conversion->GetResultType(); DataType::Type input_type = conversion->GetInputType(); - DCHECK_NE(result_type, input_type); + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " -> " << result_type; switch (result_type) { - case DataType::Type::kInt8: + case DataType::Type::kUint8: switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to byte is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: + case DataType::Type::kInt64: + if (in.IsRegister()) { + __ movzxb(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); + } else if (in.IsStackSlot() || in.IsDoubleStackSlot()) { + __ movzxb(out.AsRegister<CpuRegister>(), + Address(CpuRegister(RSP), in.GetStackIndex())); + } else { + __ movl(out.AsRegister<CpuRegister>(), + Immediate(static_cast<uint8_t>(Int64FromConstant(in.GetConstant())))); + } + break; + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt8: + switch (input_type) { + case DataType::Type::kUint8: case DataType::Type::kUint16: - // Processing a Dex `int-to-byte' instruction. + case DataType::Type::kInt16: + case DataType::Type::kInt32: + case DataType::Type::kInt64: if (in.IsRegister()) { __ movsxb(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsStackSlot() || in.IsDoubleStackSlot()) { @@ -2764,16 +2728,34 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver } break; - case DataType::Type::kInt16: + case DataType::Type::kUint16: switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to short is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. case DataType::Type::kInt8: + case DataType::Type::kInt16: case DataType::Type::kInt32: + case DataType::Type::kInt64: + if (in.IsRegister()) { + __ movzxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); + } else if (in.IsStackSlot() || in.IsDoubleStackSlot()) { + __ movzxw(out.AsRegister<CpuRegister>(), + Address(CpuRegister(RSP), in.GetStackIndex())); + } else { + __ movl(out.AsRegister<CpuRegister>(), + Immediate(static_cast<uint16_t>(Int64FromConstant(in.GetConstant())))); + } + break; + + default: + LOG(FATAL) << "Unexpected type conversion from " << input_type + << " to " << result_type; + } + break; + + case DataType::Type::kInt16: + switch (input_type) { case DataType::Type::kUint16: - // Processing a Dex `int-to-short' instruction. + case DataType::Type::kInt32: + case DataType::Type::kInt64: if (in.IsRegister()) { __ movsxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsStackSlot() || in.IsDoubleStackSlot()) { @@ -2794,7 +2776,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case DataType::Type::kInt32: switch (input_type) { case DataType::Type::kInt64: - // Processing a Dex `long-to-int' instruction. if (in.IsRegister()) { __ movl(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); } else if (in.IsDoubleStackSlot()) { @@ -2809,7 +2790,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver break; case DataType::Type::kFloat32: { - // Processing a Dex `float-to-int' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); CpuRegister output = out.AsRegister<CpuRegister>(); NearLabel done, nan; @@ -2831,7 +2811,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver } case DataType::Type::kFloat64: { - // Processing a Dex `double-to-int' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); CpuRegister output = out.AsRegister<CpuRegister>(); NearLabel done, nan; @@ -2862,18 +2841,16 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver switch (input_type) { DCHECK(out.IsRegister()); case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-long' instruction. DCHECK(in.IsRegister()); __ movsxd(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); break; case DataType::Type::kFloat32: { - // Processing a Dex `float-to-long' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); CpuRegister output = out.AsRegister<CpuRegister>(); NearLabel done, nan; @@ -2895,7 +2872,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver } case DataType::Type::kFloat64: { - // Processing a Dex `double-to-long' instruction. XmmRegister input = in.AsFpuRegister<XmmRegister>(); CpuRegister output = out.AsRegister<CpuRegister>(); NearLabel done, nan; @@ -2922,42 +2898,14 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver } break; - case DataType::Type::kUint16: - switch (input_type) { - case DataType::Type::kInt64: - // Type conversion from long to char is a result of code transformations. - case DataType::Type::kBool: - // Boolean input is a result of code transformations. - case DataType::Type::kInt8: - case DataType::Type::kInt16: - case DataType::Type::kInt32: - // Processing a Dex `int-to-char' instruction. - if (in.IsRegister()) { - __ movzxw(out.AsRegister<CpuRegister>(), in.AsRegister<CpuRegister>()); - } else if (in.IsStackSlot() || in.IsDoubleStackSlot()) { - __ movzxw(out.AsRegister<CpuRegister>(), - Address(CpuRegister(RSP), in.GetStackIndex())); - } else { - __ movl(out.AsRegister<CpuRegister>(), - Immediate(static_cast<uint16_t>(Int64FromConstant(in.GetConstant())))); - } - break; - - default: - LOG(FATAL) << "Unexpected type conversion from " << input_type - << " to " << result_type; - } - break; - case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-float' instruction. if (in.IsRegister()) { __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), false); } else if (in.IsConstant()) { @@ -2971,7 +2919,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver break; case DataType::Type::kInt64: - // Processing a Dex `long-to-float' instruction. if (in.IsRegister()) { __ cvtsi2ss(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), true); } else if (in.IsConstant()) { @@ -2985,7 +2932,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver break; case DataType::Type::kFloat64: - // Processing a Dex `double-to-float' instruction. if (in.IsFpuRegister()) { __ cvtsd2ss(out.AsFpuRegister<XmmRegister>(), in.AsFpuRegister<XmmRegister>()); } else if (in.IsConstant()) { @@ -3007,12 +2953,11 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: - // Boolean input is a result of code transformations. + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: case DataType::Type::kInt16: case DataType::Type::kInt32: - case DataType::Type::kUint16: - // Processing a Dex `int-to-double' instruction. if (in.IsRegister()) { __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), false); } else if (in.IsConstant()) { @@ -3026,7 +2971,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver break; case DataType::Type::kInt64: - // Processing a Dex `long-to-double' instruction. if (in.IsRegister()) { __ cvtsi2sd(out.AsFpuRegister<XmmRegister>(), in.AsRegister<CpuRegister>(), true); } else if (in.IsConstant()) { @@ -3040,7 +2984,6 @@ void InstructionCodeGeneratorX86_64::VisitTypeConversion(HTypeConversion* conver break; case DataType::Type::kFloat32: - // Processing a Dex `float-to-double' instruction. if (in.IsFpuRegister()) { __ cvtss2sd(out.AsFpuRegister<XmmRegister>(), in.AsFpuRegister<XmmRegister>()); } else if (in.IsConstant()) { @@ -3883,6 +3826,7 @@ void InstructionCodeGeneratorX86_64::VisitDivZeroCheck(HDivZeroCheck* instructio switch (instruction->GetType()) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -4290,7 +4234,8 @@ void InstructionCodeGeneratorX86_64::HandleFieldGet(HInstruction* instruction, uint32_t offset = field_info.GetFieldOffset().Uint32Value(); switch (field_type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { __ movzxb(out.AsRegister<CpuRegister>(), Address(base, offset)); break; } @@ -4300,13 +4245,13 @@ void InstructionCodeGeneratorX86_64::HandleFieldGet(HInstruction* instruction, break; } - case DataType::Type::kInt16: { - __ movsxw(out.AsRegister<CpuRegister>(), Address(base, offset)); + case DataType::Type::kUint16: { + __ movzxw(out.AsRegister<CpuRegister>(), Address(base, offset)); break; } - case DataType::Type::kUint16: { - __ movzxw(out.AsRegister<CpuRegister>(), Address(base, offset)); + case DataType::Type::kInt16: { + __ movsxw(out.AsRegister<CpuRegister>(), Address(base, offset)); break; } @@ -4433,6 +4378,7 @@ void InstructionCodeGeneratorX86_64::HandleFieldSet(HInstruction* instruction, switch (field_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { if (value.IsConstant()) { __ movb(Address(base, offset), @@ -4443,8 +4389,8 @@ void InstructionCodeGeneratorX86_64::HandleFieldSet(HInstruction* instruction, break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { if (value.IsConstant()) { __ movw(Address(base, offset), Immediate(CodeGenerator::GetInt16ValueOf(value.GetConstant()))); @@ -4714,7 +4660,8 @@ void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) { DataType::Type type = instruction->GetType(); switch (type) { - case DataType::Type::kBool: { + case DataType::Type::kBool: + case DataType::Type::kUint8: { CpuRegister out = out_loc.AsRegister<CpuRegister>(); __ movzxb(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_1, data_offset)); break; @@ -4726,12 +4673,6 @@ void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) { break; } - case DataType::Type::kInt16: { - CpuRegister out = out_loc.AsRegister<CpuRegister>(); - __ movsxw(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_2, data_offset)); - break; - } - case DataType::Type::kUint16: { CpuRegister out = out_loc.AsRegister<CpuRegister>(); if (mirror::kUseStringCompression && instruction->IsStringCharAt()) { @@ -4754,6 +4695,12 @@ void InstructionCodeGeneratorX86_64::VisitArrayGet(HArrayGet* instruction) { break; } + case DataType::Type::kInt16: { + CpuRegister out = out_loc.AsRegister<CpuRegister>(); + __ movsxw(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_2, data_offset)); + break; + } + case DataType::Type::kInt32: { CpuRegister out = out_loc.AsRegister<CpuRegister>(); __ movl(out, CodeGeneratorX86_64::ArrayAddress(obj, index, TIMES_4, data_offset)); @@ -4865,6 +4812,7 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: { uint32_t offset = mirror::Array::DataOffset(sizeof(uint8_t)).Uint32Value(); Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_1, offset); @@ -4877,8 +4825,8 @@ void InstructionCodeGeneratorX86_64::VisitArraySet(HArraySet* instruction) { break; } - case DataType::Type::kInt16: - case DataType::Type::kUint16: { + case DataType::Type::kUint16: + case DataType::Type::kInt16: { uint32_t offset = mirror::Array::DataOffset(sizeof(uint16_t)).Uint32Value(); Address address = CodeGeneratorX86_64::ArrayAddress(array, index, TIMES_2, offset); if (value.IsRegister()) { diff --git a/compiler/optimizing/data_type-inl.h b/compiler/optimizing/data_type-inl.h index fbc0c1215d..e389bad3ad 100644 --- a/compiler/optimizing/data_type-inl.h +++ b/compiler/optimizing/data_type-inl.h @@ -46,17 +46,19 @@ constexpr DataType::Type DataType::FromShorty(char type) { constexpr char DataType::TypeId(DataType::Type type) { // Type id for visualizer. + // Types corresponding to Java types are given a lower-case version of their shorty character. switch (type) { - case DataType::Type::kBool: return 'z'; - case DataType::Type::kInt8: return 'b'; - case DataType::Type::kUint16: return 'c'; - case DataType::Type::kInt16: return 's'; - case DataType::Type::kInt32: return 'i'; - case DataType::Type::kInt64: return 'j'; - case DataType::Type::kFloat32: return 'f'; - case DataType::Type::kFloat64: return 'd'; - case DataType::Type::kReference: return 'l'; - case DataType::Type::kVoid: return 'v'; + case DataType::Type::kBool: return 'z'; // Java boolean (Z). + case DataType::Type::kUint8: return 'a'; // The character before Java byte's 'b'. + case DataType::Type::kInt8: return 'b'; // Java byte (B). + case DataType::Type::kUint16: return 'c'; // Java char (C). + case DataType::Type::kInt16: return 's'; // Java short (S). + case DataType::Type::kInt32: return 'i'; // Java int (I). + case DataType::Type::kInt64: return 'j'; // Java long (J). + case DataType::Type::kFloat32: return 'f'; // Java float (F). + case DataType::Type::kFloat64: return 'd'; // Java double (D). + case DataType::Type::kReference: return 'l'; // Java reference (L). + case DataType::Type::kVoid: return 'v'; // Java void (V). } LOG(FATAL) << "Unreachable"; UNREACHABLE(); diff --git a/compiler/optimizing/data_type.cc b/compiler/optimizing/data_type.cc index 689061722e..3c99a76c17 100644 --- a/compiler/optimizing/data_type.cc +++ b/compiler/optimizing/data_type.cc @@ -21,6 +21,7 @@ namespace art { static const char* kTypeNames[] = { "Reference", "Bool", + "Uint8", "Int8", "Uint16", "Int16", diff --git a/compiler/optimizing/data_type.h b/compiler/optimizing/data_type.h index 08f9263127..5a023ad69b 100644 --- a/compiler/optimizing/data_type.h +++ b/compiler/optimizing/data_type.h @@ -29,6 +29,7 @@ class DataType { enum class Type : uint8_t { kReference = 0, kBool, + kUint8, kInt8, kUint16, kInt16, @@ -47,6 +48,7 @@ class DataType { switch (type) { case Type::kVoid: case Type::kBool: + case Type::kUint8: case Type::kInt8: return 0; case Type::kUint16: @@ -71,6 +73,7 @@ class DataType { case Type::kVoid: return 0; case Type::kBool: + case Type::kUint8: case Type::kInt8: return 1; case Type::kUint16: @@ -99,6 +102,7 @@ class DataType { // our bit representation makes it safe. switch (type) { case Type::kBool: + case Type::kUint8: case Type::kInt8: case Type::kUint16: case Type::kInt16: @@ -118,10 +122,27 @@ class DataType { return type == Type::kInt64 || type == Type::kFloat64; } + static bool IsUnsignedType(Type type) { + return type == Type::kUint8 || type == Type::kUint16; + } + + static Type ToSignedType(Type type) { + switch (type) { + case Type::kUint8: + return Type::kInt8; + case Type::kUint16: + return Type::kInt16; + default: + DCHECK(type != Type::kVoid && type != Type::kReference); + return type; + } + } + // Return the general kind of `type`, fusing integer-like types as Type::kInt. static Type Kind(Type type) { switch (type) { case Type::kBool: + case Type::kUint8: case Type::kInt8: case Type::kInt16: case Type::kUint16: @@ -136,6 +157,8 @@ class DataType { switch (type) { case Type::kBool: return std::numeric_limits<bool>::min(); + case Type::kUint8: + return std::numeric_limits<uint8_t>::min(); case Type::kInt8: return std::numeric_limits<int8_t>::min(); case Type::kUint16: @@ -156,6 +179,8 @@ class DataType { switch (type) { case Type::kBool: return std::numeric_limits<bool>::max(); + case Type::kUint8: + return std::numeric_limits<uint8_t>::max(); case Type::kInt8: return std::numeric_limits<int8_t>::max(); case Type::kUint16: @@ -172,6 +197,8 @@ class DataType { return 0; } + static bool IsTypeConversionImplicit(Type input_type, Type result_type); + static const char* PrettyDescriptor(Type type); private: @@ -179,6 +206,25 @@ class DataType { }; std::ostream& operator<<(std::ostream& os, DataType::Type data_type); +// Defined outside DataType to have the operator<< available for DCHECK_NE(). +inline bool DataType::IsTypeConversionImplicit(Type input_type, Type result_type) { + DCHECK_NE(DataType::Type::kVoid, result_type); + DCHECK_NE(DataType::Type::kVoid, input_type); + + // Invariant: We should never generate a conversion to a Boolean value. + DCHECK_NE(DataType::Type::kBool, result_type); + + // Besides conversion to the same type, integral conversions to non-Int64 types + // are implicit if the result value range covers the input value range, i.e. + // widening conversions that do not need to trim the sign bits. + return result_type == input_type || + (result_type != Type::kInt64 && + IsIntegralType(input_type) && + IsIntegralType(result_type) && + MinValueOfIntegralType(input_type) >= MinValueOfIntegralType(result_type) && + MaxValueOfIntegralType(input_type) <= MaxValueOfIntegralType(result_type)); +} + } // namespace art #endif // ART_COMPILER_OPTIMIZING_DATA_TYPE_H_ diff --git a/compiler/optimizing/data_type_test.cc b/compiler/optimizing/data_type_test.cc index 927291a54a..3ce683ac4d 100644 --- a/compiler/optimizing/data_type_test.cc +++ b/compiler/optimizing/data_type_test.cc @@ -18,6 +18,8 @@ #include "data_type-inl.h" +#include "base/array_ref.h" +#include "base/macros.h" #include "primitive.h" namespace art { @@ -57,4 +59,58 @@ TEST(DataType, Names) { #undef CHECK_NAME } +TEST(DataType, IsTypeConversionImplicit) { + static const DataType::Type kIntegralTypes[] = { + DataType::Type::kBool, + DataType::Type::kUint8, + DataType::Type::kInt8, + DataType::Type::kUint16, + DataType::Type::kInt16, + DataType::Type::kInt32, + DataType::Type::kInt64, + }; + const ArrayRef<const DataType::Type> kIntegralInputTypes(kIntegralTypes); + // Note: kBool cannot be used as a result type. + DCHECK_EQ(kIntegralTypes[0], DataType::Type::kBool); + const ArrayRef<const DataType::Type> kIntegralResultTypes = kIntegralInputTypes.SubArray(1u); + + static const bool kImplicitIntegralConversions[][arraysize(kIntegralTypes)] = { + // Bool Uint8 Int8 Uint16 Int16 Int32 Int64 + { /* Bool N/A */ true, true, true, true, true, false }, + { /* Uint8 N/A */ true, false, true, true, true, false }, + { /* Int8 N/A */ false, true, false, true, true, false }, + { /* Uint16 N/A */ false, false, true, false, true, false }, + { /* Int16 N/A */ false, false, false, true, true, false }, + { /* Int32 N/A */ false, false, false, false, true, false }, + { /* Int64 N/A */ false, false, false, false, false, true }, + }; + static_assert(arraysize(kIntegralTypes) == arraysize(kImplicitIntegralConversions), "size check"); + + for (size_t input_index = 0; input_index != kIntegralInputTypes.size(); ++input_index) { + DataType::Type input_type = kIntegralInputTypes[input_index]; + for (size_t result_index = 1u; result_index != kIntegralResultTypes.size(); ++result_index) { + DataType::Type result_type = kIntegralResultTypes[result_index]; + EXPECT_EQ(kImplicitIntegralConversions[input_index][result_index], + DataType::IsTypeConversionImplicit(input_type, result_type)) + << input_type << " " << result_type; + } + } + for (DataType::Type input_type : kIntegralInputTypes) { + EXPECT_FALSE(DataType::IsTypeConversionImplicit(input_type, DataType::Type::kFloat32)); + EXPECT_FALSE(DataType::IsTypeConversionImplicit(input_type, DataType::Type::kFloat64)); + } + for (DataType::Type result_type : kIntegralResultTypes) { + EXPECT_FALSE(DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, result_type)); + EXPECT_FALSE(DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, result_type)); + } + EXPECT_TRUE( + DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, DataType::Type::kFloat32)); + EXPECT_FALSE( + DataType::IsTypeConversionImplicit(DataType::Type::kFloat32, DataType::Type::kFloat64)); + EXPECT_FALSE( + DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, DataType::Type::kFloat32)); + EXPECT_TRUE( + DataType::IsTypeConversionImplicit(DataType::Type::kFloat64, DataType::Type::kFloat64)); +} + } // namespace art diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 194f063d48..eccdccf186 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -521,20 +521,28 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { StartAttributeStream("kind") << deoptimize->GetKind(); } + void VisitVecOperation(HVecOperation* vec_operation) OVERRIDE { + StartAttributeStream("packed_type") << vec_operation->GetPackedType(); + } + void VisitVecHalvingAdd(HVecHalvingAdd* hadd) OVERRIDE { + VisitVecBinaryOperation(hadd); StartAttributeStream("unsigned") << std::boolalpha << hadd->IsUnsigned() << std::noboolalpha; StartAttributeStream("rounded") << std::boolalpha << hadd->IsRounded() << std::noboolalpha; } void VisitVecMin(HVecMin* min) OVERRIDE { + VisitVecBinaryOperation(min); StartAttributeStream("unsigned") << std::boolalpha << min->IsUnsigned() << std::noboolalpha; } void VisitVecMax(HVecMax* max) OVERRIDE { + VisitVecBinaryOperation(max); StartAttributeStream("unsigned") << std::boolalpha << max->IsUnsigned() << std::noboolalpha; } void VisitVecMultiplyAccumulate(HVecMultiplyAccumulate* instruction) OVERRIDE { + VisitVecOperation(instruction); StartAttributeStream("kind") << instruction->GetOpKind(); } diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index fe286ab88a..eab17aad31 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -59,14 +59,19 @@ static void RotateEntryPhiFirst(HLoopInformation* loop, static bool IsNarrowingIntegralConversion(DataType::Type from, DataType::Type to) { switch (from) { case DataType::Type::kInt64: - return to == DataType::Type::kInt8 || to == DataType::Type::kInt16 - || to == DataType::Type::kUint16 || to == DataType::Type::kInt32; + return to == DataType::Type::kUint8 || + to == DataType::Type::kInt8 || + to == DataType::Type::kUint16 || + to == DataType::Type::kInt16 || + to == DataType::Type::kInt32; case DataType::Type::kInt32: - return to == DataType::Type::kInt8 || to == DataType::Type::kInt16 - || to == DataType::Type::kUint16; + return to == DataType::Type::kUint8 || + to == DataType::Type::kInt8 || + to == DataType::Type::kUint16 || + to == DataType::Type::kInt16; case DataType::Type::kUint16: case DataType::Type::kInt16: - return to == DataType::Type::kInt8; + return to == DataType::Type::kUint8 || to == DataType::Type::kInt8; default: return false; } @@ -77,10 +82,11 @@ static bool IsNarrowingIntegralConversion(DataType::Type from, DataType::Type to */ static DataType::Type ImplicitConversion(DataType::Type type) { switch (type) { - case DataType::Type::kInt16: - case DataType::Type::kUint16: - case DataType::Type::kInt8: case DataType::Type::kBool: + case DataType::Type::kUint8: + case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: return DataType::Type::kInt32; default: return type; @@ -1142,9 +1148,10 @@ bool HInductionVarAnalysis::IsAtLeast(InductionInfo* info, int64_t* value) { bool HInductionVarAnalysis::IsNarrowingLinear(InductionInfo* info) { return info != nullptr && info->induction_class == kLinear && - (info->type == DataType::Type::kInt8 || - info->type == DataType::Type::kInt16 || + (info->type == DataType::Type::kUint8 || + info->type == DataType::Type::kInt8 || info->type == DataType::Type::kUint16 || + info->type == DataType::Type::kInt16 || (info->type == DataType::Type::kInt32 && (info->op_a->type == DataType::Type::kInt64 || info->op_b->type == DataType::Type::kInt64))); } diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index 92b584cc3b..ab6fbae248 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -159,9 +159,10 @@ static bool IsConstantValue(InductionVarRange::Value v) { /** Corrects a value for type to account for arithmetic wrap-around in lower precision. */ static InductionVarRange::Value CorrectForType(InductionVarRange::Value v, DataType::Type type) { switch (type) { - case DataType::Type::kInt16: + case DataType::Type::kUint8: + case DataType::Type::kInt8: case DataType::Type::kUint16: - case DataType::Type::kInt8: { + case DataType::Type::kInt16: { // Constants within range only. // TODO: maybe some room for improvement, like allowing widening conversions int32_t min = DataType::MinValueOfIntegralType(type); @@ -216,10 +217,11 @@ bool InductionVarRange::GetInductionRange(HInstruction* context, // bounds check elimination, will have truncated higher precision induction // at their use point already). switch (info->type) { - case DataType::Type::kInt32: - case DataType::Type::kInt16: - case DataType::Type::kUint16: + case DataType::Type::kUint8: case DataType::Type::kInt8: + case DataType::Type::kUint16: + case DataType::Type::kInt16: + case DataType::Type::kInt32: break; default: return false; diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index cf1cbd578c..f739d7b4f6 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -251,7 +251,8 @@ bool InstructionSimplifierVisitor::TryCombineVecMultiplyAccumulate(HVecMul* mul) InstructionSet isa = codegen_->GetInstructionSet(); switch (isa) { case kArm64: - if (!(type == DataType::Type::kInt8 || + if (!(type == DataType::Type::kUint8 || + type == DataType::Type::kInt8 || type == DataType::Type::kUint16 || type == DataType::Type::kInt16 || type == DataType::Type::kInt32)) { @@ -260,7 +261,8 @@ bool InstructionSimplifierVisitor::TryCombineVecMultiplyAccumulate(HVecMul* mul) break; case kMips: case kMips64: - if (!(type == DataType::Type::kInt8 || + if (!(type == DataType::Type::kUint8 || + type == DataType::Type::kInt8 || type == DataType::Type::kUint16 || type == DataType::Type::kInt16 || type == DataType::Type::kInt32 || @@ -876,10 +878,11 @@ static bool AreLowerPrecisionArgs(DataType::Type to_type, HInstruction* a, HInst } DataType::Type type1 = a->GetType(); DataType::Type type2 = b->GetType(); - return (type1 == DataType::Type::kInt8 && type2 == DataType::Type::kInt8) || - (type1 == DataType::Type::kInt16 && type2 == DataType::Type::kInt16) || - (type1 == DataType::Type::kUint16 && type2 == DataType::Type::kUint16) || - (type1 == DataType::Type::kInt32 && type2 == DataType::Type::kInt32 && + return (type1 == DataType::Type::kUint8 && type2 == DataType::Type::kUint8) || + (type1 == DataType::Type::kInt8 && type2 == DataType::Type::kInt8) || + (type1 == DataType::Type::kInt16 && type2 == DataType::Type::kInt16) || + (type1 == DataType::Type::kUint16 && type2 == DataType::Type::kUint16) || + (type1 == DataType::Type::kInt32 && type2 == DataType::Type::kInt32 && to_type == DataType::Type::kInt64); } @@ -1036,30 +1039,13 @@ void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) { } } -static bool IsTypeConversionImplicit(DataType::Type input_type, DataType::Type result_type) { - // Invariant: We should never generate a conversion to a Boolean value. - DCHECK_NE(DataType::Type::kBool, result_type); - - // Besides conversion to the same type, widening integral conversions are implicit, - // excluding conversions to long and the byte->char conversion where we need to - // clear the high 16 bits of the 32-bit sign-extended representation of byte. - return result_type == input_type || - (result_type == DataType::Type::kInt32 && (input_type == DataType::Type::kBool || - input_type == DataType::Type::kInt8 || - input_type == DataType::Type::kInt16 || - input_type == DataType::Type::kUint16)) || - (result_type == DataType::Type::kUint16 && input_type == DataType::Type::kBool) || - (result_type == DataType::Type::kInt16 && (input_type == DataType::Type::kBool || - input_type == DataType::Type::kInt8)) || - (result_type == DataType::Type::kInt8 && input_type == DataType::Type::kBool); -} - static bool IsTypeConversionLossless(DataType::Type input_type, DataType::Type result_type) { // The conversion to a larger type is loss-less with the exception of two cases, - // - conversion to Uint16, the only unsigned type, where we may lose some bits, and + // - conversion to the unsigned type Uint16, where we may lose some bits, and // - conversion from float to long, the only FP to integral conversion with smaller FP type. // For integral to FP conversions this holds because the FP mantissa is large enough. - DCHECK_NE(input_type, result_type); + // Note: The size check excludes Uint8 as the result type. + DCHECK(!DataType::IsTypeConversionImplicit(input_type, result_type)); return DataType::Size(result_type) > DataType::Size(input_type) && result_type != DataType::Type::kUint16 && !(result_type == DataType::Type::kInt64 && input_type == DataType::Type::kFloat32); @@ -1069,7 +1055,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct HInstruction* input = instruction->GetInput(); DataType::Type input_type = input->GetType(); DataType::Type result_type = instruction->GetResultType(); - if (IsTypeConversionImplicit(input_type, result_type)) { + if (DataType::IsTypeConversionImplicit(input_type, result_type)) { // Remove the implicit conversion; this includes conversion to the same type. instruction->ReplaceWith(input); instruction->GetBlock()->RemoveInstruction(instruction); @@ -1098,7 +1084,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct if (is_first_conversion_lossless || integral_conversions_with_non_widening_second) { // If the merged conversion is implicit, do the simplification unconditionally. - if (IsTypeConversionImplicit(original_type, result_type)) { + if (DataType::IsTypeConversionImplicit(original_type, result_type)) { instruction->ReplaceWith(original_input); instruction->GetBlock()->RemoveInstruction(instruction); if (!input_conversion->HasUses()) { @@ -1127,7 +1113,7 @@ void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruct if (trailing_ones >= kBitsPerByte * DataType::Size(result_type)) { // The `HAnd` is useless, for example in `(byte) (x & 0xff)`, get rid of it. HInstruction* original_input = input_and->GetLeastConstantLeft(); - if (IsTypeConversionImplicit(original_input->GetType(), result_type)) { + if (DataType::IsTypeConversionImplicit(original_input->GetType(), result_type)) { instruction->ReplaceWith(original_input); instruction->GetBlock()->RemoveInstruction(instruction); RecordSimplification(); @@ -2167,8 +2153,12 @@ void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) { HBoundsCheck* bounds_check = new (arena) HBoundsCheck( index, length, dex_pc, invoke->GetDexMethodIndex()); invoke->GetBlock()->InsertInstructionBefore(bounds_check, invoke); - HArrayGet* array_get = new (arena) HArrayGet( - str, bounds_check, DataType::Type::kUint16, dex_pc, /* is_string_char_at */ true); + HArrayGet* array_get = new (arena) HArrayGet(str, + bounds_check, + DataType::Type::kUint16, + SideEffects::None(), // Strings are immutable. + dex_pc, + /* is_string_char_at */ true); invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, array_get); bounds_check->CopyEnvironmentFrom(invoke->GetEnvironment()); GetGraph()->SetHasBoundsChecks(true); diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index bd14f2b142..54c2d43e9c 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -276,6 +276,7 @@ class LSEVisitor : public HGraphVisitor { case DataType::Type::kReference: return GetGraph()->GetNullConstant(); case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index fec64e2adf..2090a12929 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -28,6 +28,46 @@ namespace art { +// TODO: Clean up the packed type detection so that we have the right type straight away +// and do not need to go through this normalization. +static inline void NormalizePackedType(/* inout */ DataType::Type* type, + /* inout */ bool* is_unsigned) { + switch (*type) { + case DataType::Type::kBool: + DCHECK(!*is_unsigned); + break; + case DataType::Type::kUint8: + case DataType::Type::kInt8: + if (*is_unsigned) { + *is_unsigned = false; + *type = DataType::Type::kUint8; + } else { + *type = DataType::Type::kInt8; + } + break; + case DataType::Type::kUint16: + case DataType::Type::kInt16: + if (*is_unsigned) { + *is_unsigned = false; + *type = DataType::Type::kUint16; + } else { + *type = DataType::Type::kInt16; + } + break; + case DataType::Type::kInt32: + case DataType::Type::kInt64: + // We do not have kUint32 and kUint64 at the moment. + break; + case DataType::Type::kFloat32: + case DataType::Type::kFloat64: + DCHECK(!*is_unsigned); + break; + default: + LOG(FATAL) << "Unexpected type " << *type; + UNREACHABLE(); + } +} + // Enables vectorization (SIMDization) in the loop optimizer. static constexpr bool kEnableVectorization = true; @@ -87,6 +127,7 @@ static bool IsSignExtensionAndGet(HInstruction* instruction, int64_t value = 0; if (IsInt64AndGet(instruction, /*out*/ &value)) { switch (type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: if (IsInt<8>(value)) { *operand = instruction; @@ -151,6 +192,7 @@ static bool IsZeroExtensionAndGet(HInstruction* instruction, int64_t value = 0; if (IsInt64AndGet(instruction, /*out*/ &value)) { switch (type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: if (IsUint<8>(value)) { *operand = instruction; @@ -170,9 +212,13 @@ static bool IsZeroExtensionAndGet(HInstruction* instruction, } // An implicit widening conversion of any unsigned expression zero-extends. if (instruction->GetType() == type) { - if (type == DataType::Type::kUint16) { - *operand = instruction; - return true; + switch (type) { + case DataType::Type::kUint8: + case DataType::Type::kUint16: + *operand = instruction; + return true; + default: + return false; } } // A sign (or zero) extension followed by an explicit removal of just the @@ -190,6 +236,7 @@ static bool IsZeroExtensionAndGet(HInstruction* instruction, (IsInt64AndGet(b, /*out*/ &mask) && (IsSignExtensionAndGet(a, type, /*out*/ operand) || IsZeroExtensionAndGet(a, type, /*out*/ operand)))) { switch ((*operand)->GetType()) { + case DataType::Type::kUint8: case DataType::Type::kInt8: return mask == std::numeric_limits<uint8_t>::max(); case DataType::Type::kUint16: @@ -257,51 +304,10 @@ static bool IsNarrowerOperand(HInstruction* a, // Compute relative vector length based on type difference. static size_t GetOtherVL(DataType::Type other_type, DataType::Type vector_type, size_t vl) { - switch (other_type) { - case DataType::Type::kBool: - case DataType::Type::kInt8: - switch (vector_type) { - case DataType::Type::kBool: - case DataType::Type::kInt8: return vl; - default: break; - } - return vl; - case DataType::Type::kUint16: - case DataType::Type::kInt16: - switch (vector_type) { - case DataType::Type::kBool: - case DataType::Type::kInt8: return vl >> 1; - case DataType::Type::kUint16: - case DataType::Type::kInt16: return vl; - default: break; - } - break; - case DataType::Type::kInt32: - switch (vector_type) { - case DataType::Type::kBool: - case DataType::Type::kInt8: return vl >> 2; - case DataType::Type::kUint16: - case DataType::Type::kInt16: return vl >> 1; - case DataType::Type::kInt32: return vl; - default: break; - } - break; - case DataType::Type::kInt64: - switch (vector_type) { - case DataType::Type::kBool: - case DataType::Type::kInt8: return vl >> 3; - case DataType::Type::kUint16: - case DataType::Type::kInt16: return vl >> 2; - case DataType::Type::kInt32: return vl >> 1; - case DataType::Type::kInt64: return vl; - default: break; - } - break; - default: - break; - } - LOG(FATAL) << "Unsupported idiom conversion"; - UNREACHABLE(); + DCHECK(DataType::IsIntegralType(other_type)); + DCHECK(DataType::IsIntegralType(vector_type)); + DCHECK_GE(DataType::SizeShift(other_type), DataType::SizeShift(vector_type)); + return vl >> (DataType::SizeShift(other_type) - DataType::SizeShift(vector_type)); } // Detect up to two instructions a and b, and an acccumulated constant c. @@ -1105,19 +1111,19 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, return true; } else if (instruction->IsArrayGet()) { // Deal with vector restrictions. - if (instruction->AsArrayGet()->IsStringCharAt() && - HasVectorRestrictions(restrictions, kNoStringCharAt)) { + bool is_string_char_at = instruction->AsArrayGet()->IsStringCharAt(); + if (is_string_char_at && HasVectorRestrictions(restrictions, kNoStringCharAt)) { return false; } // Accept a right-hand-side array base[index] for - // (1) exact matching vector type, + // (1) matching vector type (exact match or signed/unsigned integral type of the same size), // (2) loop-invariant base, // (3) unit stride index, // (4) vectorizable right-hand-side value. HInstruction* base = instruction->InputAt(0); HInstruction* index = instruction->InputAt(1); HInstruction* offset = nullptr; - if (type == instruction->GetType() && + if (DataType::ToSignedType(type) == DataType::ToSignedType(instruction->GetType()) && node->loop_info->IsDefinedOutOfTheLoop(base) && induction_range_.IsUnitStride(instruction, index, graph_, &offset)) { if (generate_code) { @@ -1281,6 +1287,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, } if (VectorizeUse(node, r, generate_code, type, restrictions)) { if (generate_code) { + NormalizePackedType(&type, &is_unsigned); GenerateVecOp(instruction, vector_map_->Get(r), nullptr, type); } return true; @@ -1340,6 +1347,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict // ARM 32-bit always supports advanced SIMD (64-bit SIMD). switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: *restrictions |= kNoDiv | kNoReduction; return TrySetVectorLength(8); @@ -1359,6 +1367,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict // ARMv8 AArch64 always supports advanced SIMD (128-bit SIMD). switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: *restrictions |= kNoDiv; return TrySetVectorLength(16); @@ -1387,6 +1396,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict if (features->AsX86InstructionSetFeatures()->HasSSE4_1()) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: *restrictions |= kNoMul | kNoDiv | kNoShift | kNoAbs | kNoSignedHAdd | kNoUnroundedHAdd | kNoSAD; @@ -1416,6 +1426,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict if (features->AsMipsInstructionSetFeatures()->HasMsa()) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: *restrictions |= kNoDiv | kNoReduction | kNoSAD; return TrySetVectorLength(16); @@ -1444,6 +1455,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict if (features->AsMips64InstructionSetFeatures()->HasMsa()) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: *restrictions |= kNoDiv | kNoReduction | kNoSAD; return TrySetVectorLength(16); @@ -1540,11 +1552,16 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, HInstruction* base = org->InputAt(0); if (opb != nullptr) { vector = new (global_allocator_) HVecStore( - global_allocator_, base, opa, opb, type, vector_length_); + global_allocator_, base, opa, opb, type, org->GetSideEffects(), vector_length_); } else { bool is_string_char_at = org->AsArrayGet()->IsStringCharAt(); - vector = new (global_allocator_) HVecLoad( - global_allocator_, base, opa, type, vector_length_, is_string_char_at); + vector = new (global_allocator_) HVecLoad(global_allocator_, + base, + opa, + type, + org->GetSideEffects(), + vector_length_, + is_string_char_at); } // Known dynamically enforced alignment? if (vector_peeling_candidate_ != nullptr && @@ -1556,11 +1573,12 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, // Scalar store or load. DCHECK(vector_mode_ == kSequential); if (opb != nullptr) { - vector = new (global_allocator_) HArraySet(org->InputAt(0), opa, opb, type, kNoDexPc); + vector = new (global_allocator_) HArraySet( + org->InputAt(0), opa, opb, type, org->GetSideEffects(), kNoDexPc); } else { bool is_string_char_at = org->AsArrayGet()->IsStringCharAt(); vector = new (global_allocator_) HArrayGet( - org->InputAt(0), opa, type, kNoDexPc, is_string_char_at); + org->InputAt(0), opa, type, org->GetSideEffects(), kNoDexPc, is_string_char_at); } } vector_map_->Put(org, vector); @@ -1737,6 +1755,7 @@ void HLoopOptimization::GenerateVecOp(HInstruction* org, case Intrinsics::kMathMinLongLong: case Intrinsics::kMathMinFloatFloat: case Intrinsics::kMathMinDoubleDouble: { + NormalizePackedType(&type, &is_unsigned); vector = new (global_allocator_) HVecMin(global_allocator_, opa, opb, type, vector_length_, is_unsigned); break; @@ -1745,6 +1764,7 @@ void HLoopOptimization::GenerateVecOp(HInstruction* org, case Intrinsics::kMathMaxLongLong: case Intrinsics::kMathMaxFloatFloat: case Intrinsics::kMathMaxDoubleDouble: { + NormalizePackedType(&type, &is_unsigned); vector = new (global_allocator_) HVecMax(global_allocator_, opa, opb, type, vector_length_, is_unsigned); break; @@ -1857,14 +1877,15 @@ bool HLoopOptimization::VectorizeHalvingAddIdiom(LoopNode* node, VectorizeUse(node, s, generate_code, type, restrictions)) { if (generate_code) { if (vector_mode_ == kVector) { + NormalizePackedType(&type, &is_unsigned); vector_map_->Put(instruction, new (global_allocator_) HVecHalvingAdd( global_allocator_, vector_map_->Get(r), vector_map_->Get(s), type, vector_length_, - is_unsigned, - is_rounded)); + is_rounded, + is_unsigned)); MaybeRecordStat(stats_, MethodCompilationStat::kLoopVectorizedIdiom); } else { GenerateVecOp(instruction, vector_map_->Get(r), vector_map_->Get(s), type); @@ -1952,6 +1973,7 @@ bool HLoopOptimization::VectorizeSADIdiom(LoopNode* node, VectorizeUse(node, r, generate_code, sub_type, restrictions) && VectorizeUse(node, s, generate_code, sub_type, restrictions)) { if (generate_code) { + NormalizePackedType(&reduction_type, &is_unsigned); if (vector_mode_ == kVector) { vector_map_->Put(instruction, new (global_allocator_) HVecSADAccumulate( global_allocator_, diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 41ea998a8c..cae5054ef7 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -590,6 +590,7 @@ HConstant* HGraph::GetConstant(DataType::Type type, int64_t value, uint32_t dex_ case DataType::Type::kBool: DCHECK(IsUint<1>(value)); FALLTHROUGH_INTENDED; + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index c49cee3284..c75a5124f3 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1760,14 +1760,26 @@ class SideEffects : public ValueObject { static constexpr uint64_t kAllReads = ((1ULL << (kLastBitForReads + 1 - kFieldReadOffset)) - 1) << kFieldReadOffset; - // Translates type to bit flag. + // Translates type to bit flag. The type must correspond to a Java type. static uint64_t TypeFlag(DataType::Type type, int offset) { - CHECK_NE(type, DataType::Type::kVoid); - const uint64_t one = 1; - const int shift = static_cast<int>(type); // 0-based consecutive enum + int shift; + switch (type) { + case DataType::Type::kReference: shift = 0; break; + case DataType::Type::kBool: shift = 1; break; + case DataType::Type::kInt8: shift = 2; break; + case DataType::Type::kUint16: shift = 3; break; + case DataType::Type::kInt16: shift = 4; break; + case DataType::Type::kInt32: shift = 5; break; + case DataType::Type::kInt64: shift = 6; break; + case DataType::Type::kFloat32: shift = 7; break; + case DataType::Type::kFloat64: shift = 8; break; + default: + LOG(FATAL) << "Unexpected data type " << type; + UNREACHABLE(); + } DCHECK_LE(kFieldWriteOffset, shift); DCHECK_LT(shift, kArrayWriteOffset); - return one << (shift + offset); + return UINT64_C(1) << (shift + offset); } // Private constructor on direct flags value. @@ -5382,9 +5394,21 @@ class HArrayGet FINAL : public HExpression<2> { HArrayGet(HInstruction* array, HInstruction* index, DataType::Type type, + uint32_t dex_pc) + : HArrayGet(array, + index, + type, + SideEffects::ArrayReadOfType(type), + dex_pc, + /* is_string_char_at */ false) {} + + HArrayGet(HInstruction* array, + HInstruction* index, + DataType::Type type, + SideEffects side_effects, uint32_t dex_pc, - bool is_string_char_at = false) - : HExpression(type, SideEffects::ArrayReadOfType(type), dex_pc) { + bool is_string_char_at) + : HExpression(type, side_effects, dex_pc) { SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at); SetRawInputAt(0, array); SetRawInputAt(1, index); @@ -5453,7 +5477,21 @@ class HArraySet FINAL : public HTemplateInstruction<3> { HInstruction* value, DataType::Type expected_component_type, uint32_t dex_pc) - : HTemplateInstruction(SideEffects::None(), dex_pc) { + : HArraySet(array, + index, + value, + expected_component_type, + // Make a best guess for side effects now, may be refined during SSA building. + ComputeSideEffects(GetComponentType(value->GetType(), expected_component_type)), + dex_pc) {} + + HArraySet(HInstruction* array, + HInstruction* index, + HInstruction* value, + DataType::Type expected_component_type, + SideEffects side_effects, + uint32_t dex_pc) + : HTemplateInstruction(side_effects, dex_pc) { SetPackedField<ExpectedComponentTypeField>(expected_component_type); SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType() == DataType::Type::kReference); SetPackedFlag<kFlagValueCanBeNull>(true); @@ -5461,8 +5499,6 @@ class HArraySet FINAL : public HTemplateInstruction<3> { SetRawInputAt(0, array); SetRawInputAt(1, index); SetRawInputAt(2, value); - // Make a best guess now, may be refined during SSA building. - ComputeSideEffects(); } bool NeedsEnvironment() const OVERRIDE { @@ -5501,24 +5537,26 @@ class HArraySet FINAL : public HTemplateInstruction<3> { HInstruction* GetValue() const { return InputAt(2); } DataType::Type GetComponentType() const { + return GetComponentType(GetValue()->GetType(), GetRawExpectedComponentType()); + } + + static DataType::Type GetComponentType(DataType::Type value_type, + DataType::Type expected_component_type) { // The Dex format does not type floating point index operations. Since the - // `expected_component_type_` is set during building and can therefore not + // `expected_component_type` comes from SSA building and can therefore not // be correct, we also check what is the value type. If it is a floating // point type, we must use that type. - DataType::Type value_type = GetValue()->GetType(); return ((value_type == DataType::Type::kFloat32) || (value_type == DataType::Type::kFloat64)) ? value_type - : GetRawExpectedComponentType(); + : expected_component_type; } DataType::Type GetRawExpectedComponentType() const { return GetPackedField<ExpectedComponentTypeField>(); } - void ComputeSideEffects() { - DataType::Type type = GetComponentType(); - SetSideEffects(SideEffects::ArrayWriteOfType(type).Union( - SideEffectsForArchRuntimeCalls(type))); + static SideEffects ComputeSideEffects(DataType::Type type) { + return SideEffects::ArrayWriteOfType(type).Union(SideEffectsForArchRuntimeCalls(type)); } static SideEffects SideEffectsForArchRuntimeCalls(DataType::Type value_type) { diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h index 0aac260839..d01f8c0289 100644 --- a/compiler/optimizing/nodes_vector.h +++ b/compiler/optimizing/nodes_vector.h @@ -232,8 +232,10 @@ inline static bool HasConsistentPackedTypes(HInstruction* input, DataType::Type DataType::Type input_type = input->AsVecOperation()->GetPackedType(); switch (input_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: return type == DataType::Type::kBool || + type == DataType::Type::kUint8 || type == DataType::Type::kInt8; case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -471,10 +473,14 @@ class HVecHalvingAdd FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - bool is_unsigned, bool is_rounded, - uint32_t dex_pc = kNoDexPc) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { + bool is_unsigned = false) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + // 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); @@ -584,9 +590,13 @@ class HVecMin FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - bool is_unsigned, - uint32_t dex_pc = kNoDexPc) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { + bool is_unsigned = false) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + // 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); @@ -622,9 +632,13 @@ class HVecMax FINAL : public HVecBinaryOperation { HInstruction* right, DataType::Type packed_type, size_t vector_length, - bool is_unsigned, - uint32_t dex_pc = kNoDexPc) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { + bool is_unsigned = false) + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, kNoDexPc) { + // 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); @@ -933,12 +947,13 @@ class HVecLoad FINAL : public HVecMemoryOperation { HInstruction* base, HInstruction* index, DataType::Type packed_type, + SideEffects side_effects, size_t vector_length, bool is_string_char_at, uint32_t dex_pc = kNoDexPc) : HVecMemoryOperation(arena, packed_type, - SideEffects::ArrayReadOfType(packed_type), + side_effects, /* number_of_inputs */ 2, vector_length, dex_pc) { @@ -977,11 +992,12 @@ class HVecStore FINAL : public HVecMemoryOperation { HInstruction* index, HInstruction* value, DataType::Type packed_type, + SideEffects side_effects, size_t vector_length, uint32_t dex_pc = kNoDexPc) : HVecMemoryOperation(arena, packed_type, - SideEffects::ArrayWriteOfType(packed_type), + side_effects, /* number_of_inputs */ 3, vector_length, dex_pc) { diff --git a/compiler/optimizing/nodes_vector_test.cc b/compiler/optimizing/nodes_vector_test.cc index 3acdb20b32..7dbfcda736 100644 --- a/compiler/optimizing/nodes_vector_test.cc +++ b/compiler/optimizing/nodes_vector_test.cc @@ -47,6 +47,16 @@ class NodesVectorTest : public CommonCompilerTest { 0, DataType::Type::kInt32); entry_block_->AddInstruction(parameter_); + int8_parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(1), + 0, + DataType::Type::kInt8); + entry_block_->AddInstruction(int8_parameter_); + int16_parameter_ = new (&allocator_) HParameterValue(graph_->GetDexFile(), + dex::TypeIndex(2), + 0, + DataType::Type::kInt16); + entry_block_->AddInstruction(int16_parameter_); } // General building fields. @@ -58,6 +68,8 @@ class NodesVectorTest : public CommonCompilerTest { HBasicBlock* exit_block_; HInstruction* parameter_; + HInstruction* int8_parameter_; + HInstruction* int16_parameter_; }; // @@ -126,8 +138,14 @@ TEST_F(NodesVectorTest, VectorOperationProperties) { HVecReplicateScalar(&allocator_, parameter_, DataType::Type::kInt32, 2); HVecOperation* v3 = new (&allocator_) HVecReplicateScalar(&allocator_, parameter_, DataType::Type::kInt16, 4); - HVecOperation* v4 = new (&allocator_) - HVecStore(&allocator_, parameter_, parameter_, v0, DataType::Type::kInt32, 4); + HVecOperation* v4 = new (&allocator_) HVecStore( + &allocator_, + parameter_, + parameter_, + v0, + DataType::Type::kInt32, + SideEffects::ArrayWriteOfType(DataType::Type::kInt32), + 4); EXPECT_TRUE(v0->Equals(v0)); EXPECT_TRUE(v1->Equals(v1)); @@ -175,12 +193,27 @@ TEST_F(NodesVectorTest, VectorOperationProperties) { } TEST_F(NodesVectorTest, VectorAlignmentAndStringCharAtMatterOnLoad) { - HVecLoad* v0 = new (&allocator_) HVecLoad( - &allocator_, parameter_, parameter_, DataType::Type::kInt32, 4, /*is_string_char_at*/ false); - HVecLoad* v1 = new (&allocator_) HVecLoad( - &allocator_, parameter_, parameter_, DataType::Type::kInt32, 4, /*is_string_char_at*/ false); - HVecLoad* v2 = new (&allocator_) HVecLoad( - &allocator_, parameter_, parameter_, DataType::Type::kInt32, 4, /*is_string_char_at*/ true); + HVecLoad* v0 = new (&allocator_) HVecLoad(&allocator_, + parameter_, + parameter_, + DataType::Type::kInt32, + SideEffects::ArrayReadOfType(DataType::Type::kInt32), + 4, + /*is_string_char_at*/ false); + HVecLoad* v1 = new (&allocator_) HVecLoad(&allocator_, + parameter_, + parameter_, + DataType::Type::kInt32, + SideEffects::ArrayReadOfType(DataType::Type::kInt32), + 4, + /*is_string_char_at*/ false); + HVecLoad* v2 = new (&allocator_) HVecLoad(&allocator_, + parameter_, + parameter_, + DataType::Type::kInt32, + SideEffects::ArrayReadOfType(DataType::Type::kInt32), + 4, + /*is_string_char_at*/ true); EXPECT_TRUE(v0->CanBeMoved()); EXPECT_TRUE(v1->CanBeMoved()); @@ -209,99 +242,155 @@ TEST_F(NodesVectorTest, VectorAlignmentAndStringCharAtMatterOnLoad) { } TEST_F(NodesVectorTest, VectorSignMattersOnMin) { - HVecOperation* v0 = new (&allocator_) + HVecOperation* p0 = new (&allocator_) HVecReplicateScalar(&allocator_, parameter_, DataType::Type::kInt32, 4); + HVecOperation* p1 = new (&allocator_) + HVecReplicateScalar(&allocator_, int8_parameter_, DataType::Type::kInt8, 4); + HVecOperation* p2 = new (&allocator_) + HVecReplicateScalar(&allocator_, int16_parameter_, DataType::Type::kInt16, 4); + + HVecMin* v0 = new (&allocator_) HVecMin( + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_unsigned*/ true); + HVecMin* v1 = new (&allocator_) HVecMin( + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_unsigned*/ false); + HVecMin* v2 = new (&allocator_) HVecMin( + &allocator_, p0, p0, DataType::Type::kInt32, 2, /*is_unsigned*/ true); + HVecMin* v3 = new (&allocator_) HVecMin(&allocator_, p1, p1, DataType::Type::kUint8, 16); + HVecMin* v4 = new (&allocator_) HVecMin(&allocator_, p1, p1, DataType::Type::kInt8, 16); + HVecMin* v5 = new (&allocator_) HVecMin(&allocator_, p2, p2, DataType::Type::kUint16, 8); + HVecMin* v6 = new (&allocator_) HVecMin(&allocator_, p2, p2, DataType::Type::kInt16, 8); + HVecMin* min_insns[] = { v0, v1, v2, v3, v4, v5, v6 }; + + EXPECT_FALSE(p0->CanBeMoved()); + EXPECT_FALSE(p1->CanBeMoved()); + EXPECT_FALSE(p2->CanBeMoved()); + + for (HVecMin* min_insn : min_insns) { + EXPECT_TRUE(min_insn->CanBeMoved()); + } - HVecMin* v1 = new (&allocator_) - HVecMin(&allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ true); - HVecMin* v2 = new (&allocator_) - HVecMin(&allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ false); - HVecMin* v3 = new (&allocator_) - HVecMin(&allocator_, v0, v0, DataType::Type::kInt32, 2, /*is_unsigned*/ true); - - EXPECT_FALSE(v0->CanBeMoved()); - EXPECT_TRUE(v1->CanBeMoved()); - EXPECT_TRUE(v2->CanBeMoved()); - EXPECT_TRUE(v3->CanBeMoved()); - - EXPECT_TRUE(v1->IsUnsigned()); - EXPECT_FALSE(v2->IsUnsigned()); - EXPECT_TRUE(v3->IsUnsigned()); - - EXPECT_TRUE(v1->Equals(v1)); - EXPECT_TRUE(v2->Equals(v2)); - EXPECT_TRUE(v3->Equals(v3)); + // Deprecated; IsUnsigned() should be removed with the introduction of Uint32 and Uint64. + EXPECT_TRUE(v0->IsUnsigned()); + EXPECT_FALSE(v1->IsUnsigned()); + EXPECT_TRUE(v2->IsUnsigned()); - EXPECT_FALSE(v1->Equals(v2)); // different signs - EXPECT_FALSE(v1->Equals(v3)); // different vector lengths + for (HVecMin* min_insn1 : min_insns) { + for (HVecMin* min_insn2 : min_insns) { + EXPECT_EQ(min_insn1 == min_insn2, min_insn1->Equals(min_insn2)); + } + } } TEST_F(NodesVectorTest, VectorSignMattersOnMax) { - HVecOperation* v0 = new (&allocator_) + HVecOperation* p0 = new (&allocator_) HVecReplicateScalar(&allocator_, parameter_, DataType::Type::kInt32, 4); + HVecOperation* p1 = new (&allocator_) + HVecReplicateScalar(&allocator_, int8_parameter_, DataType::Type::kInt8, 4); + HVecOperation* p2 = new (&allocator_) + HVecReplicateScalar(&allocator_, int16_parameter_, DataType::Type::kInt16, 4); + + HVecMax* v0 = new (&allocator_) HVecMax( + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_unsigned*/ true); + HVecMax* v1 = new (&allocator_) HVecMax( + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_unsigned*/ false); + HVecMax* v2 = new (&allocator_) HVecMax( + &allocator_, p0, p0, DataType::Type::kInt32, 2, /*is_unsigned*/ true); + HVecMax* v3 = new (&allocator_) HVecMax(&allocator_, p1, p1, DataType::Type::kUint8, 16); + HVecMax* v4 = new (&allocator_) HVecMax(&allocator_, p1, p1, DataType::Type::kInt8, 16); + HVecMax* v5 = new (&allocator_) HVecMax(&allocator_, p2, p2, DataType::Type::kUint16, 8); + HVecMax* v6 = new (&allocator_) HVecMax(&allocator_, p2, p2, DataType::Type::kInt16, 8); + HVecMax* max_insns[] = { v0, v1, v2, v3, v4, v5, v6 }; + + EXPECT_FALSE(p0->CanBeMoved()); + EXPECT_FALSE(p1->CanBeMoved()); + EXPECT_FALSE(p2->CanBeMoved()); + + for (HVecMax* max_insn : max_insns) { + EXPECT_TRUE(max_insn->CanBeMoved()); + } - HVecMax* v1 = new (&allocator_) - HVecMax(&allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ true); - HVecMax* v2 = new (&allocator_) - HVecMax(&allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ false); - HVecMax* v3 = new (&allocator_) - HVecMax(&allocator_, v0, v0, DataType::Type::kInt32, 2, /*is_unsigned*/ true); - - EXPECT_FALSE(v0->CanBeMoved()); - EXPECT_TRUE(v1->CanBeMoved()); - EXPECT_TRUE(v2->CanBeMoved()); - EXPECT_TRUE(v3->CanBeMoved()); - - EXPECT_TRUE(v1->IsUnsigned()); - EXPECT_FALSE(v2->IsUnsigned()); - EXPECT_TRUE(v3->IsUnsigned()); - - EXPECT_TRUE(v1->Equals(v1)); - EXPECT_TRUE(v2->Equals(v2)); - EXPECT_TRUE(v3->Equals(v3)); + // Deprecated; IsUnsigned() should be removed with the introduction of Uint32 and Uint64. + EXPECT_TRUE(v0->IsUnsigned()); + EXPECT_FALSE(v1->IsUnsigned()); + EXPECT_TRUE(v2->IsUnsigned()); - EXPECT_FALSE(v1->Equals(v2)); // different signs - EXPECT_FALSE(v1->Equals(v3)); // different vector lengths + for (HVecMax* max_insn1 : max_insns) { + for (HVecMax* max_insn2 : max_insns) { + EXPECT_EQ(max_insn1 == max_insn2, max_insn1->Equals(max_insn2)); + } + } } TEST_F(NodesVectorTest, VectorAttributesMatterOnHalvingAdd) { - HVecOperation* v0 = new (&allocator_) + HVecOperation* p0 = new (&allocator_) HVecReplicateScalar(&allocator_, parameter_, DataType::Type::kInt32, 4); + HVecOperation* p1 = new (&allocator_) + HVecReplicateScalar(&allocator_, int8_parameter_, DataType::Type::kInt8, 4); + HVecOperation* p2 = new (&allocator_) + HVecReplicateScalar(&allocator_, int16_parameter_, DataType::Type::kInt16, 4); + HVecHalvingAdd* v0 = new (&allocator_) HVecHalvingAdd( + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_rounded*/ true, /*is_unsigned*/ true); HVecHalvingAdd* v1 = new (&allocator_) HVecHalvingAdd( - &allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ true, /*is_rounded*/ true); + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_rounded*/ false, /*is_unsigned*/ true); HVecHalvingAdd* v2 = new (&allocator_) HVecHalvingAdd( - &allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ true, /*is_rounded*/ false); + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_rounded*/ true, /*is_unsigned*/ false); HVecHalvingAdd* v3 = new (&allocator_) HVecHalvingAdd( - &allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ false, /*is_rounded*/ true); + &allocator_, p0, p0, DataType::Type::kInt32, 4, /*is_rounded*/ false, /*is_unsigned*/ false); HVecHalvingAdd* v4 = new (&allocator_) HVecHalvingAdd( - &allocator_, v0, v0, DataType::Type::kInt32, 4, /*is_unsigned*/ false, /*is_rounded*/ false); + &allocator_, p0, p0, DataType::Type::kInt32, 2, /*is_rounded*/ true, /*is_unsigned*/ true); HVecHalvingAdd* v5 = new (&allocator_) HVecHalvingAdd( - &allocator_, v0, v0, DataType::Type::kInt32, 2, /*is_unsigned*/ true, /*is_rounded*/ true); - - EXPECT_FALSE(v0->CanBeMoved()); - EXPECT_TRUE(v1->CanBeMoved()); - EXPECT_TRUE(v2->CanBeMoved()); - EXPECT_TRUE(v3->CanBeMoved()); - EXPECT_TRUE(v4->CanBeMoved()); - EXPECT_TRUE(v5->CanBeMoved()); + &allocator_, p1, p1, DataType::Type::kUint8, 16, /*is_rounded*/ true); + HVecHalvingAdd* v6 = new (&allocator_) HVecHalvingAdd( + &allocator_, p1, p1, DataType::Type::kUint8, 16, /*is_rounded*/ false); + HVecHalvingAdd* v7 = new (&allocator_) HVecHalvingAdd( + &allocator_, p1, p1, DataType::Type::kInt8, 16, /*is_rounded*/ true); + HVecHalvingAdd* v8 = new (&allocator_) HVecHalvingAdd( + &allocator_, p1, p1, DataType::Type::kInt8, 16, /*is_rounded*/ false); + HVecHalvingAdd* v9 = new (&allocator_) HVecHalvingAdd( + &allocator_, p2, p2, DataType::Type::kUint16, 8, /*is_rounded*/ true); + HVecHalvingAdd* v10 = new (&allocator_) HVecHalvingAdd( + &allocator_, p2, p2, DataType::Type::kUint16, 8, /*is_rounded*/ false); + HVecHalvingAdd* v11 = new (&allocator_) HVecHalvingAdd( + &allocator_, p2, p2, DataType::Type::kInt16, 2, /*is_rounded*/ true); + HVecHalvingAdd* v12 = new (&allocator_) HVecHalvingAdd( + &allocator_, p2, p2, DataType::Type::kInt16, 2, /*is_rounded*/ false); + HVecHalvingAdd* hadd_insns[] = { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 }; + + EXPECT_FALSE(p0->CanBeMoved()); + EXPECT_FALSE(p1->CanBeMoved()); + EXPECT_FALSE(p2->CanBeMoved()); + + for (HVecHalvingAdd* hadd_insn : hadd_insns) { + EXPECT_TRUE(hadd_insn->CanBeMoved()); + } - EXPECT_TRUE(v1->Equals(v1)); - EXPECT_TRUE(v2->Equals(v2)); - EXPECT_TRUE(v3->Equals(v3)); - EXPECT_TRUE(v4->Equals(v4)); - EXPECT_TRUE(v5->Equals(v5)); - - EXPECT_TRUE(v1->IsUnsigned() && v1->IsRounded()); - EXPECT_TRUE(v2->IsUnsigned() && !v2->IsRounded()); - EXPECT_TRUE(!v3->IsUnsigned() && v3->IsRounded()); - EXPECT_TRUE(!v4->IsUnsigned() && !v4->IsRounded()); - EXPECT_TRUE(v5->IsUnsigned() && v5->IsRounded()); - - EXPECT_FALSE(v1->Equals(v2)); // different attributes - EXPECT_FALSE(v1->Equals(v3)); // different attributes - EXPECT_FALSE(v1->Equals(v4)); // different attributes - EXPECT_FALSE(v1->Equals(v5)); // different vector lengths + // Deprecated; IsUnsigned() should be removed with the introduction of Uint32 and Uint64. + EXPECT_TRUE(v0->IsUnsigned()); + EXPECT_TRUE(v1->IsUnsigned()); + EXPECT_TRUE(!v2->IsUnsigned()); + EXPECT_TRUE(!v3->IsUnsigned()); + EXPECT_TRUE(v4->IsUnsigned()); + + EXPECT_TRUE(v0->IsRounded()); + EXPECT_TRUE(!v1->IsRounded()); + EXPECT_TRUE(v2->IsRounded()); + EXPECT_TRUE(!v3->IsRounded()); + EXPECT_TRUE(v4->IsRounded()); + EXPECT_TRUE(v5->IsRounded()); + EXPECT_TRUE(!v6->IsRounded()); + EXPECT_TRUE(v7->IsRounded()); + EXPECT_TRUE(!v8->IsRounded()); + EXPECT_TRUE(v9->IsRounded()); + EXPECT_TRUE(!v10->IsRounded()); + EXPECT_TRUE(v11->IsRounded()); + EXPECT_TRUE(!v12->IsRounded()); + + for (HVecHalvingAdd* hadd_insn1 : hadd_insns) { + for (HVecHalvingAdd* hadd_insn2 : hadd_insns) { + EXPECT_EQ(hadd_insn1 == hadd_insn2, hadd_insn1->Equals(hadd_insn2)); + } + } } TEST_F(NodesVectorTest, VectorOperationMattersOnMultiplyAccumulate) { diff --git a/compiler/optimizing/register_allocation_resolver.cc b/compiler/optimizing/register_allocation_resolver.cc index f0057c3095..1786aa72a1 100644 --- a/compiler/optimizing/register_allocation_resolver.cc +++ b/compiler/optimizing/register_allocation_resolver.cc @@ -112,6 +112,7 @@ void RegisterAllocationResolver::Resolve(ArrayRef<HInstruction* const> safepoint case DataType::Type::kReference: case DataType::Type::kInt32: case DataType::Type::kUint16: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kBool: case DataType::Type::kInt16: diff --git a/compiler/optimizing/register_allocator_graph_color.cc b/compiler/optimizing/register_allocator_graph_color.cc index 4ff7315045..33df607831 100644 --- a/compiler/optimizing/register_allocator_graph_color.cc +++ b/compiler/optimizing/register_allocator_graph_color.cc @@ -1940,6 +1940,7 @@ void RegisterAllocatorGraphColor::AllocateSpillSlots(const ArenaVector<Interfere case DataType::Type::kReference: case DataType::Type::kInt32: case DataType::Type::kUint16: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kBool: case DataType::Type::kInt16: diff --git a/compiler/optimizing/register_allocator_linear_scan.cc b/compiler/optimizing/register_allocator_linear_scan.cc index 2012cd5847..9803a7b650 100644 --- a/compiler/optimizing/register_allocator_linear_scan.cc +++ b/compiler/optimizing/register_allocator_linear_scan.cc @@ -1116,6 +1116,7 @@ void RegisterAllocatorLinearScan::AllocateSpillSlotFor(LiveInterval* interval) { case DataType::Type::kReference: case DataType::Type::kInt32: case DataType::Type::kUint16: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kBool: case DataType::Type::kInt16: diff --git a/compiler/optimizing/scheduler_arm.cc b/compiler/optimizing/scheduler_arm.cc index 110db47eb5..b3c8f105d1 100644 --- a/compiler/optimizing/scheduler_arm.cc +++ b/compiler/optimizing/scheduler_arm.cc @@ -514,9 +514,10 @@ void SchedulingLatencyVisitorARM::VisitCompare(HCompare* instr) { DataType::Type type = instr->InputAt(0)->GetType(); switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: last_visited_internal_latency_ = 2 * kArmIntegerOpLatency; break; @@ -633,9 +634,10 @@ void SchedulingLatencyVisitorARM::VisitArrayGet(HArrayGet* instruction) { switch (type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { if (maybe_compressed_char_at) { last_visited_internal_latency_ += kArmMemoryLoadLatency; @@ -733,9 +735,10 @@ void SchedulingLatencyVisitorARM::VisitArraySet(HArraySet* instruction) { switch (value_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: { if (index->IsConstant()) { last_visited_latency_ = kArmMemoryStoreLatency; @@ -916,9 +919,10 @@ void SchedulingLatencyVisitorARM::HandleFieldGetLatencies(HInstruction* instruct switch (field_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: case DataType::Type::kInt32: last_visited_latency_ = kArmMemoryLoadLatency; break; @@ -977,9 +981,10 @@ void SchedulingLatencyVisitorARM::HandleFieldSetLatencies(HInstruction* instruct switch (field_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: - case DataType::Type::kInt16: case DataType::Type::kUint16: + case DataType::Type::kInt16: if (is_volatile) { last_visited_internal_latency_ = kArmMemoryBarrierLatency + kArmMemoryStoreLatency; last_visited_latency_ = kArmMemoryBarrierLatency; @@ -1047,6 +1052,7 @@ void SchedulingLatencyVisitorARM::VisitTypeConversion(HTypeConversion* instr) { DataType::Type input_type = instr->GetInputType(); switch (result_type) { + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1072,6 +1078,7 @@ void SchedulingLatencyVisitorARM::VisitTypeConversion(HTypeConversion* instr) { case DataType::Type::kInt64: switch (input_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1095,6 +1102,7 @@ void SchedulingLatencyVisitorARM::VisitTypeConversion(HTypeConversion* instr) { case DataType::Type::kFloat32: switch (input_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: @@ -1118,6 +1126,7 @@ void SchedulingLatencyVisitorARM::VisitTypeConversion(HTypeConversion* instr) { case DataType::Type::kFloat64: switch (input_type) { case DataType::Type::kBool: + case DataType::Type::kUint8: case DataType::Type::kInt8: case DataType::Type::kUint16: case DataType::Type::kInt16: diff --git a/compiler/optimizing/side_effects_test.cc b/compiler/optimizing/side_effects_test.cc index ac5eb15228..97317124ef 100644 --- a/compiler/optimizing/side_effects_test.cc +++ b/compiler/optimizing/side_effects_test.cc @@ -21,6 +21,19 @@ namespace art { +// Only runtime types other than void are allowed. +static const DataType::Type kTestTypes[] = { + DataType::Type::kReference, + DataType::Type::kBool, + DataType::Type::kInt8, + DataType::Type::kUint16, + DataType::Type::kInt16, + DataType::Type::kInt32, + DataType::Type::kInt64, + DataType::Type::kFloat32, + DataType::Type::kFloat64, +}; + /** * Tests for the SideEffects class. */ @@ -91,9 +104,7 @@ TEST(SideEffectsTest, None) { TEST(SideEffectsTest, DependencesAndNoDependences) { // Apply test to each individual data type. - for (DataType::Type type = DataType::Type::kReference; - type < DataType::Type::kVoid; - type = static_cast<DataType::Type>(static_cast<uint8_t>(type) + 1u)) { + for (DataType::Type type : kTestTypes) { // Same data type and access type: proper write/read dep. testWriteAndReadDependence( SideEffects::FieldWriteOfType(type, false), @@ -169,9 +180,7 @@ TEST(SideEffectsTest, SameWidthTypesNoAlias) { TEST(SideEffectsTest, AllWritesAndReads) { SideEffects s = SideEffects::None(); // Keep taking the union of different writes and reads. - for (DataType::Type type = DataType::Type::kReference; - type < DataType::Type::kVoid; - type = static_cast<DataType::Type>(static_cast<uint8_t>(type) + 1u)) { + for (DataType::Type type : kTestTypes) { s = s.Union(SideEffects::FieldWriteOfType(type, /* is_volatile */ false)); s = s.Union(SideEffects::ArrayWriteOfType(type)); s = s.Union(SideEffects::FieldReadOfType(type, /* is_volatile */ false)); diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index 77b7a228dc..23563168a0 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -393,7 +393,7 @@ bool SsaBuilder::FixAmbiguousArrayOps() { } // Refine the side effects of this floating point aset. Note that we do this even if // no replacement occurs, since the right-hand-side may have been corrected already. - aset->ComputeSideEffects(); + aset->SetSideEffects(HArraySet::ComputeSideEffects(aset->GetComponentType())); } else { // Array elements are integral and the value assigned to it initially // was integral too. Nothing to do. diff --git a/test/646-checker-hadd-alt-byte/src/Main.java b/test/646-checker-hadd-alt-byte/src/Main.java index 7be3151c6c..87f7688d4a 100644 --- a/test/646-checker-hadd-alt-byte/src/Main.java +++ b/test/646-checker-hadd-alt-byte/src/Main.java @@ -43,21 +43,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -83,21 +83,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -121,21 +121,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -162,21 +162,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -200,7 +200,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after) @@ -208,7 +208,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after) @@ -216,7 +216,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed_constant(byte[] b1, byte[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -241,7 +241,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after) @@ -249,7 +249,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after) @@ -257,7 +257,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(byte[] b1, byte[] bo) { int min_length = Math.min(bo.length, b1.length); diff --git a/test/646-checker-hadd-alt-char/src/Main.java b/test/646-checker-hadd-alt-char/src/Main.java index 2799ea7483..292ea1b826 100644 --- a/test/646-checker-hadd-alt-char/src/Main.java +++ b/test/646-checker-hadd-alt-char/src/Main.java @@ -43,21 +43,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(char[] b1, char[] b2, char[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -83,21 +83,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). @@ -124,21 +124,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(char[] b1, char[] b2, char[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -165,21 +165,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). @@ -206,7 +206,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after) @@ -214,7 +214,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after) @@ -222,7 +222,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(char[] b1, char[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -247,7 +247,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (after) @@ -255,7 +255,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). diff --git a/test/646-checker-hadd-alt-short/src/Main.java b/test/646-checker-hadd-alt-short/src/Main.java index 6cd102f035..da94829e3d 100644 --- a/test/646-checker-hadd-alt-short/src/Main.java +++ b/test/646-checker-hadd-alt-short/src/Main.java @@ -43,21 +43,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -83,21 +83,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -121,21 +121,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -162,21 +162,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -200,7 +200,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after) @@ -208,7 +208,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after) @@ -216,7 +216,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed_constant(short[] b1, short[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -241,7 +241,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after) @@ -249,7 +249,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after) @@ -257,7 +257,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(short[] b1, short[] bo) { int min_length = Math.min(bo.length, b1.length); diff --git a/test/646-checker-hadd-byte/src/Main.java b/test/646-checker-hadd-byte/src/Main.java index a9e844cf17..f0adca301e 100644 --- a/test/646-checker-hadd-byte/src/Main.java +++ b/test/646-checker-hadd-byte/src/Main.java @@ -40,21 +40,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -80,21 +80,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -118,21 +118,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -159,21 +159,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(byte[] b1, byte[] b2, byte[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -197,7 +197,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after) @@ -205,7 +205,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed_constant(byte[], byte[]) loop_optimization (after) @@ -213,7 +213,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I127>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed_constant(byte[] b1, byte[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -238,7 +238,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after) @@ -246,7 +246,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(byte[], byte[]) loop_optimization (after) @@ -254,7 +254,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I255>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint8 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(byte[] b1, byte[] bo) { int min_length = Math.min(bo.length, b1.length); diff --git a/test/646-checker-hadd-char/src/Main.java b/test/646-checker-hadd-char/src/Main.java index 22eb7cb3cc..94030cc298 100644 --- a/test/646-checker-hadd-char/src/Main.java +++ b/test/646-checker-hadd-char/src/Main.java @@ -40,21 +40,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(char[] b1, char[] b2, char[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -80,21 +80,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). @@ -121,21 +121,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(char[] b1, char[] b2, char[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -162,21 +162,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_also_unsigned(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). @@ -203,7 +203,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after) @@ -211,7 +211,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(char[], char[]) loop_optimization (after) @@ -219,7 +219,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(char[] b1, char[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -244,7 +244,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (after) @@ -252,7 +252,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_also_unsigned_constant(char[], char[]) loop_optimization (after) @@ -260,7 +260,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // // Note: HAnd has no impact (already a zero extension). diff --git a/test/646-checker-hadd-short/src/Main.java b/test/646-checker-hadd-short/src/Main.java index 756f8a8ae9..4ed23563b8 100644 --- a/test/646-checker-hadd-short/src/Main.java +++ b/test/646-checker-hadd-short/src/Main.java @@ -40,21 +40,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -81,21 +81,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed_alt(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -122,21 +122,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -160,21 +160,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -198,21 +198,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed_alt(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -240,21 +240,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_signed_alt2(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_signed_alt2(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:false rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Int16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_signed_alt2(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -282,21 +282,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -323,21 +323,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.rounding_halving_add_unsigned_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.rounding_halving_add_unsigned_alt(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] unsigned:true rounded:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 rounded:true loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void rounding_halving_add_unsigned_alt(short[] b1, short[] b2, short[] bo) { int min_length = Math.min(bo.length, Math.min(b1.length, b2.length)); @@ -362,7 +362,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after) @@ -370,7 +370,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_signed_constant(short[], short[]) loop_optimization (after) @@ -378,7 +378,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<SMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:false rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Int16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_signed_constant(short[] b1, short[] bo) { int min_length = Math.min(bo.length, b1.length); @@ -403,7 +403,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after) @@ -411,7 +411,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.halving_add_unsigned_constant(short[], short[]) loop_optimization (after) @@ -419,7 +419,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<UMAX>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] unsigned:true rounded:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<HAdd:d\d+>> VecHalvingAdd [<<Get>>,<<Repl>>] packed_type:Uint16 rounded:false loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<HAdd>>] loop:<<Loop>> outer_loop:none private static void halving_add_unsigned_constant(short[] b1, short[] bo) { int min_length = Math.min(bo.length, b1.length); diff --git a/test/651-checker-byte-simd-minmax/src/Main.java b/test/651-checker-byte-simd-minmax/src/Main.java index 9643b90d15..44472a87cb 100644 --- a/test/651-checker-byte-simd-minmax/src/Main.java +++ b/test/651-checker-byte-simd-minmax/src/Main.java @@ -31,21 +31,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMin(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMin(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin(byte[] x, byte[] y, byte[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -69,21 +69,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMinUnsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMinUnsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMinUnsigned(byte[] x, byte[] y, byte[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -104,21 +104,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMax(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMax(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none private static void doitMax(byte[] x, byte[] y, byte[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -142,21 +142,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMaxUnsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMaxUnsigned(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none private static void doitMaxUnsigned(byte[] x, byte[] y, byte[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -178,7 +178,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Int8 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin100(byte[] x, byte[] y) { int min = Math.min(x.length, y.length); diff --git a/test/651-checker-char-simd-minmax/src/Main.java b/test/651-checker-char-simd-minmax/src/Main.java index 8a0262cfcd..93f21f823b 100644 --- a/test/651-checker-char-simd-minmax/src/Main.java +++ b/test/651-checker-char-simd-minmax/src/Main.java @@ -31,21 +31,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMin(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMin(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin(char[] x, char[] y, char[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -66,21 +66,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMax(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMax(char[], char[], char[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none private static void doitMax(char[] x, char[] y, char[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -102,7 +102,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin100(char[] x, char[] y) { int min = Math.min(x.length, y.length); diff --git a/test/651-checker-short-simd-minmax/src/Main.java b/test/651-checker-short-simd-minmax/src/Main.java index ffbf73bd62..00569e4ae1 100644 --- a/test/651-checker-short-simd-minmax/src/Main.java +++ b/test/651-checker-short-simd-minmax/src/Main.java @@ -31,21 +31,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMin(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMin(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin(short[] x, short[] y, short[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -69,21 +69,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMinUnsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMinUnsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMinUnsigned(short[] x, short[] y, short[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -104,21 +104,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMax(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMax(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none private static void doitMax(short[] x, short[] y, short[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -142,21 +142,21 @@ public class Main { /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM64: void Main.doitMaxUnsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none // /// CHECK-START-MIPS64: void Main.doitMaxUnsigned(short[], short[], short[]) loop_optimization (after) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] unsigned:true loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none private static void doitMaxUnsigned(short[] x, short[] y, short[] z) { int min = Math.min(x.length, Math.min(y.length, z.length)); @@ -178,7 +178,7 @@ public class Main { /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] unsigned:false loop:<<Loop>> outer_loop:none + /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Int16 loop:<<Loop>> outer_loop:none /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none private static void doitMin100(short[] x, short[] y) { int min = Math.min(x.length, y.length); |