Commit 7f19628a authored by ahaas's avatar ahaas Committed by Commit bot

[wasm] Int64Lowering of Word64Ctz.

R=titzer@chromium.org

Review URL: https://codereview.chromium.org/1806593003

Cr-Commit-Position: refs/heads/master@{#34811}
parent b82e10d3
...@@ -542,6 +542,26 @@ void Int64Lowering::LowerNode(Node* node) { ...@@ -542,6 +542,26 @@ void Int64Lowering::LowerNode(Node* node) {
break; break;
} }
// kExprI64Ctz: // kExprI64Ctz:
case IrOpcode::kWord64Ctz: {
DCHECK(node->InputCount() == 1);
DCHECK(machine()->Word32Ctz().IsSupported());
Node* input = node->InputAt(0);
Diamond d(
graph(), common(),
graph()->NewNode(machine()->Word32Equal(), GetReplacementLow(input),
graph()->NewNode(common()->Int32Constant(0))));
Node* low_node =
d.Phi(MachineRepresentation::kWord32,
graph()->NewNode(machine()->Int32Add(),
graph()->NewNode(machine()->Word32Ctz().op(),
GetReplacementHigh(input)),
graph()->NewNode(common()->Int32Constant(32))),
graph()->NewNode(machine()->Word32Ctz().op(),
GetReplacementLow(input)));
ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
break;
}
// kExprI64Popcnt:
case IrOpcode::kWord64Popcnt: { case IrOpcode::kWord64Popcnt: {
DCHECK(node->InputCount() == 1); DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0); Node* input = node->InputAt(0);
...@@ -557,7 +577,6 @@ void Int64Lowering::LowerNode(Node* node) { ...@@ -557,7 +577,6 @@ void Int64Lowering::LowerNode(Node* node) {
graph()->NewNode(common()->Int32Constant(0))); graph()->NewNode(common()->Int32Constant(0)));
break; break;
} }
// kExprI64Popcnt:
default: { DefaultLowering(node); } default: { DefaultLowering(node); }
} }
......
...@@ -478,6 +478,13 @@ const Operator* MachineOperatorBuilder::CheckedStore( ...@@ -478,6 +478,13 @@ const Operator* MachineOperatorBuilder::CheckedStore(
const Operator* MachineOperatorBuilder::Word64PopcntPlaceholder() { const Operator* MachineOperatorBuilder::Word64PopcntPlaceholder() {
return &cache_.kWord64Popcnt; return &cache_.kWord64Popcnt;
} }
// On 32 bit platforms we need to get a reference to optional operators of
// 64-bit instructions for later Int64Lowering, even though 32 bit platforms
// don't support the original 64-bit instruction.
const Operator* MachineOperatorBuilder::Word64CtzPlaceholder() {
return &cache_.kWord64Ctz;
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -178,6 +178,7 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -178,6 +178,7 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* Word64Ror(); const Operator* Word64Ror();
const Operator* Word64Clz(); const Operator* Word64Clz();
const OptionalOperator Word64Ctz(); const OptionalOperator Word64Ctz();
const Operator* Word64CtzPlaceholder();
const Operator* Word64Equal(); const Operator* Word64Equal();
const Operator* Int32PairAdd(); const Operator* Int32PairAdd();
......
...@@ -842,6 +842,21 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { ...@@ -842,6 +842,21 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
op = m->Word64Clz(); op = m->Word64Clz();
break; break;
// kExprI64Ctz: // kExprI64Ctz:
case wasm::kExprI64Ctz: {
if (m->Word64Ctz().IsSupported()) {
op = m->Word64Ctz().op();
break;
} else if (m->Is32() && m->Word32Ctz().IsSupported()) {
op = m->Word64CtzPlaceholder();
break;
} else if (m->Word64ReverseBits().IsSupported()) {
Node* reversed = graph()->NewNode(m->Word64ReverseBits().op(), input);
Node* result = graph()->NewNode(m->Word64Clz(), reversed);
return result;
} else {
return BuildI64Ctz(input);
}
}
// kExprI64Popcnt: // kExprI64Popcnt:
case wasm::kExprI64Popcnt: { case wasm::kExprI64Popcnt: {
if (m->Word64Popcnt().IsSupported()) { if (m->Word64Popcnt().IsSupported()) {
...@@ -900,22 +915,6 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { ...@@ -900,22 +915,6 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
case wasm::kExprI64UConvertF64: { case wasm::kExprI64UConvertF64: {
return BuildI64UConvertF64(input); return BuildI64UConvertF64(input);
} }
#if WASM_64
// Opcodes only supported on 64-bit platforms.
// TODO(titzer): query the machine operator builder here instead of #ifdef.
case wasm::kExprI64Ctz: {
if (m->Word64Ctz().IsSupported()) {
op = m->Word64Ctz().op();
break;
} else if (m->Word64ReverseBits().IsSupported()) {
Node* reversed = graph()->NewNode(m->Word64ReverseBits().op(), input);
Node* result = graph()->NewNode(m->Word64Clz(), reversed);
return result;
} else {
return BuildI64Ctz(input);
}
}
#endif
default: default:
op = UnsupportedOpcode(opcode); op = UnsupportedOpcode(opcode);
} }
......
...@@ -69,8 +69,8 @@ ...@@ -69,8 +69,8 @@
V(I64GeS, true) \ V(I64GeS, true) \
V(I64GtU, true) \ V(I64GtU, true) \
V(I64GeU, true) \ V(I64GeU, true) \
V(I64Ctz, true) \
V(I64Clz, true) \ V(I64Clz, true) \
V(I64Ctz, false) \
V(I64Popcnt, !MIPS_OR_X87) \ V(I64Popcnt, !MIPS_OR_X87) \
V(I32ConvertI64, true) \ V(I32ConvertI64, true) \
V(I64SConvertF32, false) \ V(I64SConvertF32, false) \
......
...@@ -590,6 +590,27 @@ TEST_F(Int64LoweringTest, I64Clz) { ...@@ -590,6 +590,27 @@ TEST_F(Int64LoweringTest, I64Clz) {
IsInt32Constant(0), start(), start())); IsInt32Constant(0), start(), start()));
} }
// kExprI64Ctz: // kExprI64Ctz:
TEST_F(Int64LoweringTest, I64Ctz) {
LowerGraph(graph()->NewNode(machine()->Word64CtzPlaceholder(),
Int64Constant(value(0))),
MachineRepresentation::kWord64);
Capture<Node*> branch_capture;
Matcher<Node*> branch_matcher = IsBranch(
IsWord32Equal(IsInt32Constant(low_word_value(0)), IsInt32Constant(0)),
start());
EXPECT_THAT(
graph()->end()->InputAt(1),
IsReturn2(
IsPhi(MachineRepresentation::kWord32,
IsInt32Add(IsWord32Ctz(IsInt32Constant(high_word_value(0))),
IsInt32Constant(32)),
IsWord32Ctz(IsInt32Constant(low_word_value(0))),
IsMerge(
IsIfTrue(AllOf(CaptureEq(&branch_capture), branch_matcher)),
IsIfFalse(
AllOf(CaptureEq(&branch_capture), branch_matcher)))),
IsInt32Constant(0), start(), start()));
}
// kExprI64Popcnt: // kExprI64Popcnt:
TEST_F(Int64LoweringTest, Dfs) { TEST_F(Int64LoweringTest, Dfs) {
......
...@@ -2272,6 +2272,7 @@ IS_UNOP_MATCHER(NumberToUint32) ...@@ -2272,6 +2272,7 @@ IS_UNOP_MATCHER(NumberToUint32)
IS_UNOP_MATCHER(ObjectIsReceiver) IS_UNOP_MATCHER(ObjectIsReceiver)
IS_UNOP_MATCHER(ObjectIsSmi) IS_UNOP_MATCHER(ObjectIsSmi)
IS_UNOP_MATCHER(Word32Clz) IS_UNOP_MATCHER(Word32Clz)
IS_UNOP_MATCHER(Word32Ctz)
IS_UNOP_MATCHER(Word32Popcnt) IS_UNOP_MATCHER(Word32Popcnt)
#undef IS_UNOP_MATCHER #undef IS_UNOP_MATCHER
......
...@@ -279,6 +279,7 @@ Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher, ...@@ -279,6 +279,7 @@ Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher); const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord32Clz(const Matcher<Node*>& value_matcher); Matcher<Node*> IsWord32Clz(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsWord32Ctz(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsWord32Popcnt(const Matcher<Node*>& value_matcher); Matcher<Node*> IsWord32Popcnt(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher); const Matcher<Node*>& rhs_matcher);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment