dmd/compiler/test/runnable/powinline.d
Fares A. Bakhit fa1f860e4b
Fix #21024 - Optimize x^^c expressions (#21082)
* Fix #21024 - Optimize x^^c expressions

Reason for the *magic* constraint c<8 on inlining x^^c:

https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/fpu/e_powl.S;h=47f129f34d368d7c67b8e5f2462b36b0bebb7621;hb=HEAD#l136

* Fix poor assumption about expression state

* Restrict optimization to floating point expressions

* Generalize optimization to any scalar data type

* Fix segfault on x^^c where x is a single member anonymous enum

DMD segfaulted on compiling the unittests in std/algorithm/sorting.o, the
unittest that caused the segfault can be reduced to:

    enum real Two = 2.0;
    auto _ = Two^^3;

I'm not sure why copying the anonymous enum into a `const` variable causes
the compiler to segfault.

* Add tests to x^^c inlining optimization

* Fix missing type for e1 ^^ -1 to 1 / e1 rewrite

* Move rewrites from constant folding to expression semantic and restrict them to [-1, 2]

* Improve error message for the x^^2 rewrite.

Before:
    ex.d(4): Error: can implicitly convert expression `(const const(double) __powtmp2 = x + 5.0;) , __powtmp2 * ...` of type `double` to `int`
        int y = ( x + 5 ) ^^ 2;
                ^
and after:
    ex.d(4): Error: cannot implicitly convert expression `(x + 5.0) ^^ 2L` of type `double` to `int`
        int y = ( x + 5 ) ^^ 2;
                ^

* Update C++ frontend header to match change in `CommaExp`

* Address code review feedback

Co-authored-by: Dennis Korpel <dkorpel@gmail.com>

---------

Co-authored-by: Dennis Korpel <dkorpel@gmail.com>
2025-03-29 12:13:38 +01:00

44 lines
695 B
D

/*
REQUIRED_ARGS: -betterC
RUN_OUTPUT:
---
Success
---
*/
import core.stdc.stdio;
void test1()
{
enum real Two = 2.0;
static assert(Two^^3 == 8.0);
}
void test2()
{
double x = 5.0;
assert(x^^-1 == 1/x);
x = -1.0;
assert(x^^1 == x);
assert((x += 3) ^^ 2.0 == 4.0);
assert((x) ^^ 2.0 == 4.0);
assert((x *= 5) ^^ 2.0 == (x * x));
assert(x^^-1 == 1.0 / x);
assert((x^^-1) ^^ 0.0 == 1.0);
}
void test3()
{
int x = 6;
assert(x ^^ 0 == 1);
assert((x += 3) ^^ 2 == 81);
assert(x ^^ 2 == (x ^^ 1) * (x ^^ 1));
static assert(4.0 ^^ -1 == 0.25);
}
extern(C) void main()
{
test1();
test2();
test3();
printf("Success\n");
}