-
Notifications
You must be signed in to change notification settings - Fork 170
The virtual function is not correctly invoked. #420
Open
Description
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 = %d0円A00円") {addr_space = 0 : i32} llvm.func @printf(!llvm.ptr, ...) -> i32 llvm.mlir.global internal constant @str0("%d%d00円") {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 } } */
Activity
Metadata
Metadata
Assignees
Labels
No labels