<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/87855>87855</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[MLIR][LLVM IR]Why get wrong result when call MLIR function by c++?
</td>
</tr>
<tr>
<th>Labels</th>
<td>
mlir
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
spacemaninhust
</td>
</tr>
</table>
<pre>
I wrote softmax in linalg as follows:
`#map = affine_map<(d0, d1) -> (d0, d1)>
#map1 = affine_map<(d0, d1) -> (d0, 0)>
module {
func.func @forward(%arg0: tensor<3x2xf32>) -> tensor<3x2xf32> {
%cst = arith.constant dense<0.000000e+00> : tensor<3x1xf32>
%0 = linalg.generic {indexing_maps = [#map, #map1], iterator_types = ["parallel", "reduction"]} ins(%arg0 : tensor<3x2xf32>) outs(%cst : tensor<3x1xf32>) {
^bb0(%in: f32, %out: f32):
%3 = math.exp %in : f32
%4 = arith.addf %3, %out : f32
linalg.yield %4 : f32
} -> tensor<3x1xf32>
%1 = tensor.empty() : tensor<3x2xf32>
%2 = linalg.generic {indexing_maps = [#map, #map1, #map], iterator_types = ["parallel", "parallel"]} ins(%arg0, %0 : tensor<3x2xf32>, tensor<3x1xf32>) outs(%1 : tensor<3x2xf32>) {
^bb0(%in: f32, %in_0: f32, %out: f32):
%3 = math.exp %in : f32
%4 = arith.divf %3, %in_0 : f32
linalg.yield %4 : f32
} -> tensor<3x2xf32>
return %2 : tensor<3x2xf32>
}
}`
I use the following pass to convert to LLVM IR:
`mlir-opt --llvm-request-c-wrappers \
--linalg-bufferize --tensor-bufferize --arith-bufferize --arith-expand \
--convert-linalg-to-affine-loops \
-func-bufferize -finalizing-bufferize -convert-bufferization-to-memref \
--convert-to-llvm
mlir-translate --mlir-to-llvmir`
Here is my LLVM IR:
`; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"
@__constant_3x1xf32 = private constant [3 x [1 x float]] zeroinitializer
declare ptr @malloc(i64)
declare void @free(ptr)
define { ptr, ptr, i64, [2 x i64], [2 x i64] } @forward(ptr %0, ptr %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6) {
%8 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } undef, ptr %0, 0
%9 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %8, ptr %1, 1
%10 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %9, i64 %2, 2
%11 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %10, i64 %3, 3, 0
%12 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %11, i64 %5, 4, 0
%13 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %12, i64 %4, 3, 1
%14 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %13, i64 %6, 4, 1
%15 = call ptr @malloc(i64 add (i64 ptrtoint (ptr getelementptr (float, ptr null, i64 3) to i64), i64 64))
%16 = ptrtoint ptr %15 to i64
%17 = add i64 %16, 63
%18 = urem i64 %17, 64
%19 = sub i64 %17, %18
%20 = inttoptr i64 %19 to ptr
%21 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } undef, ptr %15, 0
%22 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %21, ptr %20, 1
%23 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %22, i64 0, 2
%24 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %23, i64 3, 3, 0
%25 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %24, i64 1, 3, 1
%26 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %25, i64 1, 4, 0
%27 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %26, i64 1, 4, 1
%28 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, 1
%29 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, 2
%30 = getelementptr float, ptr %28, i64 %29
call void @llvm.memcpy.p0.p0.i64(ptr %30, ptr @__constant_3x1xf32, i64 mul (i64 ptrtoint (ptr getelementptr (float, ptr null, i32 1) to i64), i64 3), i1 false)
br label %31
31: ; preds = %54, %7
%32 = phi i64 [ %55, %54 ], [ 0, %7 ]
%33 = icmp slt i64 %32, 3
br i1 %33, label %34, label %56
34: ; preds = %31
br label %35
35: ; preds = %38, %34
%36 = phi i64 [ %53, %38 ], [ 0, %34 ]
%37 = icmp slt i64 %36, 2
br i1 %37, label %38, label %54
38: ; preds = %35
%39 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %14, 1
%40 = mul i64 %32, 2
%41 = add i64 %40, %36
%42 = getelementptr float, ptr %39, i64 %41
%43 = load float, ptr %42, align 4
%44 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, 1
%45 = add i64 %32, 0
%46 = getelementptr float, ptr %44, i64 %45
%47 = load float, ptr %46, align 4
%48 = call float @llvm.exp.f32(float %43)
%49 = fadd float %48, %47
%50 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, 1
%51 = add i64 %32, 0
%52 = getelementptr float, ptr %50, i64 %51
store float %49, ptr %52, align 4
%53 = add i64 %36, 1
br label %35
54: ; preds = %35
%55 = add i64 %32, 1
br label %31
56: ; preds = %31
%57 = call ptr @malloc(i64 add (i64 ptrtoint (ptr getelementptr (float, ptr null, i64 6) to i64), i64 64))
%58 = ptrtoint ptr %57 to i64
%59 = add i64 %58, 63
%60 = urem i64 %59, 64
%61 = sub i64 %59, %60
%62 = inttoptr i64 %61 to ptr
%63 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } undef, ptr %57, 0
%64 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %63, ptr %62, 1
%65 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %64, i64 0, 2
%66 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %65, i64 3, 3, 0
%67 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %66, i64 2, 3, 1
%68 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %67, i64 2, 4, 0
%69 = insertvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %68, i64 1, 4, 1
br label %70
70: ; preds = %94, %56
%71 = phi i64 [ %95, %94 ], [ 0, %56 ]
%72 = icmp slt i64 %71, 3
br i1 %72, label %73, label %96
73: ; preds = %70
br label %74
74: ; preds = %77, %73
%75 = phi i64 [ %93, %77 ], [ 0, %73 ]
%76 = icmp slt i64 %75, 2
br i1 %76, label %77, label %94
77: ; preds = %74
%78 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %14, 1
%79 = mul i64 %71, 2
%80 = add i64 %79, %75
%81 = getelementptr float, ptr %78, i64 %80
%82 = load float, ptr %81, align 4
%83 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %27, 1
%84 = add i64 %71, 0
%85 = getelementptr float, ptr %83, i64 %84
%86 = load float, ptr %85, align 4
%87 = call float @llvm.exp.f32(float %82)
%88 = fdiv float %87, %86
%89 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %69, 1
%90 = mul i64 %71, 2
%91 = add i64 %90, %75
%92 = getelementptr float, ptr %89, i64 %91
store float %88, ptr %92, align 4
%93 = add i64 %75, 1
br label %74
94: ; preds = %74
%95 = add i64 %71, 1
br label %70
96: ; preds = %70
ret { ptr, ptr, i64, [2 x i64], [2 x i64] } %69
}
define void @_mlir_ciface_forward(ptr %0, ptr %1) {
%3 = load { ptr, ptr, i64, [2 x i64], [2 x i64] }, ptr %1, align 8
%4 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 0
%5 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 1
%6 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 2
%7 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 3, 0
%8 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 3, 1
%9 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 4, 0
%10 = extractvalue { ptr, ptr, i64, [2 x i64], [2 x i64] } %3, 4, 1
%11 = call { ptr, ptr, i64, [2 x i64], [2 x i64] } @forward(ptr %4, ptr %5, i64 %6, i64 %7, i64 %8, i64 %9, i64 %10)
store { ptr, ptr, i64, [2 x i64], [2 x i64] } %11, ptr %0, align 8
ret void
}
; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare float @llvm.exp.f32(float) #1
attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}`
But when I call it by c++, I got wrong result. Here is my code:
`extern "C" {
void _mlir_ciface_forward(memref::MemRefDescriptor<float, 2> *C,
memref::MemRefDescriptor<float, 2> *A);
}
int main() {
const int32_t M = 3;
const int32_t N = 2;
float matA[M][N] = {{1, 1}, {2, 1}, {3, 1}};
float matC[M][N];
std::array<int64_t, 2> aDim = {M, N};
std::array<int64_t, 2> cDim = {M, N};
memref::MemRef<float, 2> A((float *)matA, aDim);
memref::MemRef<float, 2> C((float *)matC, cDim);
_mlir_ciface_forward(&C.memRefDesc, &A.memRefDesc);
std::cout << "result:\n";
utility::printMatrix(C);
}`
I used memref to encapsulate MemRefDescriptor,C’s result is incorrect. Looks like there is some offset. C should be a 3*2 matrix, when I output some more data, I find that the correct data is behind.Like this:
`result:
| 0.0000 0.0000 |
| 0.0000 0.0000 |
| 0.0000 0.0000 |
| 0.0000 0.0000 |
| 0.0000 0.0000 |
| 0.0000 0.0000 |
| 0.5000 0.5000 |
| 0.7311 0.2689 |
| 0.8808 0.1192 |`
Why is this happening, and can anyone help me?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMW0uTo7iT_zSqi8IOkBCCQx3KdldsRXTNYQ6zxwoZhK0dEKwQ9ZhPvyEJbPFwbfU03fGv6GhjkPKlzF9mCpm1rThJzu8B2QFyuGOdPtfqvm1YxismhTx3rb471vnH_RN8U7XmsK0LXbF3KCQshWTlCbIWFnVZ1m8t-PYIdnuQPoDgAIIHEAcA4Yo1EOADZEUhJH-pWAPwHqAkDwDawzwEKIUbgL_B8T2Av_VULInwB2kEPomqzruSQ0B37juERSezrfkPgigoavXGVA5QAhBh6hQA_AA1l22tAN7jd_ReYGSIDVwWnvnEIQSIZK12Iiuhz9uslq1mUsOcy5YDvA-2gf3jAO2CwBIYMw0Hpj7RwJJ0dt-euORKZIazkDl_F_JkLNPaMWZBreGMMXoTAnIw34TmiulaveiPhnujUcMUK0teAoTcLKR43mVa1NLcIgdAD1DI9mqoqdC-pepO9yOdKZa1Q-nEcuTb8Ri4eUKaWWaglYbUnb7cSAF-uM6yxsFWlYrp85a_N9ASgMOE8dDIWxqW54WdfuWyNKs3-ofgZT6QmAwy5pn6x-IyOmd2o7a8avSHVTi9aU5_Mvo5H7hc_rg3-HcWnKG33ydOsb_lAldfCT9zqS97ipAvwe_wnVy8jnzH8F3Reebrr7julBzc4FNnAfTQAyg9GCS210-waznUZ95DtpAn2LC2hbqGWS1fudLm8vv3v57h059zPK9KoTZ1o-FmU5av1Ubx_-14qzfZ5k2xpuGqhYDs--FButk4zTfHrii4Ev9wuNk4mUe3rDUX7vD3hsl8QrKXcyCt641LC5uyrpsJfwPxPt3CzBH_CDkSaaA43GIG8gzhileKFzf469raoE8xxjBaMdmWTBsF3A03RKjLAvwXVxyKFlYfFyNjL13iHXy2yerp4EIRUTPsIFjJM-0eAUTdhLbuVMZfClFyySreT0ALE9Agvv0_Cl5ehoT00geindwo8Wqkv2QrQHYYvpuPEL7DoqyZNpFPDvAfrmohhRbGnFz59HOelUxx2GhlsmvFyrLOAEpEHJnYWxj5WovcJmLFOUBJo9VsoFlgE__QPtwPH5bm3giI4Lv95lBtdMPG1ijPW9EQCXpKFpN7cja2vGvsXUfeNfGu4wk4AUQSa1AhW670Kyu7nxO-kzkvPGH7EufKLl2VnZF_aprQ4xYGa7NLp9ZHPrtwbXZhMF1hPLVoiFZnGk7dJ5oxxaszRVP_xbPVjFZnisfB0Ws6Ykos04yV5RJQQJabRGkvG610LQwaucA9cc1LXnGpnX8mDpd6f5VdWQ7csYlLXcMeefq7_ZfUlyZ2-DdwGhyfDLO9odTl_zwfFAythjH2B7nw7xSvLqOoHTUi5aK27Y7jQZaANw4N4aZ1bSQbBlvdzPp4Q9cNlSnuhGTqsWj1MEGhxxAFU8dBq4cIuoRIMEUetHpoIOw55wLsILI6x0vWChfDH8WrcyQjjjOUQ3R1jvGc40hHF4_8XSuWrcSSzpikv4iJ75HYYcEYA0cAaNX10-kF6CzYDrWWqUu3Fa-y5mPbBOaflWwojfC1NloqFwf6VVf-JExjBMNFmMbDdQgLVrbcQ-yjgiU78tIKGvqFIg5NV_Rjf6bobhTP--YXEZcnASLUN3xfIp-FMyzZ2aGkH2paustCwqEXpvamR6QHr6xqYFvqSwWCXGRe1ROhG27uX1WNRl9JPNI8WkFzHC6amIwYkTUYJb2FsJ8Qcbxo46G7xsmSjXE0NTJdNnI8iqWrkenYyMnYyNFI92QN3Ykv7PqgEc7gL3KgYYJ15HE-sEThtK6JLhaO_XHoCwCE_Xo-GoniIqCsWT6bFVmhWClOEvpuEUW_Ab0jMtXf2chPXFH8Bd0jv0uM_LWO6Ce6xzd0T651sp1zwW7-3mwtEif9fWPccVkbOecqjFLXQUPoRT689VvLv9bGZOZjcxuTr_gX8fs3cmHR6lpxT9PUn3LDufqtP1-meCT3bSQkq0Cu7yHkhhMuCzPKfCReFf-NMPQ3tGjxV1u0fkdl2qIROm_R-t0Qz4puO2PUosXBrEVzuxAjUnE4bdHcIEvAH4cWW7Q4nLdo8boNzLRFI3QaUfHqTUyMPYYxmoZ5vHoPE0c3W7R49fYlJp-3aPHq7Ut8aV_QYosWr7ubaHUYcZy1aPHqG4px8kmL5sMaDXxYo8EKsJYOBT3xKxkaLlWb6VDRp4sVPYkn1SZFi9UmDZdLeopG5SUdV_jpqKSneAXdabBo5FFZS9dIZHTYu6I-zFKyaOShpKd0sW3CUyPHy0YmyyU9jcdGHlf46Vh3uobufs6g6282zEt6mk5LeudxPjQmwTQP0iF5Ub_qSMIvlFzU31NIfKxI0O2yNgmXq64E_4ZyM4lm-odToEvIF3RP_P3sZKRH_Inu5Ibu9AdK-gSNy6DEOVeRi9droZsMoZf4-Jas31rG6dTG6ay1nPthOiv702DJD9OvlP6J31qmt0r_xH9_ld4o_dNZ6e8AZTktjVAjXQUxR8LMSn8afjFHpmuU_tc8obhewU-cfJczCP5r3GEL8qUqhXrJRMEy_vL_vZydvmD19hF-QlgwecvpnMR_-bL-3sOsoCS_hsWogvw1LPwop7-Gxcxa62dXvFh0r4-eeLHUDtffecHzCvv6Gt3mnbVPUkReIE1ORlyuqZ9EfRD3rsPAS3cO01d56-5jyiTGDdwZRFpELAOTj520ZyDhg9aqNVAra2PEI8v-hrIuFOdQ1p18EzKHb6Is-0NaFa9q9QFQwtSp4pWZqDjL35TQ15cZ0yMwn72WkTUrBWst-0Z3ikNLq5blx6DjfIhhOYzoDSdCKKqKqZNFVYSDf6dx-yGzq-Jtw7OuZJodS75oBVnLudqf1j-9eKNtLqa1EsdO89ZK7rIX3a2zJNczc2M24ads_p0d4NTTUOjW3h7Z2hYlOw25OTSZD4XBfEbgjRAYwf60YwgQOvBjd4JPsqjhX1y1_Rne_o0b9s8E7joN385cwieHDULD4wfMANrZf3v4BE-1hm-qlieoeNuVegu9c2xZnXP_EBt_19yeUUR7gNA1bVsXv5Hz3UE7QwU_PPPqT14ceJsp0Wh7uvFSBLqj1uhhD9B-COCFvx8l92APhe4WIUBIDSsm5HBEd1BnYG9fjUIhNUYvGj7bFcEXYtPnf9jn6MqsH-UCoWL6AZDdsz1kt_vDwpjzPEB3fTnoihZAd2jyHV--08Nt-vsx_dnAVufObkwp9gHwXkgdRy9Xc7GDqAapns3dP3x-XyCQfUpgIDNfwtnCPdglufRKZhGtAQ3GH0Tlr-mX6O0X6RlXszKPfKSnesOdAYr3BsV7x3NRGT-Mbs2JXSyXuTPoe4D7U_gm5swjsrdRfNWq06IU-sNNa5SQ-plpJd4BSvZTn76eAYZdy_PeIlDXkMuMNW1nT67OwsWdAU72e_ANgSQAadr2KGDiX8isVopnegu_1_XfLSzF3_aAsYOHtq44rIui5XoL97A9112ZwyOHzBRcD8h4pBV3P0BQ3emm025iZfJ_zjRzKFQYfNVnpu0B5p6vfW5YHflZyHz73fEXrQ9JVwv21thD9wOM4QPQ_X_gI-IekYVHFIchDLYoNl3--FGSBAkMtmFo-mm6v6z7f58_jJ2MbeCZNQ2XQp5ssMgcZkxCJj9qyeGZlw2s-HD4-_Euv8d5ilN2x-9DGiIcpzQM7s73Ic-LIgrjY5DzgtOA0ShKgijIoyjMkzi5E_coQFEQBXGAQhKk2yApGM9oFORHEjHCQBTwiolya1NfrU53om07fp_QhJA72-629-7nCCbQ3A8P7tS9PXt-7E6tqRxEq9srAS10aX_P9Pz96U-Hc8NBa3IwJjjxcS5zjmczn5lifxpkix8vCeLHu06V92etG-tX6BGgx5PQ5-64zeoKoEd7Etx9bBpV_w_PNECPVpsWoEer0P8FAAD__8yCvKY">