[turbofan][turboshaft] Improve the reduction of UintNLessThanOrEqual
Add "x <= 0 => x == 0" reduction when "x" is uint. This allows x64 to select shorter instructions: Before: REX.W cmpq r9,0x0 jna addr After: REX.W testq r9,r9 jz addr This optimization is also ported to turboshaft. Bug: v8:12783 Change-Id: I87dfd5879c047bb57d30e7a51a309106e3a519ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3967480 Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Hao A Xu <hao.a.xu@intel.com> Cr-Commit-Position: refs/heads/main@{#83994}
This commit is contained in:
parent
fbd4541fe7
commit
7112fe658d
@ -34,6 +34,7 @@ class Word32Adapter {
|
||||
using IntNBinopMatcher = Int32BinopMatcher;
|
||||
using UintNBinopMatcher = Uint32BinopMatcher;
|
||||
using intN_t = int32_t;
|
||||
using uintN_t = uint32_t;
|
||||
// WORD_SIZE refers to the N for which this adapter specializes.
|
||||
static constexpr std::size_t WORD_SIZE = 32;
|
||||
|
||||
@ -75,6 +76,9 @@ class Word32Adapter {
|
||||
const Operator* IntNAdd(MachineOperatorBuilder* machine) {
|
||||
return machine->Int32Add();
|
||||
}
|
||||
static const Operator* WordNEqual(MachineOperatorBuilder* machine) {
|
||||
return machine->Word32Equal();
|
||||
}
|
||||
|
||||
Reduction ReplaceIntN(int32_t value) { return r_->ReplaceInt32(value); }
|
||||
Reduction ReduceWordNAnd(Node* node) { return r_->ReduceWord32And(node); }
|
||||
@ -85,6 +89,10 @@ class Word32Adapter {
|
||||
Node* UintNConstant(uint32_t value) { return r_->Uint32Constant(value); }
|
||||
Node* WordNAnd(Node* lhs, Node* rhs) { return r_->Word32And(lhs, rhs); }
|
||||
|
||||
Reduction ReduceWordNComparisons(Node* node) {
|
||||
return r_->ReduceWord32Comparisons(node);
|
||||
}
|
||||
|
||||
private:
|
||||
MachineOperatorReducer* r_;
|
||||
};
|
||||
@ -98,6 +106,7 @@ class Word64Adapter {
|
||||
using IntNBinopMatcher = Int64BinopMatcher;
|
||||
using UintNBinopMatcher = Uint64BinopMatcher;
|
||||
using intN_t = int64_t;
|
||||
using uintN_t = uint64_t;
|
||||
// WORD_SIZE refers to the N for which this adapter specializes.
|
||||
static constexpr std::size_t WORD_SIZE = 64;
|
||||
|
||||
@ -139,6 +148,9 @@ class Word64Adapter {
|
||||
static const Operator* IntNAdd(MachineOperatorBuilder* machine) {
|
||||
return machine->Int64Add();
|
||||
}
|
||||
static const Operator* WordNEqual(MachineOperatorBuilder* machine) {
|
||||
return machine->Word64Equal();
|
||||
}
|
||||
|
||||
Reduction ReplaceIntN(int64_t value) { return r_->ReplaceInt64(value); }
|
||||
Reduction ReduceWordNAnd(Node* node) { return r_->ReduceWord64And(node); }
|
||||
@ -152,6 +164,10 @@ class Word64Adapter {
|
||||
Node* UintNConstant(uint64_t value) { return r_->Uint64Constant(value); }
|
||||
Node* WordNAnd(Node* lhs, Node* rhs) { return r_->Word64And(lhs, rhs); }
|
||||
|
||||
Reduction ReduceWordNComparisons(Node* node) {
|
||||
return r_->ReduceWord64Comparisons(node);
|
||||
}
|
||||
|
||||
private:
|
||||
MachineOperatorReducer* r_;
|
||||
};
|
||||
@ -457,15 +473,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
return ReduceWord32Comparisons(node);
|
||||
}
|
||||
case IrOpcode::kUint32LessThanOrEqual: {
|
||||
Uint32BinopMatcher m(node);
|
||||
if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true
|
||||
if (m.right().Is(kMaxUInt32)) return ReplaceBool(true); // x <= M => true
|
||||
if (m.IsFoldable()) { // K <= K => K (K stands for arbitrary constants)
|
||||
return ReplaceBool(m.left().ResolvedValue() <=
|
||||
m.right().ResolvedValue());
|
||||
}
|
||||
if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
|
||||
return ReduceWord32Comparisons(node);
|
||||
return ReduceUintNLessThanOrEqual<Word32Adapter>(node);
|
||||
}
|
||||
case IrOpcode::kFloat32Sub: {
|
||||
Float32BinopMatcher m(node);
|
||||
@ -915,12 +923,7 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
|
||||
return ReduceWord64Comparisons(node);
|
||||
}
|
||||
case IrOpcode::kUint64LessThanOrEqual: {
|
||||
Uint64BinopMatcher m(node);
|
||||
if (m.IsFoldable()) { // K <= K => K (K stands for arbitrary constants)
|
||||
return ReplaceBool(m.left().ResolvedValue() <=
|
||||
m.right().ResolvedValue());
|
||||
}
|
||||
return ReduceWord64Comparisons(node);
|
||||
return ReduceUintNLessThanOrEqual<Word64Adapter>(node);
|
||||
}
|
||||
case IrOpcode::kFloat32Select:
|
||||
case IrOpcode::kFloat64Select:
|
||||
@ -1858,6 +1861,27 @@ Reduction MachineOperatorReducer::ReduceWordNAnd(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
template <typename WordNAdapter>
|
||||
Reduction MachineOperatorReducer::ReduceUintNLessThanOrEqual(Node* node) {
|
||||
using A = WordNAdapter;
|
||||
A a(this);
|
||||
|
||||
typename A::UintNBinopMatcher m(node);
|
||||
typename A::uintN_t kMaxUIntN =
|
||||
std::numeric_limits<typename A::uintN_t>::max();
|
||||
if (m.left().Is(0)) return ReplaceBool(true); // 0 <= x => true
|
||||
if (m.right().Is(kMaxUIntN)) return ReplaceBool(true); // x <= M => true
|
||||
if (m.IsFoldable()) { // K <= K => K (K stands for arbitrary constants)
|
||||
return ReplaceBool(m.left().ResolvedValue() <= m.right().ResolvedValue());
|
||||
}
|
||||
if (m.LeftEqualsRight()) return ReplaceBool(true); // x <= x => true
|
||||
if (m.right().Is(0)) { // x <= 0 => x == 0
|
||||
NodeProperties::ChangeOp(node, a.WordNEqual(machine()));
|
||||
return Changed(node);
|
||||
}
|
||||
return a.ReduceWordNComparisons(node);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Represents an operation of the form `(source & mask) == masked_value`.
|
||||
|
@ -134,6 +134,8 @@ class V8_EXPORT_PRIVATE MachineOperatorReducer final
|
||||
Reduction ReduceWordNOr(Node* node);
|
||||
template <typename WordNAdapter>
|
||||
Reduction ReduceWordNXor(Node* node);
|
||||
template <typename WordNAdapter>
|
||||
Reduction ReduceUintNLessThanOrEqual(Node* node);
|
||||
|
||||
// Tries to simplify "if(x == 0)" by removing the "== 0" and inverting
|
||||
// branches.
|
||||
|
@ -1270,6 +1270,10 @@ class MachineOptimizationReducer : public Next {
|
||||
k == rep.MaxUnsignedValue()) {
|
||||
return Asm().Word32Constant(1);
|
||||
}
|
||||
// x <= 0 => x == 0
|
||||
if (uint64_t k; Asm().MatchWordConstant(right, rep_w, &k) && k == 0) {
|
||||
return Asm().Equal(left, Asm().WordConstant(0, rep_w), rep_w);
|
||||
}
|
||||
}
|
||||
if (kind == Kind::kUnsignedLessThan) {
|
||||
// x < 0 => false
|
||||
|
Loading…
Reference in New Issue
Block a user