PPC/s390: Support Int64MulWithOverflow

Port 78570f7826

Original Commit Message:

    This CL implemented Int64MulWithOverflow on x64 and arm64
    to support type feedback collection for BigInt64 multiplication.

R=panq@google.com, joransiu@ca.ibm.com, junyan@redhat.com, midawson@redhat.com
BUG=
LOG=N

Change-Id: Ieda7f5f3619c9280bc777f21bab1a66716d8e36e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3945132
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#83634}
This commit is contained in:
Milad Fa 2022-10-11 10:42:27 -04:00 committed by V8 LUCI CQ
parent 45106e33d0
commit 2488755c4d
5 changed files with 79 additions and 0 deletions

View File

@ -1109,6 +1109,23 @@ void EmitInt32MulWithOverflow(InstructionSelector* selector, Node* node,
VisitCompare(selector, kPPC_Cmp32, high32_operand, temp_operand, cont);
}
void EmitInt64MulWithOverflow(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
PPCOperandGenerator g(selector);
Int64BinopMatcher m(node);
InstructionOperand result = g.DefineAsRegister(node);
InstructionOperand left = g.UseRegister(m.left().node());
InstructionOperand high = g.TempRegister();
InstructionOperand result_sign = g.TempRegister();
InstructionOperand right = g.UseRegister(m.right().node());
selector->Emit(kPPC_Mul64, result, left, right);
selector->Emit(kPPC_MulHighS64, high, left, right);
selector->Emit(kPPC_ShiftRightAlg64, result_sign, result,
g.TempImmediate(63));
// Test whether {high} is a sign-extension of {result}.
selector->EmitWithContinuation(kPPC_Cmp64, high, result_sign, cont);
}
} // namespace
void InstructionSelector::VisitInt32Mul(Node* node) {
@ -1554,6 +1571,15 @@ void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
FlagsContinuation cont;
VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, &cont);
}
void InstructionSelector::VisitInt64MulWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf);
return EmitInt64MulWithOverflow(this, node, &cont);
}
FlagsContinuation cont;
EmitInt64MulWithOverflow(this, node, &cont);
}
#endif
static bool CompareLogical(FlagsContinuation* cont) {
@ -1734,6 +1760,9 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub,
kInt16Imm_Negate, cont);
case IrOpcode::kInt64MulWithOverflow:
cont->OverwriteAndNegateIfEqual(kNotEqual);
return EmitInt64MulWithOverflow(this, node, cont);
#endif
default:
break;

View File

@ -306,6 +306,7 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
case kS390_Abs64:
case kS390_Abs32:
case kS390_Mul32:
case kS390_Mul64WithOverflow:
return overflow;
default:
break;
@ -1695,6 +1696,21 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kS390_Mul64:
ASSEMBLE_BIN_OP(RRInstr(MulS64), RM64Instr(MulS64), RIInstr(MulS64));
break;
case kS390_Mul64WithOverflow: {
Register dst = i.OutputRegister(), src1 = i.InputRegister(0),
src2 = i.InputRegister(1);
DCHECK(!AreAliased(dst, src1, src2));
if (CpuFeatures::IsSupported(MISC_INSTR_EXT2)) {
__ msgrkc(dst, src1, src2);
} else {
__ mgrk(r0, src1, src2); // r0 = high 64-bits, r1 = low 64-bits.
__ lgr(dst, r1);
__ ShiftRightS64(r1, r1, Operand(63));
// Test whether {high} is a sign-extension of {result}.
__ CmpU64(r0, r1);
}
break;
}
case kS390_MulHigh32:
// zero-ext
ASSEMBLE_BIN_OP(RRRInstr(MulHighS32), RRM32Instr(MulHighS32),

View File

@ -47,6 +47,7 @@ namespace compiler {
V(S390_Mul32) \
V(S390_Mul32WithOverflow) \
V(S390_Mul64) \
V(S390_Mul64WithOverflow) \
V(S390_MulHighS64) \
V(S390_MulHighU64) \
V(S390_MulHigh32) \

View File

@ -46,6 +46,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_Mul32:
case kS390_Mul32WithOverflow:
case kS390_Mul64:
case kS390_Mul64WithOverflow:
case kS390_MulHighS64:
case kS390_MulHighU64:
case kS390_MulHigh32:

View File

@ -1259,6 +1259,23 @@ static inline bool TryMatchInt64SubWithOverflow(InstructionSelector* selector,
return TryMatchInt64OpWithOverflow<kS390_Sub64>(selector, node,
SubOperandMode);
}
void EmitInt64MulWithOverflow(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
S390OperandGenerator g(selector);
Int64BinopMatcher m(node);
InstructionOperand inputs[2];
size_t input_count = 0;
InstructionOperand outputs[1];
size_t output_count = 0;
inputs[input_count++] = g.UseUniqueRegister(m.left().node());
inputs[input_count++] = g.UseUniqueRegister(m.right().node());
outputs[output_count++] = g.DefineAsRegister(node);
selector->EmitWithContinuation(kS390_Mul64WithOverflow, output_count, outputs,
input_count, inputs, cont);
}
#endif
static inline bool TryMatchDoubleConstructFromInsert(
@ -1587,6 +1604,16 @@ void InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
->MarkAsCall();
}
void InstructionSelector::VisitInt64MulWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(
CpuFeatures::IsSupported(MISC_INSTR_EXT2) ? kOverflow : kNotEqual, ovf);
return EmitInt64MulWithOverflow(this, node, &cont);
}
FlagsContinuation cont;
EmitInt64MulWithOverflow(this, node, &cont);
}
static bool CompareLogical(FlagsContinuation* cont) {
switch (cont->condition()) {
case kUnsignedLessThan:
@ -1904,6 +1931,11 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitWord64BinOp(this, node, kS390_Sub64, SubOperandMode,
cont);
case IrOpcode::kInt64MulWithOverflow:
cont->OverwriteAndNegateIfEqual(
CpuFeatures::IsSupported(MISC_INSTR_EXT2) ? kOverflow
: kNotEqual);
return EmitInt64MulWithOverflow(this, node, cont);
#endif
default:
break;