summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2024-09-10 21:25:15 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2024-09-11 09:29:15 +0000
commit744830cb242c82c4637e6fb303b36d0371c84979 (patch)
tree843d73b277fb4057fa63f4dcf232640e0e688bce
parent88c7e963f7861a1b92742150010ca7253f10023f (diff)
Revert "riscv64: Add node Rol, fix InstructionBuilder"
This reverts commit 39927bc359ccbe65371213c4559126b05dcfb117. Reason for revert: Failure on bot with: error: Statement could not be matched starting from line 1089612 TestRotate.java:95: rol {{a\d+}}, {{a\d+}}, {{a\d+}} ISA_FEATURES = {'rv64gcv_zba_zbb_zbs': True} READ_BARRIER_TYPE = baker 567-checker-builder-intrinsics FAILED: [run-test:1074] CFG checker failed $ ssh -q -F /b/s/w/ir/cache/builder/art/test/testrunner/ssh_config -p 10001 ubuntu@localhost "rm -rf /home/ubuntu/art-test-chroot/data/run-test/test-343039" 567-checker-builder-intrinsics files deleted from host and from target ---------- test-art-target-run-test-ndebug-prebuild-optimizing-no-relocate-ntrace-cms-checkjni-picimage-ndebuggable-no-jvmti-567-checker-builder-intrinsics64 Change-Id: Ic1fd87c331c9eba315af6c98c3ad393766327417
-rw-r--r--compiler/optimizing/code_generator_arm64.cc24
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc87
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.h8
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc22
-rw-r--r--compiler/optimizing/code_generator_x86.cc56
-rw-r--r--compiler/optimizing/code_generator_x86.h2
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc62
-rw-r--r--compiler/optimizing/code_generator_x86_64.h2
-rw-r--r--compiler/optimizing/graph_checker.cc4
-rw-r--r--compiler/optimizing/instruction_builder.cc19
-rw-r--r--compiler/optimizing/instruction_simplifier_arm.cc6
-rw-r--r--compiler/optimizing/instruction_simplifier_arm64.cc6
-rw-r--r--compiler/optimizing/instruction_simplifier_shared.cc19
-rw-r--r--compiler/optimizing/instruction_simplifier_shared.h8
-rw-r--r--compiler/optimizing/instruction_simplifier_x86.cc31
-rw-r--r--compiler/optimizing/nodes.cc2
-rw-r--r--compiler/optimizing/nodes.h26
-rw-r--r--test/567-checker-builder-intrinsics/src/TestRotate.java439
18 files changed, 184 insertions, 639 deletions
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 42d955ef9e..6ffd1aa686 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -2430,22 +2430,6 @@ void InstructionCodeGeneratorARM64::HandleBinaryOp(HBinaryOperation* instr) {
__ Orr(dst, lhs, rhs);
} else if (instr->IsSub()) {
__ Sub(dst, lhs, rhs);
- } else if (instr->IsRol()) {
- if (rhs.IsImmediate()) {
- uint32_t shift = (-rhs.GetImmediate()) & (lhs.GetSizeInBits() - 1);
- __ Ror(dst, lhs, shift);
- } else {
- UseScratchRegisterScope temps(GetVIXLAssembler());
-
- // Ensure shift distance is in the same size register as the result. If
- // we are rotating a long and the shift comes in a w register originally,
- // we don't need to sxtw for use as an x since the shift distances are
- // all & reg_bits - 1.
- Register right = RegisterFrom(instr->GetLocations()->InAt(1), type);
- Register negated = (type == DataType::Type::kInt32) ? temps.AcquireW() : temps.AcquireX();
- __ Neg(negated, right);
- __ Ror(dst, lhs, negated);
- }
} else if (instr->IsRor()) {
if (rhs.IsImmediate()) {
uint32_t shift = rhs.GetImmediate() & (lhs.GetSizeInBits() - 1);
@@ -6427,14 +6411,6 @@ void InstructionCodeGeneratorARM64::VisitReturnVoid([[maybe_unused]] HReturnVoid
codegen_->GenerateFrameExit();
}
-void LocationsBuilderARM64::VisitRol(HRol* rol) {
- HandleBinaryOp(rol);
-}
-
-void InstructionCodeGeneratorARM64::VisitRol(HRol* rol) {
- HandleBinaryOp(rol);
-}
-
void LocationsBuilderARM64::VisitRor(HRor* ror) {
HandleBinaryOp(ror);
}
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index fb8f8c0153..1afca6b8d6 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -5280,22 +5280,17 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi
}
}
-void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rotate) {
- LocationSummary* locations = rotate->GetLocations();
- vixl32::Register in = InputRegisterAt(rotate, 0);
+void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HRor* ror) {
+ LocationSummary* locations = ror->GetLocations();
+ vixl32::Register in = InputRegisterAt(ror, 0);
Location rhs = locations->InAt(1);
- vixl32::Register out = OutputRegister(rotate);
+ vixl32::Register out = OutputRegister(ror);
if (rhs.IsConstant()) {
// Arm32 and Thumb2 assemblers require a rotation on the interval [1,31],
// so map all rotations to a +ve. equivalent in that range.
// (e.g. left *or* right by -2 bits == 30 bits in the same direction.)
uint32_t rot = CodeGenerator::GetInt32ValueOf(rhs.GetConstant()) & 0x1F;
-
- if (rotate->IsRol()) {
- rot = -rot;
- }
-
if (rot) {
// Rotate, mapping left rotations to right equivalents if necessary.
// (e.g. left by 2 bits == right by 30.)
@@ -5304,16 +5299,7 @@ void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rota
__ Mov(out, in);
}
} else {
- if (rotate->IsRol()) {
- UseScratchRegisterScope temps(GetVIXLAssembler());
-
- vixl32::Register negated = temps.Acquire();
- __ Rsb(negated, RegisterFrom(rhs), 0);
- __ Ror(out, in, negated);
- } else {
- DCHECK(rotate->IsRor());
- __ Ror(out, in, RegisterFrom(rhs));
- }
+ __ Ror(out, in, RegisterFrom(rhs));
}
}
@@ -5321,8 +5307,8 @@ void InstructionCodeGeneratorARMVIXL::HandleIntegerRotate(HBinaryOperation* rota
// rotates by swapping input regs (effectively rotating by the first 32-bits of
// a larger rotation) or flipping direction (thus treating larger right/left
// rotations as sub-word sized rotations in the other direction) as appropriate.
-void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate) {
- LocationSummary* locations = rotate->GetLocations();
+void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HRor* ror) {
+ LocationSummary* locations = ror->GetLocations();
vixl32::Register in_reg_lo = LowRegisterFrom(locations->InAt(0));
vixl32::Register in_reg_hi = HighRegisterFrom(locations->InAt(0));
Location rhs = locations->InAt(1);
@@ -5331,11 +5317,6 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate)
if (rhs.IsConstant()) {
uint64_t rot = CodeGenerator::GetInt64ValueOf(rhs.GetConstant());
-
- if (rotate->IsRol()) {
- rot = -rot;
- }
-
// Map all rotations to +ve. equivalents on the interval [0,63].
rot &= kMaxLongShiftDistance;
// For rotates over a word in size, 'pre-rotate' by 32-bits to keep rotate
@@ -5360,17 +5341,7 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate)
vixl32::Register shift_left = RegisterFrom(locations->GetTemp(1));
vixl32::Label end;
vixl32::Label shift_by_32_plus_shift_right;
- vixl32::Label* final_label = codegen_->GetFinalLabel(rotate, &end);
-
- // Negate rhs, taken from VisitNeg
- if (rotate->IsRol()) {
- Location negated = locations->GetTemp(2);
- Location in = rhs;
-
- __ Rsb(RegisterFrom(negated), RegisterFrom(in), 0);
-
- rhs = negated;
- }
+ vixl32::Label* final_label = codegen_->GetFinalLabel(ror, &end);
__ And(shift_right, RegisterFrom(rhs), 0x1F);
__ Lsrs(shift_left, RegisterFrom(rhs), 6);
@@ -5403,11 +5374,11 @@ void InstructionCodeGeneratorARMVIXL::HandleLongRotate(HBinaryOperation* rotate)
}
}
-void LocationsBuilderARMVIXL::HandleRotate(HBinaryOperation* rotate) {
+void LocationsBuilderARMVIXL::VisitRor(HRor* ror) {
LocationSummary* locations =
- new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall);
- HInstruction* shift = rotate->InputAt(1);
- switch (rotate->GetResultType()) {
+ new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall);
+ HInstruction* shift = ror->InputAt(1);
+ switch (ror->GetResultType()) {
case DataType::Type::kInt32: {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::RegisterOrConstant(shift));
@@ -5420,39 +5391,25 @@ void LocationsBuilderARMVIXL::HandleRotate(HBinaryOperation* rotate) {
locations->SetInAt(1, Location::ConstantLocation(shift));
} else {
locations->SetInAt(1, Location::RequiresRegister());
-
- if (rotate->IsRor()) {
- locations->AddRegisterTemps(2);
- } else {
- DCHECK(rotate->IsRol());
- locations->AddRegisterTemps(3);
- }
+ locations->AddRegisterTemps(2);
}
locations->SetOut(Location::RequiresRegister(), Location::kOutputOverlap);
break;
}
default:
- LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType();
+ LOG(FATAL) << "Unexpected operation type " << ror->GetResultType();
}
}
-void LocationsBuilderARMVIXL::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
-void LocationsBuilderARMVIXL::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
-void InstructionCodeGeneratorARMVIXL::HandleRotate(HBinaryOperation* rotate) {
- DataType::Type type = rotate->GetResultType();
+void InstructionCodeGeneratorARMVIXL::VisitRor(HRor* ror) {
+ DataType::Type type = ror->GetResultType();
switch (type) {
case DataType::Type::kInt32: {
- HandleIntegerRotate(rotate);
+ HandleIntegerRotate(ror);
break;
}
case DataType::Type::kInt64: {
- HandleLongRotate(rotate);
+ HandleLongRotate(ror);
break;
}
default:
@@ -5461,14 +5418,6 @@ void InstructionCodeGeneratorARMVIXL::HandleRotate(HBinaryOperation* rotate) {
}
}
-void InstructionCodeGeneratorARMVIXL::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
-void InstructionCodeGeneratorARMVIXL::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
void LocationsBuilderARMVIXL::HandleShift(HBinaryOperation* op) {
DCHECK(op->IsShl() || op->IsShr() || op->IsUShr());
diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h
index 00b5a69b1d..0c2e79c134 100644
--- a/compiler/optimizing/code_generator_arm_vixl.h
+++ b/compiler/optimizing/code_generator_arm_vixl.h
@@ -390,12 +390,13 @@ class LocationsBuilderARMVIXL : public HGraphVisitor {
void HandleInvoke(HInvoke* invoke);
void HandleBitwiseOperation(HBinaryOperation* operation, Opcode opcode);
void HandleCondition(HCondition* condition);
+ void HandleIntegerRotate(LocationSummary* locations);
+ void HandleLongRotate(LocationSummary* locations);
void HandleShift(HBinaryOperation* operation);
void HandleFieldSet(HInstruction* instruction,
const FieldInfo& field_info,
WriteBarrierKind write_barrier_kind);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
- void HandleRotate(HBinaryOperation* rotate);
Location ArithmeticZeroOrFpuRegister(HInstruction* input);
Location ArmEncodableConstantOrRegister(HInstruction* constant, Opcode opcode);
@@ -445,9 +446,8 @@ class InstructionCodeGeneratorARMVIXL : public InstructionCodeGenerator {
void GenerateAddLongConst(Location out, Location first, uint64_t value);
void HandleBitwiseOperation(HBinaryOperation* operation);
void HandleCondition(HCondition* condition);
- void HandleIntegerRotate(HBinaryOperation* rotate);
- void HandleLongRotate(HBinaryOperation* rotate);
- void HandleRotate(HBinaryOperation* rotate);
+ void HandleIntegerRotate(HRor* ror);
+ void HandleLongRotate(HRor* ror);
void HandleShift(HBinaryOperation* operation);
void GenerateWideAtomicStore(vixl::aarch32::Register addr,
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index 43f855a915..bfc693f76b 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -2331,7 +2331,6 @@ void LocationsBuilderRISCV64::HandleShift(HBinaryOperation* instruction) {
DCHECK(instruction->IsShl() ||
instruction->IsShr() ||
instruction->IsUShr() ||
- instruction->IsRol() ||
instruction->IsRor());
LocationSummary* locations = new (GetGraph()->GetAllocator()) LocationSummary(instruction);
@@ -2354,9 +2353,7 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
DCHECK(instruction->IsShl() ||
instruction->IsShr() ||
instruction->IsUShr() ||
- instruction->IsRol() ||
instruction->IsRor());
-
LocationSummary* locations = instruction->GetLocations();
DataType::Type type = instruction->GetType();
@@ -2369,9 +2366,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
if (rs2_location.IsConstant()) {
int64_t imm = CodeGenerator::GetInt64ValueOf(rs2_location.GetConstant());
- if (instruction->IsRol()) {
- imm = -imm;
- }
uint32_t shamt =
imm & (type == DataType::Type::kInt32 ? kMaxIntShiftDistance : kMaxLongShiftDistance);
@@ -2386,8 +2380,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
__ Sraiw(rd, rs1, shamt);
} else if (instruction->IsUShr()) {
__ Srliw(rd, rs1, shamt);
- } else if (instruction->IsRol()) {
- __ Roriw(rd, rs1, shamt);
} else {
DCHECK(instruction->IsRor());
__ Roriw(rd, rs1, shamt);
@@ -2399,8 +2391,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
__ Srai(rd, rs1, shamt);
} else if (instruction->IsUShr()) {
__ Srli(rd, rs1, shamt);
- } else if (instruction->IsRol()) {
- __ Rori(rd, rs1, shamt);
} else {
DCHECK(instruction->IsRor());
__ Rori(rd, rs1, shamt);
@@ -2415,8 +2405,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
__ Sraw(rd, rs1, rs2);
} else if (instruction->IsUShr()) {
__ Srlw(rd, rs1, rs2);
- } else if (instruction->IsRol()) {
- __ Rolw(rd, rs1, rs2);
} else {
DCHECK(instruction->IsRor());
__ Rorw(rd, rs1, rs2);
@@ -2428,8 +2416,6 @@ void InstructionCodeGeneratorRISCV64::HandleShift(HBinaryOperation* instruction)
__ Sra(rd, rs1, rs2);
} else if (instruction->IsUShr()) {
__ Srl(rd, rs1, rs2);
- } else if (instruction->IsRol()) {
- __ Rol(rd, rs1, rs2);
} else {
DCHECK(instruction->IsRor());
__ Ror(rd, rs1, rs2);
@@ -5020,14 +5006,6 @@ void InstructionCodeGeneratorRISCV64::VisitReturnVoid([[maybe_unused]] HReturnVo
codegen_->GenerateFrameExit();
}
-void LocationsBuilderRISCV64::VisitRol(HRol* instruction) {
- HandleShift(instruction);
-}
-
-void InstructionCodeGeneratorRISCV64::VisitRol(HRol* instruction) {
- HandleShift(instruction);
-}
-
void LocationsBuilderRISCV64::VisitRor(HRor* instruction) {
HandleShift(instruction);
}
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 7e3c6216eb..5b2d0d4535 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -5052,19 +5052,11 @@ void InstructionCodeGeneratorX86::GenerateUShrLong(const Location& loc, Register
__ Bind(&done);
}
-void LocationsBuilderX86::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
void LocationsBuilderX86::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
-void LocationsBuilderX86::HandleRotate(HBinaryOperation* rotate) {
LocationSummary* locations =
- new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall);
+ new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall);
- switch (rotate->GetResultType()) {
+ switch (ror->GetResultType()) {
case DataType::Type::kInt64:
// Add the temporary needed.
locations->AddTemp(Location::RequiresRegister());
@@ -5072,62 +5064,39 @@ void LocationsBuilderX86::HandleRotate(HBinaryOperation* rotate) {
case DataType::Type::kInt32:
locations->SetInAt(0, Location::RequiresRegister());
// The shift count needs to be in CL (unless it is a constant).
- locations->SetInAt(1, Location::ByteRegisterOrConstant(ECX, rotate->InputAt(1)));
+ locations->SetInAt(1, Location::ByteRegisterOrConstant(ECX, ror->InputAt(1)));
locations->SetOut(Location::SameAsFirstInput());
break;
default:
- LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType();
+ LOG(FATAL) << "Unexpected operation type " << ror->GetResultType();
UNREACHABLE();
}
}
-void InstructionCodeGeneratorX86::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
void InstructionCodeGeneratorX86::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
-void InstructionCodeGeneratorX86::HandleRotate(HBinaryOperation* rotate) {
- LocationSummary* locations = rotate->GetLocations();
+ LocationSummary* locations = ror->GetLocations();
Location first = locations->InAt(0);
Location second = locations->InAt(1);
- if (rotate->GetResultType() == DataType::Type::kInt32) {
+ if (ror->GetResultType() == DataType::Type::kInt32) {
Register first_reg = first.AsRegister<Register>();
if (second.IsRegister()) {
Register second_reg = second.AsRegister<Register>();
- if (rotate->IsRol()) {
- __ roll(first_reg, second_reg);
- } else {
- DCHECK(rotate->IsRor());
- __ rorl(first_reg, second_reg);
- }
+ __ rorl(first_reg, second_reg);
} else {
Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftDistance);
- if (rotate->IsRol()) {
- __ roll(first_reg, imm);
- } else {
- DCHECK(rotate->IsRor());
- __ rorl(first_reg, imm);
- }
+ __ rorl(first_reg, imm);
}
return;
}
- DCHECK_EQ(rotate->GetResultType(), DataType::Type::kInt64);
+ DCHECK_EQ(ror->GetResultType(), DataType::Type::kInt64);
Register first_reg_lo = first.AsRegisterPairLow<Register>();
Register first_reg_hi = first.AsRegisterPairHigh<Register>();
Register temp_reg = locations->GetTemp(0).AsRegister<Register>();
if (second.IsRegister()) {
Register second_reg = second.AsRegister<Register>();
DCHECK_EQ(second_reg, ECX);
-
- if (rotate->IsRol()) {
- __ negl(second_reg);
- }
-
__ movl(temp_reg, first_reg_hi);
__ shrd(first_reg_hi, first_reg_lo, second_reg);
__ shrd(first_reg_lo, temp_reg, second_reg);
@@ -5136,12 +5105,7 @@ void InstructionCodeGeneratorX86::HandleRotate(HBinaryOperation* rotate) {
__ cmovl(kNotEqual, first_reg_hi, first_reg_lo);
__ cmovl(kNotEqual, first_reg_lo, temp_reg);
} else {
- int32_t value = second.GetConstant()->AsIntConstant()->GetValue();
- if (rotate->IsRol()) {
- value = -value;
- }
- int32_t shift_amt = value & kMaxLongShiftDistance;
-
+ int32_t shift_amt = second.GetConstant()->AsIntConstant()->GetValue() & kMaxLongShiftDistance;
if (shift_amt == 0) {
// Already fine.
return;
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index 321ee92e2e..bb6fa2a298 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -249,7 +249,6 @@ class LocationsBuilderX86 : public HGraphVisitor {
void HandleBitwiseOperation(HBinaryOperation* instruction);
void HandleInvoke(HInvoke* invoke);
void HandleCondition(HCondition* condition);
- void HandleRotate(HBinaryOperation* rotate);
void HandleShift(HBinaryOperation* instruction);
void HandleFieldSet(HInstruction* instruction,
const FieldInfo& field_info,
@@ -340,7 +339,6 @@ class InstructionCodeGeneratorX86 : public InstructionCodeGenerator {
bool value_can_be_null,
WriteBarrierKind write_barrier_kind);
void HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info);
- void HandleRotate(HBinaryOperation* rotate);
// Generate a heap reference load using one register `out`:
//
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 51ded684c6..6a7f9b1264 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -5035,91 +5035,55 @@ void InstructionCodeGeneratorX86_64::HandleShift(HBinaryOperation* op) {
}
}
-void LocationsBuilderX86_64::HandleRotate(HBinaryOperation* rotate) {
+void LocationsBuilderX86_64::VisitRor(HRor* ror) {
LocationSummary* locations =
- new (GetGraph()->GetAllocator()) LocationSummary(rotate, LocationSummary::kNoCall);
+ new (GetGraph()->GetAllocator()) LocationSummary(ror, LocationSummary::kNoCall);
- switch (rotate->GetResultType()) {
+ switch (ror->GetResultType()) {
case DataType::Type::kInt32:
case DataType::Type::kInt64: {
locations->SetInAt(0, Location::RequiresRegister());
// The shift count needs to be in CL (unless it is a constant).
- locations->SetInAt(1, Location::ByteRegisterOrConstant(RCX, rotate->InputAt(1)));
+ locations->SetInAt(1, Location::ByteRegisterOrConstant(RCX, ror->InputAt(1)));
locations->SetOut(Location::SameAsFirstInput());
break;
}
default:
- LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType();
+ LOG(FATAL) << "Unexpected operation type " << ror->GetResultType();
UNREACHABLE();
}
}
-void InstructionCodeGeneratorX86_64::HandleRotate(HBinaryOperation* rotate) {
- LocationSummary* locations = rotate->GetLocations();
+void InstructionCodeGeneratorX86_64::VisitRor(HRor* ror) {
+ LocationSummary* locations = ror->GetLocations();
CpuRegister first_reg = locations->InAt(0).AsRegister<CpuRegister>();
Location second = locations->InAt(1);
- switch (rotate->GetResultType()) {
+ switch (ror->GetResultType()) {
case DataType::Type::kInt32:
if (second.IsRegister()) {
CpuRegister second_reg = second.AsRegister<CpuRegister>();
- if (rotate->IsRor()) {
- __ rorl(first_reg, second_reg);
- } else {
- DCHECK(rotate->IsRol());
- __ roll(first_reg, second_reg);
- }
+ __ rorl(first_reg, second_reg);
} else {
Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxIntShiftDistance);
- if (rotate->IsRor()) {
- __ rorl(first_reg, imm);
- } else {
- DCHECK(rotate->IsRol());
- __ roll(first_reg, imm);
- }
+ __ rorl(first_reg, imm);
}
break;
case DataType::Type::kInt64:
if (second.IsRegister()) {
CpuRegister second_reg = second.AsRegister<CpuRegister>();
- if (rotate->IsRor()) {
- __ rorq(first_reg, second_reg);
- } else {
- DCHECK(rotate->IsRol());
- __ rolq(first_reg, second_reg);
- }
+ __ rorq(first_reg, second_reg);
} else {
Immediate imm(second.GetConstant()->AsIntConstant()->GetValue() & kMaxLongShiftDistance);
- if (rotate->IsRor()) {
- __ rorq(first_reg, imm);
- } else {
- DCHECK(rotate->IsRol());
- __ rolq(first_reg, imm);
- }
+ __ rorq(first_reg, imm);
}
break;
default:
- LOG(FATAL) << "Unexpected operation type " << rotate->GetResultType();
+ LOG(FATAL) << "Unexpected operation type " << ror->GetResultType();
UNREACHABLE();
}
}
-void InstructionCodeGeneratorX86_64::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
-void LocationsBuilderX86_64::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
-void LocationsBuilderX86_64::VisitRor(HRor* ror) {
- HandleRotate(ror);
-}
-
-void InstructionCodeGeneratorX86_64::VisitRol(HRol* rol) {
- HandleRotate(rol);
-}
-
void LocationsBuilderX86_64::VisitShl(HShl* shl) {
HandleShift(shl);
}
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index b3eb1a0373..03b73abd62 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -247,7 +247,6 @@ class LocationsBuilderX86_64 : public HGraphVisitor {
void HandleBitwiseOperation(HBinaryOperation* operation);
void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* operation);
- void HandleRotate(HBinaryOperation* rotate);
void HandleFieldSet(HInstruction* instruction,
const FieldInfo& field_info,
WriteBarrierKind write_barrier_kind);
@@ -321,7 +320,6 @@ class InstructionCodeGeneratorX86_64 : public InstructionCodeGenerator {
void GenerateDivRemIntegral(HBinaryOperation* instruction);
void HandleCondition(HCondition* condition);
void HandleShift(HBinaryOperation* operation);
- void HandleRotate(HBinaryOperation* rotate);
void HandleFieldSet(HInstruction* instruction,
const FieldInfo& field_info,
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 82f98ed5ea..ad0d0fb2ca 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -1404,7 +1404,7 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
DataType::Type result_type = op->GetType();
// Type consistency between inputs.
- if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRol() || op->IsRor()) {
+ if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) {
if (DataType::Kind(rhs_type) != DataType::Type::kInt32) {
AddError(StringPrintf("Shift/rotate operation %s %d has a non-int kind second input: "
"%s of type %s.",
@@ -1428,7 +1428,7 @@ void GraphChecker::VisitBinaryOperation(HBinaryOperation* op) {
op->GetId(),
DataType::PrettyDescriptor(result_type)));
}
- } else if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRol() || op->IsRor()) {
+ } else if (op->IsUShr() || op->IsShr() || op->IsShl() || op->IsRor()) {
// Only check the first input (value), as the second one (distance)
// must invariably be of kind `int`.
if (result_type != DataType::Kind(lhs_type)) {
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 55e3267427..f3676bbc02 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -1953,16 +1953,14 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method,
ReceiverArg receiver_arg = method->IsStatic() ? ReceiverArg::kNone : ReceiverArg::kNullCheckedArg;
HInstruction* instruction = nullptr;
switch (intrinsic) {
- case Intrinsics::kIntegerRotateLeft:
- instruction = new (allocator_) HRol(kInt32, /*value=*/ nullptr, /*distance=*/ nullptr);
- break;
case Intrinsics::kIntegerRotateRight:
+ case Intrinsics::kIntegerRotateLeft:
+ // For rotate left, we negate the distance below.
instruction = new (allocator_) HRor(kInt32, /*value=*/ nullptr, /*distance=*/ nullptr);
break;
- case Intrinsics::kLongRotateLeft:
- instruction = new (allocator_) HRol(kInt64, /*value=*/ nullptr, /*distance=*/ nullptr);
- break;
case Intrinsics::kLongRotateRight:
+ case Intrinsics::kLongRotateLeft:
+ // For rotate left, we negate the distance below.
instruction = new (allocator_) HRor(kInt64, /*value=*/ nullptr, /*distance=*/ nullptr);
break;
case Intrinsics::kIntegerCompare:
@@ -2081,6 +2079,15 @@ bool HInstructionBuilder::BuildSimpleIntrinsic(ArtMethod* method,
}
switch (intrinsic) {
+ case Intrinsics::kIntegerRotateLeft:
+ case Intrinsics::kLongRotateLeft: {
+ // Negate the distance value for rotate left.
+ DCHECK(instruction->IsRor());
+ HNeg* neg = new (allocator_) HNeg(kInt32, instruction->InputAt(1u));
+ AppendInstruction(neg);
+ instruction->SetRawInputAt(1u, neg);
+ break;
+ }
case Intrinsics::kFloatIsNaN:
case Intrinsics::kDoubleIsNaN:
// Set the second input to be the same as first.
diff --git a/compiler/optimizing/instruction_simplifier_arm.cc b/compiler/optimizing/instruction_simplifier_arm.cc
index 7dccc036b5..a050f86363 100644
--- a/compiler/optimizing/instruction_simplifier_arm.cc
+++ b/compiler/optimizing/instruction_simplifier_arm.cc
@@ -74,7 +74,6 @@ class InstructionSimplifierArmVisitor final : public HGraphVisitor {
void VisitArraySet(HArraySet* instruction) override;
void VisitMul(HMul* instruction) override;
void VisitOr(HOr* instruction) override;
- void VisitRol(HRol* instruction) override;
void VisitShl(HShl* instruction) override;
void VisitShr(HShr* instruction) override;
void VisitSub(HSub* instruction) override;
@@ -264,11 +263,6 @@ void InstructionSimplifierArmVisitor::VisitOr(HOr* instruction) {
}
}
-void InstructionSimplifierArmVisitor::VisitRol(HRol* instruction) {
- UnfoldRotateLeft(instruction);
- RecordSimplification();
-}
-
void InstructionSimplifierArmVisitor::VisitShl(HShl* instruction) {
if (instruction->InputAt(1)->IsConstant()) {
TryMergeIntoUsersShifterOperand(instruction);
diff --git a/compiler/optimizing/instruction_simplifier_arm64.cc b/compiler/optimizing/instruction_simplifier_arm64.cc
index 8dd64e59ee..f57448d70f 100644
--- a/compiler/optimizing/instruction_simplifier_arm64.cc
+++ b/compiler/optimizing/instruction_simplifier_arm64.cc
@@ -77,7 +77,6 @@ class InstructionSimplifierArm64Visitor final : public HGraphVisitor {
void VisitArraySet(HArraySet* instruction) override;
void VisitMul(HMul* instruction) override;
void VisitOr(HOr* instruction) override;
- void VisitRol(HRol* instruction) override;
void VisitShl(HShl* instruction) override;
void VisitShr(HShr* instruction) override;
void VisitSub(HSub* instruction) override;
@@ -235,11 +234,6 @@ void InstructionSimplifierArm64Visitor::VisitOr(HOr* instruction) {
}
}
-void InstructionSimplifierArm64Visitor::VisitRol(HRol* rol) {
- UnfoldRotateLeft(rol);
- RecordSimplification();
-}
-
void InstructionSimplifierArm64Visitor::VisitShl(HShl* instruction) {
if (instruction->InputAt(1)->IsConstant()) {
TryMergeIntoUsersShifterOperand(instruction);
diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc
index 7f575c0348..b7d76da548 100644
--- a/compiler/optimizing/instruction_simplifier_shared.cc
+++ b/compiler/optimizing/instruction_simplifier_shared.cc
@@ -316,23 +316,4 @@ bool TryReplaceSubSubWithSubAdd(HSub* last_sub) {
}
}
-void UnfoldRotateLeft(HRol* rol) {
- HBasicBlock* block = rol->GetBlock();
- HGraph* graph = block->GetGraph();
- ArenaAllocator* allocator = graph->GetAllocator();
- HRor* ror;
-
- if (rol->GetRight()->IsConstant()) {
- int32_t value = rol->GetRight()->AsIntConstant()->GetValue();
- HIntConstant* negated = graph->GetIntConstant(-value);
- ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), negated);
- } else {
- HNeg* neg = new (allocator) HNeg(DataType::Type::kInt32, rol->GetRight());
- block->InsertInstructionBefore(neg, rol);
- ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), neg);
- }
-
- block->ReplaceAndRemoveInstructionWith(rol, ror);
-}
-
} // namespace art
diff --git a/compiler/optimizing/instruction_simplifier_shared.h b/compiler/optimizing/instruction_simplifier_shared.h
index 8e61109b0e..de70ec5a8a 100644
--- a/compiler/optimizing/instruction_simplifier_shared.h
+++ b/compiler/optimizing/instruction_simplifier_shared.h
@@ -77,14 +77,6 @@ bool TryExtractVecArrayAccessAddress(HVecMemoryOperation* access, HInstruction*
// Add(c, Sub(b, a))
bool TryReplaceSubSubWithSubAdd(HSub* last_sub);
-// ARM does not contain instruction ROL so replace
-// ROL dest, a, distance
-// with
-// NEG neg, distance
-// ROR dest, a, neg
-// before GVN to give it a chance to deduplicate the instructions, if it's able.
-void UnfoldRotateLeft(HRol* rol);
-
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_SHARED_H_
diff --git a/compiler/optimizing/instruction_simplifier_x86.cc b/compiler/optimizing/instruction_simplifier_x86.cc
index e1c783e5b8..5a4345d589 100644
--- a/compiler/optimizing/instruction_simplifier_x86.cc
+++ b/compiler/optimizing/instruction_simplifier_x86.cc
@@ -48,7 +48,6 @@ class InstructionSimplifierX86Visitor final : public HGraphVisitor {
}
void VisitAnd(HAnd * instruction) override;
- void VisitRol(HRol* instruction) override;
void VisitXor(HXor* instruction) override;
private:
@@ -58,10 +57,6 @@ class InstructionSimplifierX86Visitor final : public HGraphVisitor {
void InstructionSimplifierX86Visitor::VisitAnd(HAnd* instruction) {
- if (!HasAVX2()) {
- return;
- }
-
if (TryCombineAndNot(instruction)) {
RecordSimplification();
} else if (instruction->GetResultType() == DataType::Type::kInt32) {
@@ -71,26 +66,7 @@ void InstructionSimplifierX86Visitor::VisitAnd(HAnd* instruction) {
}
}
-void InstructionSimplifierX86Visitor::VisitRol(HRol* rol) {
- if (rol->GetType() != DataType::Type::kInt64) {
- return;
- }
-
- HBasicBlock* block = rol->GetBlock();
- HGraph* graph = block->GetGraph();
- ArenaAllocator* allocator = graph->GetAllocator();
-
- HNeg* neg = new (allocator) HNeg(DataType::Type::kInt32, rol->GetRight());
- block->InsertInstructionBefore(neg, rol);
- HRor* ror = new (allocator) HRor(rol->GetType(), rol->GetLeft(), neg);
- block->ReplaceAndRemoveInstructionWith(rol, ror);
-}
-
void InstructionSimplifierX86Visitor::VisitXor(HXor* instruction) {
- if (!HasAVX2()) {
- return;
- }
-
if (instruction->GetResultType() == DataType::Type::kInt32) {
if (TryGenerateMaskUptoLeastSetBit(instruction)) {
RecordSimplification();
@@ -100,8 +76,11 @@ void InstructionSimplifierX86Visitor::VisitXor(HXor* instruction) {
bool InstructionSimplifierX86::Run() {
InstructionSimplifierX86Visitor visitor(graph_, codegen_, stats_);
- visitor.VisitReversePostOrder();
- return true;
+ if (visitor.HasAVX2()) {
+ visitor.VisitReversePostOrder();
+ return true;
+ }
+ return false;
}
} // namespace x86
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 32ae89eeea..588f4d7ce2 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1829,7 +1829,7 @@ HConstant* HBinaryOperation::TryStaticEvaluation(HInstruction* left, HInstructio
} else if (left->IsLongConstant()) {
if (right->IsIntConstant()) {
// The binop(long, int) case is only valid for shifts and rotations.
- DCHECK(IsShl() || IsShr() || IsUShr() || IsRol() || IsRor()) << DebugName();
+ DCHECK(IsShl() || IsShr() || IsUShr() || IsRor()) << DebugName();
return Evaluate(left->AsLongConstant(), right->AsIntConstant());
} else if (right->IsLongConstant()) {
return Evaluate(left->AsLongConstant(), right->AsLongConstant());
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 2477c9fe51..eb6d9ecad4 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1593,7 +1593,6 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(Rem, BinaryOperation) \
M(Return, Instruction) \
M(ReturnVoid, Instruction) \
- M(Rol, BinaryOperation) \
M(Ror, BinaryOperation) \
M(Shl, BinaryOperation) \
M(Shr, BinaryOperation) \
@@ -5999,31 +5998,6 @@ class HRor final : public HBinaryOperation {
DEFAULT_COPY_CONSTRUCTOR(Ror);
};
-class HRol final : public HBinaryOperation {
- public:
- HRol(DataType::Type result_type, HInstruction* value, HInstruction* distance)
- : HBinaryOperation(kRol, result_type, value, distance) {}
-
- template <typename T>
- static T Compute(T value, int32_t distance, int32_t max_shift_value) {
- return HRor::Compute(value, -distance, max_shift_value);
- }
-
- HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
- return GetBlock()->GetGraph()->GetIntConstant(
- Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc());
- }
- HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override {
- return GetBlock()->GetGraph()->GetLongConstant(
- Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc());
- }
-
- DECLARE_INSTRUCTION(Rol);
-
- protected:
- DEFAULT_COPY_CONSTRUCTOR(Rol);
-};
-
// The value of a parameter in this method. Its location depends on
// the calling convention.
class HParameterValue final : public HExpression<0> {
diff --git a/test/567-checker-builder-intrinsics/src/TestRotate.java b/test/567-checker-builder-intrinsics/src/TestRotate.java
index 00a4fc6b60..2037ccf655 100644
--- a/test/567-checker-builder-intrinsics/src/TestRotate.java
+++ b/test/567-checker-builder-intrinsics/src/TestRotate.java
@@ -16,163 +16,76 @@
public class TestRotate {
- /// CHECK-START: int TestRotate.$inline$rotateLeftByte(byte, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftByte(byte, int) builder (after)
/// CHECK: <<ArgVal:b\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftByte(byte, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftByte(byte, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static int $inline$rotateLeftByte(byte value, int distance) {
+ private static int rotateLeftByte(byte value, int distance) {
return Integer.rotateLeft(value, distance);
}
- private static int $noinline$rotateLeftByte(byte value, int distance) {
- return Integer.rotateLeft(value, distance);
- }
-
- /// CHECK-START: int TestRotate.$inline$rotateLeftShort(short, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftShort(short, int) builder (after)
/// CHECK: <<ArgVal:s\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftShort(short, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftShort(short, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static int $inline$rotateLeftShort(short value, int distance) {
+ private static int rotateLeftShort(short value, int distance) {
return Integer.rotateLeft(value, distance);
}
- private static int $noinline$rotateLeftShort(short value, int distance) {
- return Integer.rotateLeft(value, distance);
- }
-
- /// CHECK-START: int TestRotate.$inline$rotateLeftChar(char, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftChar(char, int) builder (after)
/// CHECK: <<ArgVal:c\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftChar(char, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftChar(char, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static int $inline$rotateLeftChar(char value, int distance) {
- return Integer.rotateLeft(value, distance);
- }
-
- private static int $noinline$rotateLeftChar(char value, int distance) {
+ private static int rotateLeftChar(char value, int distance) {
return Integer.rotateLeft(value, distance);
}
- /// CHECK-START: int TestRotate.$inline$rotateLeftInt(int, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftInt(int, int) builder (after)
/// CHECK: <<ArgVal:i\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftInt(int, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftInt(int, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static int $inline$rotateLeftInt(int value, int distance) {
- return Integer.rotateLeft(value, distance);
- }
-
- /// CHECK-START-ARM64: int TestRotate.$noinline$rotateLeftInt(int, int) instruction_simplifier_arm64 (after)
- /// CHECK: <<ArgVal:i\d+>> ParameterValue
- /// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<neg:i\d+>> Neg [<<ArgDist>>]
- /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<neg>>]
- /// CHECK-DAG: Return [<<Result>>]
-
- /// CHECK-START-ARM64: int TestRotate.$noinline$rotateLeftInt(int, int) disassembly (after)
- /// CHECK: neg {{w\d+}}, {{w\d+}}
- /// CHECK: ror {{w\d+}}, {{w\d+}}, {{w\d+}}
-
- /// CHECK-START-RISCV64: int TestRotate.$noinline$rotateLeftInt(int, int) disassembly (after)
- /// CHECK: rol {{a\d+}}, {{a\d+}}, {{a\d+}}
-
- private static int $noinline$rotateLeftInt(int value, int distance) {
+ private static int rotateLeftInt(int value, int distance) {
return Integer.rotateLeft(value, distance);
}
- /// CHECK-START-ARM64: int TestRotate.$noinline$rotateLeftIntMulNegDistance(int, int) scheduler (before)
- /// CHECK: <<ArgVal:i\d+>> ParameterValue
- /// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<neg:i\d+>> Neg [<<ArgDist>>]
- /// CHECK-DAG: <<ror:i\d+>> Ror [<<ArgVal>>,<<neg>>]
- /// CHECK-DAG: <<Result:i\d+>> Mul [<<neg>>,<<ror>>]
- /// CHECK-DAG: Return [<<Result>>]
-
- private static int $noinline$rotateLeftIntMulNegDistance(int value, int distance) {
- return Integer.rotateLeft(value, distance) * -distance;
- }
-
- /// CHECK-START: int TestRotate.$noinline$rotateLeftIntConstant(int) builder (after)
- /// CHECK: <<ArgVal:i\d+>> ParameterValue
- /// CHECK: <<Constant:i\d+>> IntConstant 31
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<Constant>>]
- /// CHECK-DAG: Return [<<Result>>]
-
- /// CHECK-START-ARM64: int TestRotate.$noinline$rotateLeftIntConstant(int) disassembly (after)
- /// CHECK: ror {{w\d+}}, {{w\d+}}, #1
-
- /// CHECK-START-RISCV64: int TestRotate.$noinline$rotateLeftIntConstant(int) disassembly (after)
- /// CHECK: roriw {{a\d+}}, {{a\d+}}, 1
-
- private static int $noinline$rotateLeftIntConstant(int value) {
- return Integer.rotateLeft(value, 31);
- }
-
- /// CHECK-START: long TestRotate.$inline$rotateLeftLong(long, int) builder (after)
+ /// CHECK-START: long TestRotate.rotateLeftLong(long, int) builder (after)
/// CHECK: <<ArgVal:j\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:j\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: long TestRotate.$inline$rotateLeftLong(long, int) builder (after)
+ /// CHECK-START: long TestRotate.rotateLeftLong(long, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static long $inline$rotateLeftLong(long value, int distance) {
+ private static long rotateLeftLong(long value, int distance) {
return Long.rotateLeft(value, distance);
}
- /// CHECK-START-ARM64: long TestRotate.$noinline$rotateLeftLong(long, int) instruction_simplifier_arm64 (after)
- /// CHECK: <<ArgVal:j\d+>> ParameterValue
- /// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<neg:i\d+>> Neg [<<ArgDist>>]
- /// CHECK-DAG: <<Result:j\d+>> Ror [<<ArgVal>>,<<neg>>]
- /// CHECK-DAG: Return [<<Result>>]
-
- /// CHECK-START-ARM64: long TestRotate.$noinline$rotateLeftLong(long, int) disassembly (after)
- /// CHECK: neg {{w\d+}}, {{w\d+}}
- /// CHECK: ror {{x\d+}}, {{x\d+}}, {{x\d+}}
-
- /// CHECK-START-RISCV64: long TestRotate.$noinline$rotateLeftLong(long, int) disassembly (after)
- /// CHECK: rol {{a\d+}}, {{a\d+}}, {{a\d+}}
-
- private static long $noinline$rotateLeftLong(long value, int distance) {
- return Long.rotateLeft(value, distance);
- }
-
- /// CHECK-START: long TestRotate.$noinline$rotateLeftLongConstant(long) builder (after)
- /// CHECK: <<ArgVal:j\d+>> ParameterValue
- /// CHECK: <<Constant:i\d+>> IntConstant 63
- /// CHECK-DAG: <<Result:j\d+>> Rol [<<ArgVal>>,<<Constant>>]
- /// CHECK-DAG: Return [<<Result>>]
-
- /// CHECK-START-ARM64: long TestRotate.$noinline$rotateLeftLongConstant(long) disassembly (after)
- /// CHECK: ror {{x\d+}}, {{x\d+}}, #1
-
- /// CHECK-START-RISCV64: long TestRotate.$noinline$rotateLeftLongConstant(long) disassembly (after)
- /// CHECK: rori {{a\d+}}, {{a\d+}}, 1
-
- private static long $noinline$rotateLeftLongConstant(long value) {
- return Long.rotateLeft(value, 63);
- }
-
/// CHECK-START: int TestRotate.rotateRightByte(byte, int) builder (after)
/// CHECK: <<ArgVal:b\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
@@ -239,20 +152,17 @@ public class TestRotate {
}
- /// CHECK-START: int TestRotate.$inline$rotateLeftIntWithByteDistance(int, byte) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftIntWithByteDistance(int, byte) builder (after)
/// CHECK: <<ArgVal:i\d+>> ParameterValue
/// CHECK: <<ArgDist:b\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftIntWithByteDistance(int, byte) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftIntWithByteDistance(int, byte) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- private static int $inline$rotateLeftIntWithByteDistance(int value, byte distance) {
- return Integer.rotateLeft(value, distance);
- }
-
- private static int $noinline$rotateLeftIntWithByteDistance(int value, byte distance) {
+ private static int rotateLeftIntWithByteDistance(int value, byte distance) {
return Integer.rotateLeft(value, distance);
}
@@ -269,52 +179,43 @@ public class TestRotate {
return Integer.rotateRight(value, distance);
}
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) builder (after)
/// CHECK: <<ArgVal:z\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
/// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
/// CHECK-DAG: <<One:i\d+>> IntConstant 1
/// CHECK-DAG: <<Val:i\d+>> Phi [<<One>>,<<Zero>>]
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<Val>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<Val>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) builder (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) builder (after)
/// CHECK-NOT: InvokeStaticOrDirect
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) select_generator (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) select_generator (after)
/// CHECK: <<ArgVal:z\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
/// CHECK-DAG: <<Zero:i\d+>> IntConstant 0
/// CHECK-DAG: <<One:i\d+>> IntConstant 1
/// CHECK-DAG: <<SelVal:i\d+>> Select [<<Zero>>,<<One>>,<<ArgVal>>]
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<SelVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<SelVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) select_generator (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) select_generator (after)
/// CHECK-NOT: Phi
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) instruction_simplifier$before_codegen (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) instruction_simplifier$before_codegen (after)
/// CHECK: <<ArgVal:z\d+>> ParameterValue
/// CHECK: <<ArgDist:i\d+>> ParameterValue
- /// CHECK-DAG: <<Result:i\d+>> Rol [<<ArgVal>>,<<ArgDist>>]
+ /// CHECK-DAG: <<NegDist:i\d+>> Neg [<<ArgDist>>]
+ /// CHECK-DAG: <<Result:i\d+>> Ror [<<ArgVal>>,<<NegDist>>]
/// CHECK-DAG: Return [<<Result>>]
- /// CHECK-START: int TestRotate.$inline$rotateLeftBoolean(boolean, int) instruction_simplifier$before_codegen (after)
+ /// CHECK-START: int TestRotate.rotateLeftBoolean(boolean, int) instruction_simplifier$before_codegen (after)
/// CHECK-NOT: Select
- private static int $inline$rotateLeftBoolean(boolean value, int distance) {
- // Note: D8 would replace the ternary expression `value ? 1 : 0` with `value`
- // but explicit `if` is preserved.
- int src;
- if (value) {
- src = 1;
- } else {
- src = 0;
- }
- return Integer.rotateLeft(src, distance);
- }
-
- private static int $noinline$rotateLeftBoolean(boolean value, int distance) {
+ private static int rotateLeftBoolean(boolean value, int distance) {
// Note: D8 would replace the ternary expression `value ? 1 : 0` with `value`
// but explicit `if` is preserved.
int src;
@@ -329,184 +230,99 @@ public class TestRotate {
public static void testRotateLeftBoolean() {
for (int i = 0; i < 40; i++) { // overshoot a bit
int j = i & 31;
- expectEqualsInt(0, $inline$rotateLeftBoolean(false, i));
- expectEqualsInt(1 << j, $inline$rotateLeftBoolean(true, i));
-
- expectEqualsInt(0, $noinline$rotateLeftBoolean(false, i));
- expectEqualsInt(1 << j, $noinline$rotateLeftBoolean(true, i));
+ expectEqualsInt(0, rotateLeftBoolean(false, i));
+ expectEqualsInt(1 << j, rotateLeftBoolean(true, i));
}
}
public static void testRotateLeftByte() {
- expectEqualsInt(0x00000001, $inline$rotateLeftByte((byte)0x01, 0));
- expectEqualsInt(0x00000002, $inline$rotateLeftByte((byte)0x01, 1));
- expectEqualsInt(0x80000000, $inline$rotateLeftByte((byte)0x01, 31));
- expectEqualsInt(0x00000001, $inline$rotateLeftByte((byte)0x01, 32)); // overshoot
- expectEqualsInt(0xFFFFFF03, $inline$rotateLeftByte((byte)0x81, 1));
- expectEqualsInt(0xFFFFFE07, $inline$rotateLeftByte((byte)0x81, 2));
- expectEqualsInt(0x00000120, $inline$rotateLeftByte((byte)0x12, 4));
- expectEqualsInt(0xFFFF9AFF, $inline$rotateLeftByte((byte)0x9A, 8));
-
- expectEqualsInt(0x00000001, $noinline$rotateLeftByte((byte)0x01, 0));
- expectEqualsInt(0x00000002, $noinline$rotateLeftByte((byte)0x01, 1));
- expectEqualsInt(0x80000000, $noinline$rotateLeftByte((byte)0x01, 31));
- expectEqualsInt(0x00000001, $noinline$rotateLeftByte((byte)0x01, 32)); // overshoot
- expectEqualsInt(0xFFFFFF03, $noinline$rotateLeftByte((byte)0x81, 1));
- expectEqualsInt(0xFFFFFE07, $noinline$rotateLeftByte((byte)0x81, 2));
- expectEqualsInt(0x00000120, $noinline$rotateLeftByte((byte)0x12, 4));
- expectEqualsInt(0xFFFF9AFF, $noinline$rotateLeftByte((byte)0x9A, 8));
-
+ expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 0));
+ expectEqualsInt(0x00000002, rotateLeftByte((byte)0x01, 1));
+ expectEqualsInt(0x80000000, rotateLeftByte((byte)0x01, 31));
+ expectEqualsInt(0x00000001, rotateLeftByte((byte)0x01, 32)); // overshoot
+ expectEqualsInt(0xFFFFFF03, rotateLeftByte((byte)0x81, 1));
+ expectEqualsInt(0xFFFFFE07, rotateLeftByte((byte)0x81, 2));
+ expectEqualsInt(0x00000120, rotateLeftByte((byte)0x12, 4));
+ expectEqualsInt(0xFFFF9AFF, rotateLeftByte((byte)0x9A, 8));
for (int i = 0; i < 40; i++) { // overshoot a bit
int j = i & 31;
- expectEqualsInt(0x00000000, $inline$rotateLeftByte((byte)0x0000, i));
- expectEqualsInt(0xFFFFFFFF, $inline$rotateLeftByte((byte)0xFFFF, i));
- expectEqualsInt((1 << j), $inline$rotateLeftByte((byte)0x0001, i));
- expectEqualsInt((0x12 << j) | (0x12 >>> -j), $inline$rotateLeftByte((byte)0x12, i));
-
- expectEqualsInt(0x00000000, $noinline$rotateLeftByte((byte)0x0000, i));
- expectEqualsInt(0xFFFFFFFF, $noinline$rotateLeftByte((byte)0xFFFF, i));
- expectEqualsInt((1 << j), $noinline$rotateLeftByte((byte)0x0001, i));
- expectEqualsInt((0x12 << j) | (0x12 >>> -j), $noinline$rotateLeftByte((byte)0x12, i));
+ expectEqualsInt(0x00000000, rotateLeftByte((byte)0x0000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftByte((byte)0xFFFF, i));
+ expectEqualsInt((1 << j), rotateLeftByte((byte)0x0001, i));
+ expectEqualsInt((0x12 << j) | (0x12 >>> -j), rotateLeftByte((byte)0x12, i));
}
}
public static void testRotateLeftShort() {
- expectEqualsInt(0x00000001, $inline$rotateLeftShort((short)0x0001, 0));
- expectEqualsInt(0x00000002, $inline$rotateLeftShort((short)0x0001, 1));
- expectEqualsInt(0x80000000, $inline$rotateLeftShort((short)0x0001, 31));
- expectEqualsInt(0x00000001, $inline$rotateLeftShort((short)0x0001, 32)); // overshoot
- expectEqualsInt(0xFFFF0003, $inline$rotateLeftShort((short)0x8001, 1));
- expectEqualsInt(0xFFFE0007, $inline$rotateLeftShort((short)0x8001, 2));
- expectEqualsInt(0x00012340, $inline$rotateLeftShort((short)0x1234, 4));
- expectEqualsInt(0xFF9ABCFF, $inline$rotateLeftShort((short)0x9ABC, 8));
-
- expectEqualsInt(0x00000001, $noinline$rotateLeftShort((short)0x0001, 0));
- expectEqualsInt(0x00000002, $noinline$rotateLeftShort((short)0x0001, 1));
- expectEqualsInt(0x80000000, $noinline$rotateLeftShort((short)0x0001, 31));
- expectEqualsInt(0x00000001, $noinline$rotateLeftShort((short)0x0001, 32)); // overshoot
- expectEqualsInt(0xFFFF0003, $noinline$rotateLeftShort((short)0x8001, 1));
- expectEqualsInt(0xFFFE0007, $noinline$rotateLeftShort((short)0x8001, 2));
- expectEqualsInt(0x00012340, $noinline$rotateLeftShort((short)0x1234, 4));
- expectEqualsInt(0xFF9ABCFF, $noinline$rotateLeftShort((short)0x9ABC, 8));
-
+ expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 0));
+ expectEqualsInt(0x00000002, rotateLeftShort((short)0x0001, 1));
+ expectEqualsInt(0x80000000, rotateLeftShort((short)0x0001, 31));
+ expectEqualsInt(0x00000001, rotateLeftShort((short)0x0001, 32)); // overshoot
+ expectEqualsInt(0xFFFF0003, rotateLeftShort((short)0x8001, 1));
+ expectEqualsInt(0xFFFE0007, rotateLeftShort((short)0x8001, 2));
+ expectEqualsInt(0x00012340, rotateLeftShort((short)0x1234, 4));
+ expectEqualsInt(0xFF9ABCFF, rotateLeftShort((short)0x9ABC, 8));
for (int i = 0; i < 40; i++) { // overshoot a bit
int j = i & 31;
- expectEqualsInt(0x00000000, $inline$rotateLeftShort((short)0x0000, i));
- expectEqualsInt(0xFFFFFFFF, $inline$rotateLeftShort((short)0xFFFF, i));
- expectEqualsInt((1 << j), $inline$rotateLeftShort((short)0x0001, i));
- expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), $inline$rotateLeftShort((short)0x1234, i));
-
- expectEqualsInt(0x00000000, $noinline$rotateLeftShort((short)0x0000, i));
- expectEqualsInt(0xFFFFFFFF, $noinline$rotateLeftShort((short)0xFFFF, i));
- expectEqualsInt((1 << j), $noinline$rotateLeftShort((short)0x0001, i));
- expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), $noinline$rotateLeftShort((short)0x1234, i));
+ expectEqualsInt(0x00000000, rotateLeftShort((short)0x0000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftShort((short)0xFFFF, i));
+ expectEqualsInt((1 << j), rotateLeftShort((short)0x0001, i));
+ expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftShort((short)0x1234, i));
}
}
public static void testRotateLeftChar() {
- expectEqualsInt(0x00000001, $inline$rotateLeftChar((char)0x0001, 0));
- expectEqualsInt(0x00000002, $inline$rotateLeftChar((char)0x0001, 1));
- expectEqualsInt(0x80000000, $inline$rotateLeftChar((char)0x0001, 31));
- expectEqualsInt(0x00000001, $inline$rotateLeftChar((char)0x0001, 32)); // overshoot
- expectEqualsInt(0x00010002, $inline$rotateLeftChar((char)0x8001, 1));
- expectEqualsInt(0x00020004, $inline$rotateLeftChar((char)0x8001, 2));
- expectEqualsInt(0x00012340, $inline$rotateLeftChar((char)0x1234, 4));
- expectEqualsInt(0x009ABC00, $inline$rotateLeftChar((char)0x9ABC, 8));
- expectEqualsInt(0x00FF0000, $inline$rotateLeftChar((char)0xFF00, 8));
-
- expectEqualsInt(0x00000001, $noinline$rotateLeftChar((char)0x0001, 0));
- expectEqualsInt(0x00000002, $noinline$rotateLeftChar((char)0x0001, 1));
- expectEqualsInt(0x80000000, $noinline$rotateLeftChar((char)0x0001, 31));
- expectEqualsInt(0x00000001, $noinline$rotateLeftChar((char)0x0001, 32)); // overshoot
- expectEqualsInt(0x00010002, $noinline$rotateLeftChar((char)0x8001, 1));
- expectEqualsInt(0x00020004, $noinline$rotateLeftChar((char)0x8001, 2));
- expectEqualsInt(0x00012340, $noinline$rotateLeftChar((char)0x1234, 4));
- expectEqualsInt(0x009ABC00, $noinline$rotateLeftChar((char)0x9ABC, 8));
- expectEqualsInt(0x00FF0000, $noinline$rotateLeftChar((char)0xFF00, 8));
-
+ expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 0));
+ expectEqualsInt(0x00000002, rotateLeftChar((char)0x0001, 1));
+ expectEqualsInt(0x80000000, rotateLeftChar((char)0x0001, 31));
+ expectEqualsInt(0x00000001, rotateLeftChar((char)0x0001, 32)); // overshoot
+ expectEqualsInt(0x00010002, rotateLeftChar((char)0x8001, 1));
+ expectEqualsInt(0x00020004, rotateLeftChar((char)0x8001, 2));
+ expectEqualsInt(0x00012340, rotateLeftChar((char)0x1234, 4));
+ expectEqualsInt(0x009ABC00, rotateLeftChar((char)0x9ABC, 8));
+ expectEqualsInt(0x00FF0000, rotateLeftChar((char)0xFF00, 8));
for (int i = 0; i < 40; i++) { // overshoot a bit
int j = i & 31;
- expectEqualsInt(0x00000000, $inline$rotateLeftChar((char)0x0000, i));
- expectEqualsInt((1 << j), $inline$rotateLeftChar((char)0x0001, i));
- expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), $inline$rotateLeftChar((char)0x1234, i));
-
- expectEqualsInt(0x00000000, $noinline$rotateLeftChar((char)0x0000, i));
- expectEqualsInt((1 << j), $noinline$rotateLeftChar((char)0x0001, i));
- expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), $noinline$rotateLeftChar((char)0x1234, i));
+ expectEqualsInt(0x00000000, rotateLeftChar((char)0x0000, i));
+ expectEqualsInt((1 << j), rotateLeftChar((char)0x0001, i));
+ expectEqualsInt((0x1234 << j) | (0x1234 >>> -j), rotateLeftChar((char)0x1234, i));
}
}
public static void testRotateLeftInt() {
- expectEqualsInt(0x00000001, $inline$rotateLeftInt(0x00000001, 0));
- expectEqualsInt(0x00000002, $inline$rotateLeftInt(0x00000001, 1));
- expectEqualsInt(0x80000000, $inline$rotateLeftInt(0x00000001, 31));
- expectEqualsInt(0x00000001, $inline$rotateLeftInt(0x00000001, 32)); // overshoot
- expectEqualsInt(0x00000003, $inline$rotateLeftInt(0x80000001, 1));
- expectEqualsInt(0x00000006, $inline$rotateLeftInt(0x80000001, 2));
- expectEqualsInt(0x23456781, $inline$rotateLeftInt(0x12345678, 4));
- expectEqualsInt(0xBCDEF09A, $inline$rotateLeftInt(0x9ABCDEF0, 8));
-
- expectEqualsInt(0x00000001, $noinline$rotateLeftInt(0x00000001, 0));
- expectEqualsInt(0x00000002, $noinline$rotateLeftInt(0x00000001, 1));
- expectEqualsInt(0x80000000, $noinline$rotateLeftInt(0x00000001, 31));
- expectEqualsInt(0x00000001, $noinline$rotateLeftInt(0x00000001, 32)); // overshoot
- expectEqualsInt(0x00000003, $noinline$rotateLeftInt(0x80000001, 1));
- expectEqualsInt(0x00000006, $noinline$rotateLeftInt(0x80000001, 2));
- expectEqualsInt(0x23456781, $noinline$rotateLeftInt(0x12345678, 4));
- expectEqualsInt(0xBCDEF09A, $noinline$rotateLeftInt(0x9ABCDEF0, 8));
- expectEqualsInt(0x80000000, $noinline$rotateLeftIntConstant(0x00000001));
- expectEqualsInt(Integer.MIN_VALUE, $noinline$rotateLeftIntMulNegDistance(1, -2));
-
+ expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 0));
+ expectEqualsInt(0x00000002, rotateLeftInt(0x00000001, 1));
+ expectEqualsInt(0x80000000, rotateLeftInt(0x00000001, 31));
+ expectEqualsInt(0x00000001, rotateLeftInt(0x00000001, 32)); // overshoot
+ expectEqualsInt(0x00000003, rotateLeftInt(0x80000001, 1));
+ expectEqualsInt(0x00000006, rotateLeftInt(0x80000001, 2));
+ expectEqualsInt(0x23456781, rotateLeftInt(0x12345678, 4));
+ expectEqualsInt(0xBCDEF09A, rotateLeftInt(0x9ABCDEF0, 8));
for (int i = 0; i < 40; i++) { // overshoot a bit
int j = i & 31;
- expectEqualsInt(0x00000000, $inline$rotateLeftInt(0x00000000, i));
- expectEqualsInt(0xFFFFFFFF, $inline$rotateLeftInt(0xFFFFFFFF, i));
- expectEqualsInt(1 << j, $inline$rotateLeftInt(0x00000001, i));
- expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j),
- $inline$rotateLeftInt(0x12345678, i));
-
- expectEqualsInt(0x00000000, $noinline$rotateLeftInt(0x00000000, i));
- expectEqualsInt(0xFFFFFFFF, $noinline$rotateLeftInt(0xFFFFFFFF, i));
- expectEqualsInt(1 << j, $noinline$rotateLeftInt(0x00000001, i));
- expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j),
- $noinline$rotateLeftInt(0x12345678, i));
+ expectEqualsInt(0x00000000, rotateLeftInt(0x00000000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftInt(0xFFFFFFFF, i));
+ expectEqualsInt(1 << j, rotateLeftInt(0x00000001, i));
+ expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j), rotateLeftInt(0x12345678, i));
}
}
public static void testRotateLeftLong() {
- expectEqualsLong(0x0000000000000001L, $inline$rotateLeftLong(0x0000000000000001L, 0));
- expectEqualsLong(0x0000000000000002L, $inline$rotateLeftLong(0x0000000000000001L, 1));
- expectEqualsLong(0x8000000000000000L, $inline$rotateLeftLong(0x0000000000000001L, 63));
- expectEqualsLong(0x8000000000000000L, $noinline$rotateLeftLongConstant(0x0000000000000001L));
- expectEqualsLong(0x0000000000000001L,
- $inline$rotateLeftLong(0x0000000000000001L, 64)); // overshoot
- expectEqualsLong(0x0000000000000003L, $inline$rotateLeftLong(0x8000000000000001L, 1));
- expectEqualsLong(0x0000000000000006L, $inline$rotateLeftLong(0x8000000000000001L, 2));
- expectEqualsLong(0x23456789ABCDEF01L, $inline$rotateLeftLong(0x123456789ABCDEF0L, 4));
- expectEqualsLong(0x3456789ABCDEF012L, $inline$rotateLeftLong(0x123456789ABCDEF0L, 8));
-
- expectEqualsLong(0x0000000000000001L, $noinline$rotateLeftLong(0x0000000000000001L, 0));
- expectEqualsLong(0x0000000000000002L, $noinline$rotateLeftLong(0x0000000000000001L, 1));
- expectEqualsLong(0x8000000000000000L, $noinline$rotateLeftLong(0x0000000000000001L, 63));
- expectEqualsLong(0x0000000000000001L,
- $noinline$rotateLeftLong(0x0000000000000001L, 64)); // overshoot
- expectEqualsLong(0x0000000000000003L, $noinline$rotateLeftLong(0x8000000000000001L, 1));
- expectEqualsLong(0x0000000000000006L, $noinline$rotateLeftLong(0x8000000000000001L, 2));
- expectEqualsLong(0x23456789ABCDEF01L, $noinline$rotateLeftLong(0x123456789ABCDEF0L, 4));
- expectEqualsLong(0x3456789ABCDEF012L, $noinline$rotateLeftLong(0x123456789ABCDEF0L, 8));
+ expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 0));
+ expectEqualsLong(0x0000000000000002L, rotateLeftLong(0x0000000000000001L, 1));
+ expectEqualsLong(0x8000000000000000L, rotateLeftLong(0x0000000000000001L, 63));
+ expectEqualsLong(0x0000000000000001L, rotateLeftLong(0x0000000000000001L, 64)); // overshoot
+ expectEqualsLong(0x0000000000000003L, rotateLeftLong(0x8000000000000001L, 1));
+ expectEqualsLong(0x0000000000000006L, rotateLeftLong(0x8000000000000001L, 2));
+ expectEqualsLong(0x23456789ABCDEF01L, rotateLeftLong(0x123456789ABCDEF0L, 4));
+ expectEqualsLong(0x3456789ABCDEF012L, rotateLeftLong(0x123456789ABCDEF0L, 8));
for (int i = 0; i < 70; i++) { // overshoot a bit
int j = i & 63;
- expectEqualsLong(0x0000000000000000L, $inline$rotateLeftLong(0x0000000000000000L, i));
- expectEqualsLong(0xFFFFFFFFFFFFFFFFL, $inline$rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i));
- expectEqualsLong(1L << j, $inline$rotateLeftLong(0x0000000000000001, i));
- expectEqualsLong((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
- $inline$rotateLeftLong(0x123456789ABCDEF0L, i));
-
- expectEqualsLong(0x0000000000000000L, $noinline$rotateLeftLong(0x0000000000000000L, i));
- expectEqualsLong(0xFFFFFFFFFFFFFFFFL, $noinline$rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i));
- expectEqualsLong(1L << j, $noinline$rotateLeftLong(0x0000000000000001, i));
+ expectEqualsLong(0x0000000000000000L, rotateLeftLong(0x0000000000000000L, i));
+ expectEqualsLong(0xFFFFFFFFFFFFFFFFL, rotateLeftLong(0xFFFFFFFFFFFFFFFFL, i));
+ expectEqualsLong(1L << j, rotateLeftLong(0x0000000000000001, i));
expectEqualsLong((0x123456789ABCDEF0L << j) | (0x123456789ABCDEF0L >>> -j),
- $noinline$rotateLeftLong(0x123456789ABCDEF0L, i));
+ rotateLeftLong(0x123456789ABCDEF0L, i));
}
}
@@ -655,39 +471,21 @@ public class TestRotate {
public static void testRotateLeftIntWithByteDistance() {
- expectEqualsInt(0x00000001, $inline$rotateLeftIntWithByteDistance(0x00000001, (byte)0));
- expectEqualsInt(0x00000002, $inline$rotateLeftIntWithByteDistance(0x00000001, (byte)1));
- expectEqualsInt(0x80000000, $inline$rotateLeftIntWithByteDistance(0x00000001, (byte)31));
- expectEqualsInt(0x00000001,
- $inline$rotateLeftIntWithByteDistance(0x00000001, (byte)32)); // overshoot
- expectEqualsInt(0x00000003, $inline$rotateLeftIntWithByteDistance(0x80000001, (byte)1));
- expectEqualsInt(0x00000006, $inline$rotateLeftIntWithByteDistance(0x80000001, (byte)2));
- expectEqualsInt(0x23456781, $inline$rotateLeftIntWithByteDistance(0x12345678, (byte)4));
- expectEqualsInt(0xBCDEF09A, $inline$rotateLeftIntWithByteDistance(0x9ABCDEF0, (byte)8));
-
- expectEqualsInt(0x00000001, $noinline$rotateLeftIntWithByteDistance(0x00000001, (byte)0));
- expectEqualsInt(0x00000002, $noinline$rotateLeftIntWithByteDistance(0x00000001, (byte)1));
- expectEqualsInt(0x80000000, $noinline$rotateLeftIntWithByteDistance(0x00000001, (byte)31));
- expectEqualsInt(0x00000001,
- $noinline$rotateLeftIntWithByteDistance(0x00000001, (byte)32)); // overshoot
- expectEqualsInt(0x00000003, $noinline$rotateLeftIntWithByteDistance(0x80000001, (byte)1));
- expectEqualsInt(0x00000006, $noinline$rotateLeftIntWithByteDistance(0x80000001, (byte)2));
- expectEqualsInt(0x23456781, $noinline$rotateLeftIntWithByteDistance(0x12345678, (byte)4));
- expectEqualsInt(0xBCDEF09A, $noinline$rotateLeftIntWithByteDistance(0x9ABCDEF0, (byte)8));
-
+ expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)0));
+ expectEqualsInt(0x00000002, rotateLeftIntWithByteDistance(0x00000001, (byte)1));
+ expectEqualsInt(0x80000000, rotateLeftIntWithByteDistance(0x00000001, (byte)31));
+ expectEqualsInt(0x00000001, rotateLeftIntWithByteDistance(0x00000001, (byte)32)); // overshoot
+ expectEqualsInt(0x00000003, rotateLeftIntWithByteDistance(0x80000001, (byte)1));
+ expectEqualsInt(0x00000006, rotateLeftIntWithByteDistance(0x80000001, (byte)2));
+ expectEqualsInt(0x23456781, rotateLeftIntWithByteDistance(0x12345678, (byte)4));
+ expectEqualsInt(0xBCDEF09A, rotateLeftIntWithByteDistance(0x9ABCDEF0, (byte)8));
for (byte i = 0; i < 40; i++) { // overshoot a bit
byte j = (byte)(i & 31);
- expectEqualsInt(0x00000000, $inline$rotateLeftIntWithByteDistance(0x00000000, i));
- expectEqualsInt(0xFFFFFFFF, $inline$rotateLeftIntWithByteDistance(0xFFFFFFFF, i));
- expectEqualsInt(1 << j, $inline$rotateLeftIntWithByteDistance(0x00000001, i));
- expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j),
- $inline$rotateLeftIntWithByteDistance(0x12345678, i));
-
- expectEqualsInt(0x00000000, $noinline$rotateLeftIntWithByteDistance(0x00000000, i));
- expectEqualsInt(0xFFFFFFFF, $noinline$rotateLeftIntWithByteDistance(0xFFFFFFFF, i));
- expectEqualsInt(1 << j, $noinline$rotateLeftIntWithByteDistance(0x00000001, i));
+ expectEqualsInt(0x00000000, rotateLeftIntWithByteDistance(0x00000000, i));
+ expectEqualsInt(0xFFFFFFFF, rotateLeftIntWithByteDistance(0xFFFFFFFF, i));
+ expectEqualsInt(1 << j, rotateLeftIntWithByteDistance(0x00000001, i));
expectEqualsInt((0x12345678 << j) | (0x12345678 >>> -j),
- $noinline$rotateLeftIntWithByteDistance(0x12345678, i));
+ rotateLeftIntWithByteDistance(0x12345678, i));
}
}
@@ -695,8 +493,7 @@ public class TestRotate {
expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)0));
expectEqualsInt(0x40000000, rotateRightIntWithByteDistance(0x80000000, (byte)1));
expectEqualsInt(0x00000001, rotateRightIntWithByteDistance(0x80000000, (byte)31));
- expectEqualsInt(0x80000000,
- rotateRightIntWithByteDistance(0x80000000, (byte)32)); // overshoot
+ expectEqualsInt(0x80000000, rotateRightIntWithByteDistance(0x80000000, (byte)32)); // overshoot
expectEqualsInt(0xC0000000, rotateRightIntWithByteDistance(0x80000001, (byte)1));
expectEqualsInt(0x60000000, rotateRightIntWithByteDistance(0x80000001, (byte)2));
expectEqualsInt(0x81234567, rotateRightIntWithByteDistance(0x12345678, (byte)4));