Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4435,10 +4435,10 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp)
}

// Optimize EQ/NE/GT/GE/LT/LE(op_that_sets_zf, 0) into op_that_sets_zf with GTF_SET_FLAGS + SETCC.
// For GT/GE/LT/LE don't allow ADD/SUB, runtime has to check for overflow.
// For GT/GE/LT/LE don't allow ADD/SUB/NEG, runtime has to check for overflow.
LIR::Use use;
if (((cmp->OperIs(GT_EQ, GT_NE) && op2->IsIntegralConst(0) && op1->SupportsSettingZeroFlag()) ||
(cmp->OperIs(GT_GT, GT_GE, GT_LT, GT_LE) && op2->IsIntegralConst(0) && !op1->OperIs(GT_ADD, GT_SUB) &&
(cmp->OperIs(GT_GT, GT_GE, GT_LT, GT_LE) && op2->IsIntegralConst(0) && !op1->OperIs(GT_ADD, GT_SUB, GT_NEG) &&
op1->SupportsSettingResultFlags())) &&
BlockRange().TryGetUse(cmp, &use) && IsProfitableToSetZeroFlag(op1))
{
Expand Down
52 changes: 47 additions & 5 deletions src/tests/JIT/opt/InstructionCombining/Neg.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ public static int CheckNeg()
fail = true;
}

if (NegsGreaterThanIntMinValue())
{
fail = true;
}

if (NegsGreaterThanLongMinValue())
{
fail = true;
}

if (fail)
{
return 101;
Expand Down Expand Up @@ -266,33 +276,65 @@ static bool NegsBinOpSingleLine(int a, int b)
//ARM64-FULL-LINE: negs {{w[0-9]+}}, {{w[0-9]+}}, LSL #1
return (-(a >> 1) != 0) | (-(b << 1) != 0);
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsGreaterThan(int a)
{
//ARM64-FULL-LINE: negs {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: neg {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, #0
return -a > 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsGreaterThanEq(int a)
{
//ARM64-FULL-LINE: negs {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: neg {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, #0
return -a >= 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsLessThan(int a)
{
//ARM64-FULL-LINE: negs {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: neg {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: lsr {{w[0-9]+}}, {{w[0-9]+}}, #31
return -a < 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsLessThanEq(int a)
{
//ARM64-FULL-LINE: negs {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: neg {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, #0
return -a <= 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsGreaterThanIntMinValue()
{
//ARM64-FULL-LINE: neg {{w[0-9]+}}, {{w[0-9]+}}
//ARM64-FULL-LINE: cmp {{w[0-9]+}}, #0
return -IntMinValue() > 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static bool NegsGreaterThanLongMinValue()
{
//ARM64-FULL-LINE: neg {{x[0-9]+}}, {{x[0-9]+}}
//ARM64-FULL-LINE: cmp {{x[0-9]+}}, #0
return -LongMinValue() > 0;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static int IntMinValue()
{
return int.MinValue;
}

[MethodImpl(MethodImplOptions.NoInlining)]
static long LongMinValue()
{
return long.MinValue;
}
}
}
Loading