Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The virtual function is not correctly invoked. #420

Open
sybs5968 opened this issue Jul 11, 2024 · 0 comments
Open

The virtual function is not correctly invoked. #420

sybs5968 opened this issue Jul 11, 2024 · 0 comments

Comments

@sybs5968
Copy link

Hello, when I try to translate operations with Polygeist that call virtual functions, I find that the base class calls the functions of the base class, not the functions overridden by the subclass. The sample I used is as follows. The comments are the translated result. The command I used is cgeist test.cpp --function=main --resource-dir=/Polygeist/llvm-project/build/lib/clang/18 -I /Polygeist/tools/cgeist/Test/polybench/utilities -S

In the base class, vfunc is an addition operation. In the subclass, it is rewritten as a subtraction operation. The final translation is the addition operation of the base class(%12 = arith.addi %10, %11 : i32) instead of the expected subtraction operation of the subclass.

#include <new>
#include <cstdio>
class SimStream {
public:
    int n;
    SimStream() {
        n = 0;
    }
    virtual int vfunc(int val1 , int val2) {
        return val1 + val2;
    }
};

class subSimStream : public SimStream {
public:
    int vfunc(int val1 , int val2) override {
        return val1 - val2;
    }
};

int myfunc(SimStream *ptr , int val1 , int val2) {
    int output = ptr->vfunc(val1 , val2);
    return output;
}

int main() {
    SimStream *r = new subSimStream;
    int val1 , val2 , output;
    scanf("%d%d" , &val1 , &val2);
    output = r->vfunc(val1 , val2);
    printf("output = %d\n" , output);
    delete r;
    return 0;
}

/*
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i32, dense<32> : vector<2xi32>>, #dlti.dl_entry<f16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f64, dense<64> : vector<2xi32>>, #dlti.dl_entry<i16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f128, dense<128> : vector<2xi32>>, #dlti.dl_entry<i8, dense<8> : vector<2xi32>>, #dlti.dl_entry<i1, dense<8> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi32>>, #dlti.dl_entry<f80, dense<128> : vector<2xi32>>, #dlti.dl_entry<i64, dense<64> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi32>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i32>, #dlti.dl_entry<"dlti.endianness", "little">>, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu", "polygeist.target-cpu" = "x86-64", "polygeist.target-features" = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87", "polygeist.tune-cpu" = "generic"} {
  llvm.func @free(!llvm.ptr)
  llvm.mlir.global internal constant @str1("output = %d\0A\00") {addr_space = 0 : i32}
  llvm.func @printf(!llvm.ptr, ...) -> i32
  llvm.mlir.global internal constant @str0("%d%d\00") {addr_space = 0 : i32}
  llvm.func @scanf(!llvm.ptr, ...) -> i32
  func.func @main() -> i32 attributes {llvm.linkage = #llvm.linkage<external>} {
    %c0_i32 = arith.constant 0 : i32
    %0 = llvm.mlir.undef : i32
    %alloca = memref.alloca() : memref<1xi32>
    affine.store %0, %alloca[0] : memref<1xi32>
    %alloca_0 = memref.alloca() : memref<1xi32>
    affine.store %0, %alloca_0[0] : memref<1xi32>
    %alloc = memref.alloc() : memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>
    %cast = memref.cast %alloc : memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>> to memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>
    call @_ZN12subSimStreamC1Ev(%cast) : (memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> ()
    %1 = "polygeist.memref2pointer"(%alloc) : (memref<1x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> !llvm.ptr
    %2 = llvm.mlir.zero : !llvm.ptr
    %3 = llvm.icmp "ne" %1, %2 : !llvm.ptr
    %4 = arith.select %3, %1, %2 : !llvm.ptr
    %5 = llvm.mlir.addressof @str0 : !llvm.ptr
    %6 = llvm.getelementptr %5[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<5 x i8>
    %7 = "polygeist.memref2pointer"(%alloca_0) : (memref<1xi32>) -> !llvm.ptr
    %8 = "polygeist.memref2pointer"(%alloca) : (memref<1xi32>) -> !llvm.ptr
    %9 = llvm.call @scanf(%6, %7, %8) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, !llvm.ptr, !llvm.ptr) -> i32
    %10 = affine.load %alloca_0[0] : memref<1xi32>
    %11 = affine.load %alloca[0] : memref<1xi32>
    %12 = arith.addi %10, %11 : i32
    %13 = llvm.mlir.addressof @str1 : !llvm.ptr
    %14 = llvm.getelementptr %13[0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<13 x i8>
    %15 = llvm.call @printf(%14, %12) vararg(!llvm.func<i32 (ptr, ...)>) : (!llvm.ptr, i32) -> i32
    llvm.call @free(%4) : (!llvm.ptr) -> ()
    return %c0_i32 : i32
  }
  func.func @_ZN12subSimStreamC1Ev(%arg0: memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
    %0 = "polygeist.memref2pointer"(%arg0) : (memref<?x!llvm.struct<(struct<packed (ptr, i32, array<4 x i8>)>)>>) -> !llvm.ptr
    %1 = "polygeist.pointer2memref"(%0) : (!llvm.ptr) -> memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>
    call @_ZN9SimStreamC1Ev(%1) : (memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) -> ()
    return
  }
  func.func @_ZN9SimStream5vfuncEii(%arg0: memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>, %arg1: i32, %arg2: i32) -> i32 attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
    %0 = arith.addi %arg1, %arg2 : i32
    return %0 : i32
  }
  func.func @_ZN9SimStreamC1Ev(%arg0: memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
    %c0_i32 = arith.constant 0 : i32
    %0 = "polygeist.memref2pointer"(%arg0) : (memref<?x!llvm.struct<packed (ptr, i32, array<4 x i8>)>>) -> !llvm.ptr
    %1 = llvm.getelementptr %0[0, 1] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<packed (ptr, i32, array<4 x i8>)>
    llvm.store %c0_i32, %1 : i32, !llvm.ptr
    return
  }
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant