// RUN: MxNet-opt --mxnet-to-llvm %s | FileCheck %s
// CHECK-LABEL: func.func @var_mean
func.func @var_mean(%tensorA:tensor<3x3xf32>)-> (tensor<3x1xf32>,tensor<3x1xf32>) {
%result1, %result2 = "MxNet.var_mean"( %tensorA ) {axes = array<i32 : 1>, keepdim=1:i1} : ( tensor<3x3xf32>) -> (tensor<3x1xf32>,tensor<3x1xf32>)
return %result1, %result2 : tensor<3x1xf32>,tensor<3x1xf32>
}
LLVM IR
module {
llvm.func @free(!llvm.ptr)
llvm.func @malloc(i64) -> !llvm.ptr
llvm.mlir.global private constant @__constant_3x1xf32_0(dense<3.000000e+00> : tensor<3x1xf32>) {addr_space = 0 : i32, alignment = 64 : i64} : !llvm.array<3 x array<1 x f32>>
llvm.mlir.global private constant @__constant_3x1xf32(dense<2.000000e+00> : tensor<3x1xf32>) {addr_space = 0 : i32, alignment = 64 : i64} : !llvm.array<3 x array<1 x f32>>
llvm.func @var_mean(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: i64, %arg6: i64) -> !llvm.struct<(struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>, struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>)> {
%0 = llvm.mlir.undef : !llvm.struct<(struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>, struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>)>
%1 = llvm.mlir.constant(64 : index) : i64
%2 = llvm.mlir.addressof @__constant_3x1xf32_0 : !llvm.ptr
%3 = llvm.mlir.addressof @__constant_3x1xf32 : !llvm.ptr
%4 = llvm.mlir.zero : !llvm.ptr
%5 = llvm.mlir.constant(0.000000e+00 : f32) : f32
%6 = llvm.mlir.constant(0 : index) : i64
%7 = llvm.mlir.constant(3 : index) : i64
%8 = llvm.mlir.constant(1 : index) : i64
%9 = llvm.mlir.undef : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%10 = llvm.getelementptr %3[0, 0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<3 x array<1 x f32>>
%11 = llvm.getelementptr %2[0, 0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<3 x array<1 x f32>>
%12 = llvm.getelementptr %4[3] : (!llvm.ptr) -> !llvm.ptr, f32
%13 = llvm.ptrtoint %12 : !llvm.ptr to i64
%14 = llvm.add %13, %1 : i64
%15 = llvm.call @malloc(%14) : (i64) -> !llvm.ptr
%16 = llvm.ptrtoint %15 : !llvm.ptr to i64
%17 = llvm.sub %1, %8 : i64
%18 = llvm.add %16, %17 : i64
%19 = llvm.urem %18, %1 : i64
%20 = llvm.sub %18, %19 : i64
%21 = llvm.inttoptr %20 : i64 to !llvm.ptr
llvm.br ^bb1(%6 : i64)
^bb1(%22: i64): // 2 preds: ^bb0, ^bb2
%23 = llvm.icmp "slt" %22, %7 : i64
llvm.cond_br %23, ^bb2, ^bb3
^bb2: // pred: ^bb1
%24 = llvm.getelementptr %21[%22] : (!llvm.ptr, i64) -> !llvm.ptr, f32
llvm.store %5, %24 : f32, !llvm.ptr
%25 = llvm.add %22, %8 : i64
llvm.br ^bb1(%25 : i64)
^bb3: // pred: ^bb1
llvm.br ^bb4(%6 : i64)
^bb4(%26: i64): // 2 preds: ^bb3, ^bb8
%27 = llvm.icmp "slt" %26, %7 : i64
llvm.cond_br %27, ^bb5, ^bb9
^bb5: // pred: ^bb4
llvm.br ^bb6(%6 : i64)
^bb6(%28: i64): // 2 preds: ^bb5, ^bb7
%29 = llvm.icmp "slt" %28, %7 : i64
llvm.cond_br %29, ^bb7, ^bb8
^bb7: // pred: ^bb6
%30 = llvm.getelementptr %arg1[%arg2] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%31 = llvm.mul %26, %arg5 : i64
%32 = llvm.mul %28, %arg6 : i64
%33 = llvm.add %31, %32 : i64
%34 = llvm.getelementptr %30[%33] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%35 = llvm.load %34 : !llvm.ptr -> f32
%36 = llvm.getelementptr %21[%26] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%37 = llvm.load %36 : !llvm.ptr -> f32
%38 = llvm.fadd %35, %37 : f32
llvm.store %38, %36 : f32, !llvm.ptr
%39 = llvm.add %28, %8 : i64
llvm.br ^bb6(%39 : i64)
^bb8: // pred: ^bb6
%40 = llvm.add %26, %8 : i64
llvm.br ^bb4(%40 : i64)
^bb9: // pred: ^bb4
%41 = llvm.insertvalue %15, %9[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%42 = llvm.insertvalue %21, %41[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%43 = llvm.insertvalue %6, %42[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%44 = llvm.insertvalue %7, %43[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%45 = llvm.insertvalue %8, %44[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%46 = llvm.insertvalue %8, %45[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%47 = llvm.insertvalue %8, %46[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
llvm.br ^bb10(%6 : i64)
^bb10(%48: i64): // 2 preds: ^bb9, ^bb14
%49 = llvm.icmp "slt" %48, %7 : i64
llvm.cond_br %49, ^bb11, ^bb15
^bb11: // pred: ^bb10
llvm.br ^bb12(%6 : i64)
^bb12(%50: i64): // 2 preds: ^bb11, ^bb13
%51 = llvm.icmp "slt" %50, %8 : i64
llvm.cond_br %51, ^bb13, ^bb14
^bb13: // pred: ^bb12
%52 = llvm.add %48, %50 : i64
%53 = llvm.getelementptr %21[%52] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%54 = llvm.load %53 : !llvm.ptr -> f32
%55 = llvm.getelementptr %11[%52] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%56 = llvm.load %55 : !llvm.ptr -> f32
%57 = llvm.fdiv %54, %56 : f32
llvm.store %57, %53 : f32, !llvm.ptr
%58 = llvm.add %50, %8 : i64
llvm.br ^bb12(%58 : i64)
^bb14: // pred: ^bb12
%59 = llvm.add %48, %8 : i64
llvm.br ^bb10(%59 : i64)
^bb15: // pred: ^bb10
%60 = llvm.getelementptr %4[9] : (!llvm.ptr) -> !llvm.ptr, f32
%61 = llvm.ptrtoint %60 : !llvm.ptr to i64
%62 = llvm.add %61, %1 : i64
%63 = llvm.call @malloc(%62) : (i64) -> !llvm.ptr
%64 = llvm.ptrtoint %63 : !llvm.ptr to i64
%65 = llvm.add %64, %17 : i64
%66 = llvm.urem %65, %1 : i64
%67 = llvm.sub %65, %66 : i64
%68 = llvm.inttoptr %67 : i64 to !llvm.ptr
llvm.br ^bb16(%6 : i64)
^bb16(%69: i64): // 2 preds: ^bb15, ^bb20
%70 = llvm.icmp "slt" %69, %7 : i64
llvm.cond_br %70, ^bb17, ^bb21
^bb17: // pred: ^bb16
llvm.br ^bb18(%6 : i64)
^bb18(%71: i64): // 2 preds: ^bb17, ^bb19
%72 = llvm.icmp "slt" %71, %7 : i64
llvm.cond_br %72, ^bb19, ^bb20
^bb19: // pred: ^bb18
%73 = llvm.getelementptr %arg1[%arg2] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%74 = llvm.mul %69, %arg5 : i64
%75 = llvm.mul %71, %arg6 : i64
%76 = llvm.add %74, %75 : i64
%77 = llvm.getelementptr %73[%76] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%78 = llvm.load %77 : !llvm.ptr -> f32
%79 = llvm.add %69, %6 : i64
%80 = llvm.getelementptr %21[%79] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%81 = llvm.load %80 : !llvm.ptr -> f32
%82 = llvm.fsub %78, %81 : f32
%83 = llvm.mul %69, %7 : i64
%84 = llvm.add %83, %71 : i64
%85 = llvm.getelementptr %68[%84] : (!llvm.ptr, i64) -> !llvm.ptr, f32
llvm.store %82, %85 : f32, !llvm.ptr
%86 = llvm.add %71, %8 : i64
llvm.br ^bb18(%86 : i64)
^bb20: // pred: ^bb18
%87 = llvm.add %69, %8 : i64
llvm.br ^bb16(%87 : i64)
^bb21: // pred: ^bb16
%88 = llvm.call @malloc(%62) : (i64) -> !llvm.ptr
%89 = llvm.ptrtoint %88 : !llvm.ptr to i64
%90 = llvm.add %89, %17 : i64
%91 = llvm.urem %90, %1 : i64
%92 = llvm.sub %90, %91 : i64
%93 = llvm.inttoptr %92 : i64 to !llvm.ptr
llvm.br ^bb22(%6 : i64)
^bb22(%94: i64): // 2 preds: ^bb21, ^bb26
%95 = llvm.icmp "slt" %94, %7 : i64
llvm.cond_br %95, ^bb23, ^bb27
^bb23: // pred: ^bb22
llvm.br ^bb24(%6 : i64)
^bb24(%96: i64): // 2 preds: ^bb23, ^bb25
%97 = llvm.icmp "slt" %96, %7 : i64
llvm.cond_br %97, ^bb25, ^bb26
^bb25: // pred: ^bb24
%98 = llvm.mul %94, %7 : i64
%99 = llvm.add %98, %96 : i64
%100 = llvm.getelementptr %68[%99] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%101 = llvm.load %100 : !llvm.ptr -> f32
%102 = llvm.fmul %101, %101 : f32
%103 = llvm.getelementptr %93[%99] : (!llvm.ptr, i64) -> !llvm.ptr, f32
llvm.store %102, %103 : f32, !llvm.ptr
%104 = llvm.add %96, %8 : i64
llvm.br ^bb24(%104 : i64)
^bb26: // pred: ^bb24
%105 = llvm.add %94, %8 : i64
llvm.br ^bb22(%105 : i64)
^bb27: // pred: ^bb22
%106 = llvm.call @malloc(%14) : (i64) -> !llvm.ptr
%107 = llvm.ptrtoint %106 : !llvm.ptr to i64
%108 = llvm.add %107, %17 : i64
%109 = llvm.urem %108, %1 : i64
%110 = llvm.sub %108, %109 : i64
%111 = llvm.inttoptr %110 : i64 to !llvm.ptr
llvm.br ^bb28(%6 : i64)
^bb28(%112: i64): // 2 preds: ^bb27, ^bb29
%113 = llvm.icmp "slt" %112, %7 : i64
llvm.cond_br %113, ^bb29, ^bb30
^bb29: // pred: ^bb28
%114 = llvm.getelementptr %111[%112] : (!llvm.ptr, i64) -> !llvm.ptr, f32
llvm.store %5, %114 : f32, !llvm.ptr
%115 = llvm.add %112, %8 : i64
llvm.br ^bb28(%115 : i64)
^bb30: // pred: ^bb28
llvm.br ^bb31(%6 : i64)
^bb31(%116: i64): // 2 preds: ^bb30, ^bb35
%117 = llvm.icmp "slt" %116, %7 : i64
llvm.cond_br %117, ^bb32, ^bb36
^bb32: // pred: ^bb31
llvm.br ^bb33(%6 : i64)
^bb33(%118: i64): // 2 preds: ^bb32, ^bb34
%119 = llvm.icmp "slt" %118, %7 : i64
llvm.cond_br %119, ^bb34, ^bb35
^bb34: // pred: ^bb33
%120 = llvm.mul %116, %7 : i64
%121 = llvm.add %120, %118 : i64
%122 = llvm.getelementptr %93[%121] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%123 = llvm.load %122 : !llvm.ptr -> f32
%124 = llvm.getelementptr %111[%116] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%125 = llvm.load %124 : !llvm.ptr -> f32
%126 = llvm.fadd %123, %125 : f32
llvm.store %126, %124 : f32, !llvm.ptr
%127 = llvm.add %118, %8 : i64
llvm.br ^bb33(%127 : i64)
^bb35: // pred: ^bb33
%128 = llvm.add %116, %8 : i64
llvm.br ^bb31(%128 : i64)
^bb36: // pred: ^bb31
%129 = llvm.insertvalue %106, %9[0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%130 = llvm.insertvalue %111, %129[1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%131 = llvm.insertvalue %6, %130[2] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%132 = llvm.insertvalue %7, %131[3, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%133 = llvm.insertvalue %8, %132[4, 0] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%134 = llvm.insertvalue %8, %133[3, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
%135 = llvm.insertvalue %8, %134[4, 1] : !llvm.struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>
llvm.br ^bb37(%6 : i64)
^bb37(%136: i64): // 2 preds: ^bb36, ^bb41
%137 = llvm.icmp "slt" %136, %7 : i64
llvm.cond_br %137, ^bb38, ^bb42
^bb38: // pred: ^bb37
llvm.br ^bb39(%6 : i64)
^bb39(%138: i64): // 2 preds: ^bb38, ^bb40
%139 = llvm.icmp "slt" %138, %8 : i64
llvm.cond_br %139, ^bb40, ^bb41
^bb40: // pred: ^bb39
%140 = llvm.add %136, %138 : i64
%141 = llvm.getelementptr %111[%140] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%142 = llvm.load %141 : !llvm.ptr -> f32
%143 = llvm.getelementptr %10[%140] : (!llvm.ptr, i64) -> !llvm.ptr, f32
%144 = llvm.load %143 : !llvm.ptr -> f32
%145 = llvm.fdiv %142, %144 : f32
llvm.store %145, %141 : f32, !llvm.ptr
%146 = llvm.add %138, %8 : i64
llvm.br ^bb39(%146 : i64)
^bb41: // pred: ^bb39
%147 = llvm.add %136, %8 : i64
llvm.br ^bb37(%147 : i64)
^bb42: // pred: ^bb37
llvm.call @free(%63) : (!llvm.ptr) -> ()
llvm.call @free(%88) : (!llvm.ptr) -> ()
%148 = llvm.insertvalue %135, %0[0] : !llvm.struct<(struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>, struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>)>
%149 = llvm.insertvalue %47, %148[1] : !llvm.struct<(struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>, struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>)>
llvm.return %149 : !llvm.struct<(struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>, struct<(ptr, ptr, i64, array<2 x i64>, array<2 x i64>)>)>
}
}