dotnet / dotnet/runtime

NFloat return values are not handled correctly on Windows x86

Open
#132,061 1 comment 0 reactions 0 assignees View on GitHub
area-Interop-coreclr untriaged
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Repro

```csharp
using System;
using System.Runtime.InteropServices;

static unsafe class Program
{
static float Test1(delegate* unmanaged[SuppressGCTransition] p) {
return (float)p().Value;
}

static float Test2(delegate* unmanaged[SuppressGCTransition] p) {
return p();
}
}
```

### Actual result

Test1 has the unmanaged call return value in eax:
```
call ecx
mov dword ptr [ebp-0x04], eax
```

Test2 has the unmanaged call return value in fp0:
```
call esi
fstp dword ptr [ebp-0x08]
```

### Expected result

Both test1 and test2 have the unmanaged return value in fp0. `float` and `NFloat` should have identical calling convention on 32-bit platforms.

godbolt.org link: https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:csharp,selection:(endColumn:1,endLineNumber:17,positionColumn:1,positionLineNumber:17,selectionStartColumn:1,selectionStartLineNumber:17,startColumn:1,startLineNumber:17),source:'using+System%3B%0Ausing+System.Runtime.InteropServices%3B%0A%0Astatic+unsafe+class+Program%0A%7B%0A++++static+void+Main()+%7B+%7D%0A%0A++++static+float+Test1(delegate*+unmanaged%5BSuppressGCTransition%5D%3CNFloat%3E+p)+%7B%0A++++++++return+(float)p().Value%3B%0A++++%7D%0A%0A++++static+float+Test2(delegate*+unmanaged%5BSuppressGCTransition%5D%3Cfloat%3E+p)+%7B%0A++++++++return+p()%3B%0A++++%7D%0A%7D%0A%0A'),l:'5',n:'0',o:'C%23+source+%231',t:'0')),k:43.55246519643951,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:dotnet100csharpcrossgen2,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:2,lang:csharp,libs:!(),options:'--Os+--targetarch+x86+--targetos+windows',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+.NET+10.0+Crossgen2+(Editor+%231)',t:'0')),k:37.863463937107795,l:'4',m:100,n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'WebAssembly+clang+(trunk)',editorid:1,fontScale:14,fontUsePx:'0',j:2,wrap:'1'),l:'5',n:'0',o:'Output+of+.NET+10.0+Crossgen2+(Compiler+%232)',t:'0')),k:18.584070866452716,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4

Contributor guide

Open the contributing guide

Research direction

Start by running the supplied C# repro through the linked Godbolt .NET 10 Crossgen2 configuration with --targetarch x86 and --targetos windows, then compare the generated assembly for Test1 and Test2. Done means NFloat and float unmanaged return values use the same fp0 convention on Windows x86.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
compilers, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.