clangir icon indicating copy to clipboard operation
clangir copied to clipboard

[ThroughMLIR] can not lower c array correctly

Open wenhu1024 opened this issue 10 months ago • 5 comments

here is arr.c

int testArr(int a){
        int nums[3];
        nums[0]=a;
        return nums[0];
}

then i want to get mlir through cir

./bin/clang -cc1 -triple x86_64-unknown-linux-gnu -fclangir -fno-clangir-direct-lowering -emit-mlir arr.c

but i got something wrong

loc("arr.c":3:2): error: failed to legalize unresolved materialization from ('memref<memref<3xi32>>') to ('memref<3xi32>') that remained live after conversion
fatal error: error in backend: The pass manager failed to lower CIR to MLIR standard dialects!

and the CIR is here

!s32i = !cir.int<s, 32>
#fn_attr = #cir<extra({inline = #cir.inline<no>, nothrow = #cir.nothrow, optnone = #cir.optnone, uwtable = #cir.uwtable<async>})>
#loc3 = loc("arr.c":1:13)
#loc4 = loc("arr.c":1:17)
#loc16 = loc(fused[#loc3, #loc4])
module @"/home/wenhu/work/clangir/build/ARR/arr.c" attributes {cir.lang = #cir.lang<c>, cir.sob = #cir.signed_overflow_behavior<undefined>, cir.triple = "x86_64-unknown-linux-gnu", cir.uwtable = #cir.uwtable<async>, dlti.dl_spec = #dlti.dl_spec<i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i16 = dense<16> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">} {
  cir.func @testArr(%arg0: !s32i loc(fused[#loc3, #loc4])) -> !s32i extra(#fn_attr) {
    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init] {alignment = 4 : i64} loc(#loc16)
    %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64} loc(#loc2)
    %2 = cir.alloca !cir.array<!s32i x 3>, !cir.ptr<!cir.array<!s32i x 3>>, ["nums"] {alignment = 4 : i64} loc(#loc17)
    cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i> loc(#loc7)
    %3 = cir.load %0 : !cir.ptr<!s32i>, !s32i loc(#loc8)
    %4 = cir.const #cir.int<0> : !s32i loc(#loc9)
    %5 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i> loc(#loc10)
    %6 = cir.ptr_stride(%5 : !cir.ptr<!s32i>, %4 : !s32i), !cir.ptr<!s32i> loc(#loc10)
    cir.store %3, %6 : !s32i, !cir.ptr<!s32i> loc(#loc18)
    %7 = cir.const #cir.int<0> : !s32i loc(#loc11)
    %8 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!s32i x 3>>), !cir.ptr<!s32i> loc(#loc12)
    %9 = cir.ptr_stride(%8 : !cir.ptr<!s32i>, %7 : !s32i), !cir.ptr<!s32i> loc(#loc12)
    %10 = cir.load %9 : !cir.ptr<!s32i>, !s32i loc(#loc12)
    cir.store %10, %1 : !s32i, !cir.ptr<!s32i> loc(#loc19)
    %11 = cir.load %1 : !cir.ptr<!s32i>, !s32i loc(#loc19)
    cir.return %11 : !s32i loc(#loc19)
  } loc(#loc15)
} loc(#loc)
#loc = loc("/home/wenhu/work/clangir/build/ARR/arr.c":0:0)
#loc1 = loc("arr.c":1:1)
#loc2 = loc("arr.c":5:1)
#loc5 = loc("arr.c":2:2)
#loc6 = loc("arr.c":2:12)
#loc7 = loc("arr.c":1:19)
#loc8 = loc("arr.c":3:10)
#loc9 = loc("arr.c":3:7)
#loc10 = loc("arr.c":3:2)
#loc11 = loc("arr.c":4:14)
#loc12 = loc("arr.c":4:9)
#loc13 = loc("arr.c":4:2)
#loc14 = loc("arr.c":4:15)
#loc15 = loc(fused[#loc1, #loc2])
#loc17 = loc(fused[#loc5, #loc6])
#loc18 = loc(fused[#loc10, #loc8])
#loc19 = loc(fused[#loc13, #loc14])

wenhu1024 avatar Feb 25 '25 08:02 wenhu1024

hi @wenhu1024, thank you for reporting this issue.

I submitted https://github.com/llvm/clangir/pull/1412 . However, with my patch, I am still encountering an error:

$ ./bin/clang -fclangir -fno-clangir-direct-lowering test.c -Xclang -emit-mlir -o test.mlir -c
loc("test.c":4:16): error: expected result type with offset = dynamic instead of 0
fatal error: error in backend: The pass manager failed to lower CIR to MLIR standard dialects!

PikachuHyA avatar Feb 26 '25 08:02 PikachuHyA

(cc @keryell)

bcardosolopes avatar Feb 26 '25 19:02 bcardosolopes

I do not think the CIR -> MLIR lowering is in a usable state currently, unfortunately. 😦 Do you need it for some project? I have some experiments with https://github.com/llvm/clangir/pull/1334 if you want to try. But at some point we need some support from MLIR core infrastructure @joker-eph to go beyond what MLIR standard dialect can support, which is mostly Fortran77 plus some F90 arrays...

keryell avatar Feb 26 '25 23:02 keryell

I do not think the CIR -> MLIR lowering is in a usable state currently, unfortunately. 😦

Yes,I find the CIR -> MLIR lowering can not work. 😢

Do you need it for some project?

No, I just take a look.

I have some experiments with #1334 if you want to try. But at some point we need some support from MLIR core infrastructure @joker-eph to go beyond what MLIR standard dialect can support, which is mostly Fortran77 plus some F90 arrays...

It seems that enabling the CIR -> MLIR lowering requires support from the upstream MLIR core infrastructure. It appears to be a significant amount of work.

wenhu1024 avatar Feb 27 '25 02:02 wenhu1024

from https://github.com/llvm/clangir/pull/1412#issuecomment-2685417970

it seems that currently we lower !cir.array to !memref. This looks strange since !memref looks more like !cir.ptr<!cir.array> to me. Maybe we should fix this in later changes?

I'm unsure how to properly handle !cir.array. During debugging, I found that https://github.com/llvm/clangir/pull/574 works for global arrays but fails for local ones. The GlobalOp has special handling for !memref.

see https://github.com/llvm/clangir/blob/main/clang/lib/CIR/Lowering/ThroughMLIR/LowerCIRToMLIR.cpp#L980-L985

PikachuHyA avatar Mar 03 '25 12:03 PikachuHyA