Skip to content

Conversation

ibuclaw
Copy link
Member

@ibuclaw ibuclaw commented Dec 30, 2020

@WalterBright this works when the extern(C) or extern(C++) function is external.
i.e:

extern(C++) creal cpp_twol();

extern(C) int main()
{
    auto a = cpp_twol();
    assert(a.re == 2 && a.im == 0);
    auto b = a;
    assert(b.re == 2 && b.im == 0);
    return 0;
}

But fails when the function is implemented in D.

extern(C++) creal cpp_twol() { return 2+0Li; }

extern(C) int main()
{
    auto a = cpp_twol();
    assert(a.re == 2 && a.im == 0);
    auto b = a;
    assert(b.re == 2 && b.im == 0);
    return 0;
}

Is this enough of a hint to do the fix proper?

@ibuclaw ibuclaw requested a review from WalterBright December 30, 2020 01:07
@dlang-bot
Copy link
Contributor

dlang-bot commented Dec 30, 2020

Thanks for your pull request, @ibuclaw!

Bugzilla references

Auto-close Bugzilla Severity Description
21515 major extern(C) and extern(C++) returns creal in wrong order

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#12073"

@ibuclaw ibuclaw marked this pull request as draft December 30, 2020 01:07
@RazvanN7
Copy link
Contributor

RazvanN7 commented Jan 8, 2021

I am not capable of understanding whether the fix is correct, however, you should include the test so that we see whether it passes or not.

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 8, 2021

I am not capable of understanding whether the fix is correct, however, you should include the test so that we see whether it passes or not.

It doesn't when it's implemented in D. I say this in my original post. ;-)

@RazvanN7
Copy link
Contributor

RazvanN7 commented Jan 8, 2021

Whatever it is fixing, it should have a test to not let reviewers guess what is the problem that is being fixed.

As I understand, this PR is fixing the code generation for the first example that you are providing. If that is the case, then please, include the test.

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 8, 2021

I don't consider it to be fixing anything at all, because it occurs at a place that affects every read of a complex number. There has to be a better place to tell the dmd backend to read a complex number backwards when it is returned from a function.

This is why @WalterBright should have a look to see if the hint sparks any suggestions.

@WalterBright
Copy link
Member

Looks ok to me. Add the test!

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 15, 2021

Looks ok to me. Add the test!

Isn't there any way to swap the re/im values earlier in codegen? It only needs to be done for

  1. Return statements in an extern C/C++ function.
  2. Expressions that read a complex number returned by an extern C/C++ function.

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 15, 2021

According to SYS V ABI for AMD64:

If the class is COMPLEX_X87, the real part of the value is returned in %st0 and the imaginary part in %st1.

And if I understand loadComplex correctly, it always stores the values in the reverse?

    note87(e, 0, 1);
    note87(e, sz, 0);

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 16, 2021

Inserting fxch at both the caller and callee return ought to be the simplest thing to do.

@ibuclaw ibuclaw force-pushed the issue21515 branch 15 times, most recently from 897668f to 2732d81 Compare January 16, 2021 22:47
@ibuclaw ibuclaw changed the title Attempt fixing Issue 21515 extern(C) and extern(C++) returns creal in wrong order fix Issue 21515 extern(C) and extern(C++) returns creal in wrong order Jan 16, 2021
@ibuclaw ibuclaw marked this pull request as ready for review January 16, 2021 22:51
@ibuclaw ibuclaw force-pushed the issue21515 branch 3 times, most recently from 12a25b4 to c7c3fc0 Compare January 16, 2021 23:26
@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 16, 2021

@WalterBright added fxch before returning from, and after calling creal functions.

@ibuclaw ibuclaw force-pushed the issue21515 branch 8 times, most recently from bfafe96 to e33df3e Compare January 19, 2021 09:31
@ibuclaw ibuclaw added the Review:Blocking Other Work review and pulling should be a priority label Jan 20, 2021
@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 20, 2021

Not strictly block #12069, but this bug came up when I was testing complex number passing.

@ibuclaw
Copy link
Member Author

ibuclaw commented Jan 20, 2021

@WalterBright OK? I've added more tests than strictly necessary, but wanted to be paranoid about changing the ABI for anything other than what is being targetted.

@RazvanN7 RazvanN7 added the Merge:72h no objection -> merge The PR will be merged if there are no objections raised. label Jan 21, 2021
In loadComplex and complex_eq87, the real part of x87 complex numbers
are pushed to the FPU register stack first (ST1), then the imaginary
part (ST0).  However, on the I64 ABI, real part is instead returned in
ST0 and the imaginary part in ST1. To handle this, FXCH is inserted
before returning from, and after calling a complex long double function.
@12345swordy
Copy link
Contributor

72 hours have pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Merge:auto-merge Merge:72h no objection -> merge The PR will be merged if there are no objections raised. Review:Blocking Other Work review and pulling should be a priority Severity:Bug Fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants