From d334f0c3f1adfa130efc94aa76e4dded7673e5c2 Mon Sep 17 00:00:00 2001 From: SwapnilGaikwad Date: Fri, 16 Jun 2023 20:18:30 +0100 Subject: [PATCH] Fix invalid lowering for SELECT over mixed neg/not operands (#87674) --- src/coreclr/jit/lowerarmarch.cpp | 2 +- .../JIT/opt/Compares/conditionalNegates.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 64826c428b77f..25d07c53e0929 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -2579,7 +2579,7 @@ void Lowering::TryLowerCselToCinvOrCneg(GenTreeOp* select, GenTree* cond) assert(trueVal->OperIs(GT_NOT, GT_NEG) || falseVal->OperIs(GT_NOT, GT_NEG)); - if (trueVal->OperIs(GT_NOT) || trueVal->OperIs(GT_NEG)) + if ((isCneg && trueVal->OperIs(GT_NEG)) || (!isCneg && trueVal->OperIs(GT_NOT))) { shouldReverseCondition = true; invertedOrNegatedVal = trueVal->gtGetOp1(); diff --git a/src/tests/JIT/opt/Compares/conditionalNegates.cs b/src/tests/JIT/opt/Compares/conditionalNegates.cs index 8366f1b9b9db6..b612756576010 100644 --- a/src/tests/JIT/opt/Compares/conditionalNegates.cs +++ b/src/tests/JIT/opt/Compares/conditionalNegates.cs @@ -129,4 +129,23 @@ public static void cneg_shifted_true_oper(int op1, int op2, int expected) int result = op1 < 51 ? -(op1 >> 3) : op2; Assert.Equal(expected, result); } + + [Theory] + [InlineData(1, -1)] + [InlineData(55, ~55)] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void cneg_mixed_not_and_neg_oper(int op1, int expected) + { + //ARM64-FULL-LINE: cmp {{w[0-9]+}}, #52 + //ARM64-FULL-LINE-NEXT: csneg {{w[0-9]+}}, {{w[0-9]+}}, {{w[0-9]+}}, {{gt|le}} + if (op1 <= 52) + { + op1 = -op1; + } + else + { + op1 = ~op1; + } + Assert.Equal(expected, op1); + } }