<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">