open64-compiler / open64

open64 compiler
76 stars 29 forks source link

[SPEC2006] w2ll: Get assertion when returning the small struct by value #6

Closed Yvan-xy closed 1 year ago

Yvan-xy commented 1 year ago

Extract from 473.astar/CreateWay_.cpp xcalcc -c case.cpp

class rvectort {
public:
  float x, y, z;
};
struct createwayinfot {
  rvectort finishp;
};
struct wayinfot {
  rvectort *wayarp;
};
class wayobj {
  createwayinfot createwayinfo;
  void gety(float);
  rvectort getpoint();
  bool createway(const rvectort &, const rvectort &, bool, wayinfot &);
};
bool wayobj::createway(const rvectort &startp, const rvectort &finishp,
                       bool flcorrect, wayinfot &wayinfo) {
  gety(finishp.z);
  if (flcorrect)
    createwayinfo.finishp = getpoint();
  wayinfo.wayarp[0] = startp;
}

The return value of getpoint() would be stored in PREG_F17 and PREG_F18. This is because the class rvectort is a small struct. The larger structs that are more than 16 bytes would be returned by the fake parameter of the callee.

Here is another small case:

struct A {int a; double b;};
auto f(int a, double b) {
    return A{a, b};
}

auto b(int a, double b) {
  return f(a, b);
}
Yvan-xy commented 1 year ago

This case can also be added to the regression test.

// return_small_struct.cpp
#include <stdio.h>

struct A {int a; double b;};
auto getA(int a, double b) {
    return A{a, b};
}

auto testA(int a, double b) {
  return getA(a, b);
}

struct B {double a; int b; int c;};
auto testB(float x, int y) {
  return B{x, y + 1, y - 3};
}

auto testB2(int a, int b, float c, double d) {
  return B{c + d, a, a + b};
}

struct C {float a; long long b;};
auto testC(float a, long long b) {
  return C{a + (float)-0.22293939, b * 24};
}

int main() {
  struct A a = testA(15488, 2.399);
  printf("%d %lf\n", a.a, a.b);

  struct B b1 = testB(4.33, 1899372);
  printf("%lf %d %d\n", b1.a, b1.b, b1.c);

  struct B b2 = testB2(-3, 55, 0.332, -0.1);
  printf("%lf %d %d\n", b2.a, b2.b, b2.c);

  struct C c = testC(88.7749, -9986173823);
  printf("%f %lld\n", c.a, c.b);

  return 0;
}

The expect output is:

15488 2.399000
4.330000 1899373 1899369
0.232000 -3 52
88.551964 -239668171752
shinmingliu commented 1 year ago

Let's create the regression test. Is there a convention for regression tests in GitHub?

On Wed, Apr 26, 2023 at 9:59 AM Yvan @.***> wrote:

This case can also be added to the regression test.

// return_small_struct.cpp

include

struct A {int a; double b;};auto getA(int a, double b) { return A{a, b}; } auto testA(int a, double b) { return getA(a, b); } struct B {double a; int b; int c;};auto testB(float x, int y) { return B{x, y + 1, y - 3}; } auto testB2(int a, int b, float c, double d) { return B{c + d, a, a + b}; } struct C {float a; long long b;};auto testC(float a, long long b) { return C{a + (float)-0.22293939, b * 24}; } int main() { struct A a = testA(15488, 2.399); printf("%d %lf\n", a.a, a.b);

struct B b1 = testB(4.33, 1899372); printf("%lf %d %d\n", b1.a, b1.b, b1.c);

struct B b2 = testB2(-3, 55, 0.332, -0.1); printf("%lf %d %d\n", b2.a, b2.b, b2.c);

struct C c = testC(88.7749, -9986173823); printf("%f %lld\n", c.a, c.b);

return 0; }

The expect output is:

15488 2.399000 4.330000 1899373 1899369 0.232000 -3 52 88.551964 -239668171752

— Reply to this email directly, view it on GitHub https://github.com/open64-compiler/open64/issues/6#issuecomment-1523759796, or unsubscribe https://github.com/notifications/unsubscribe-auth/AI2X4V7VTSDCBFNELGEOLWLXDFH5HANCNFSM6AAAAAAXL7NTAI . You are receiving this because you are subscribed to this thread.Message ID: @.***>