From 4cbe6f99d23e04c56a89251d49de1b0f14000427 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Mon, 18 Jul 2022 12:43:53 +0300 Subject: [PATCH] Do not consider single-reg bitcasts multi-reg nodes (#72020) * Fix an ARM codegen bug * Do not consider single-reg bitcasts multi-reg nodes * Add a test --- src/coreclr/jit/codegenarm.cpp | 15 ++++------ src/coreclr/jit/gentree.cpp | 2 +- src/coreclr/jit/lsrabuild.cpp | 2 +- .../JitBlue/Runtime_71831/Runtime_71831.cs | 29 +++++++++++++++++++ .../Runtime_71831/Runtime_71831.csproj | 18 ++++++++++++ 5 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.csproj diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp index 3a8c00bafaa18..935c4b8c7bd30 100644 --- a/src/coreclr/jit/codegenarm.cpp +++ b/src/coreclr/jit/codegenarm.cpp @@ -1014,7 +1014,7 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree) GenTree* data = tree->gtOp1; regNumber dataReg = REG_NA; - genConsumeReg(data); + genConsumeRegs(data); if (data->isContained()) { @@ -1073,18 +1073,13 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) { GenTree* data = tree->gtOp1; GenTree* actualData = data->gtSkipReloadOrCopy(); - unsigned regCount = 1; - // var = call, where call returns a multi-reg return value - // case is handled separately. + + // Stores from a multi-reg source are handled separately. if (actualData->IsMultiRegNode()) { - regCount = actualData->GetMultiRegCount(compiler); - if (regCount > 1) - { - genMultiRegStoreToLocal(tree); - } + genMultiRegStoreToLocal(tree); } - if (regCount == 1) + else { unsigned varNum = tree->GetLclNum(); LclVarDsc* varDsc = compiler->lvaGetDesc(varNum); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 99d80905bd0d5..eb3ad51acc5c4 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -812,7 +812,7 @@ bool GenTree::IsMultiRegNode() const #if !defined(TARGET_64BIT) if (OperIsMultiRegOp()) { - return true; + return AsMultiRegOp()->GetRegCount() > 1; } #endif diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 4333630327030..bb02dcc9de9d3 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3492,7 +3492,7 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc) // Second, use source registers. - if (op1->IsMultiRegNode() && (op1->GetMultiRegCount(compiler) > 1)) + if (op1->IsMultiRegNode()) { // This is the case where the source produces multiple registers. // This must be a store lclvar. diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.cs b/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.cs new file mode 100644 index 0000000000000..72049e2479e6f --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +unsafe class Runtime_71831 +{ + private static int Main() + { + return Problem(100) ? 101 : 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool Problem(int i) + { + StructWithFloats s = default; + + s.FloatOne = BitConverter.Int32BitsToSingle(i); + + return s.FloatOne != *(float*)&i; + } + + struct StructWithFloats + { + public float FloatOne; + public float FloatTwo; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.csproj new file mode 100644 index 0000000000000..240a474f3b320 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_71831/Runtime_71831.csproj @@ -0,0 +1,18 @@ + + + Exe + True + true + + + + + + + \ No newline at end of file