Skip to content

Commit 6136a9f

Browse files
gitoleglanza
authored andcommitted
[CIR][Lowering] Fix function ptr field lowering in a global struct (llvm#353)
This PR fixes a global vars lowering with a funciton ptr field. Previously, the next code caused fail in the `foo` lowering: ``` static void myfun(int a) {} static struct { void (*func)(int flag); } const Handlers[] = { {myfun}, {myfun}, {myfun} }; void foo(int i, int flag) { Handlers[i].func(flag); } ```
1 parent 6dcb08b commit 6136a9f

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,11 @@ mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp,
229229
} else if (auto llvmFun = dyn_cast<mlir::LLVM::LLVMFuncOp>(sourceSymbol)) {
230230
sourceType = llvmFun.getFunctionType();
231231
symName = llvmFun.getSymName();
232-
} else {
232+
} else if (auto fun = dyn_cast<mlir::cir::FuncOp>(sourceSymbol)) {
233+
sourceType = converter->convertType(fun.getFunctionType());
234+
symName = fun.getSymName();
235+
}
236+
else {
233237
llvm_unreachable("Unexpected GlobalOp type");
234238
}
235239

clang/test/CIR/Lowering/globals.cir

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=MLIR
33
// RUN: cir-translate %s -cir-to-llvmir -o %t.ll
44
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
// XFAIL: *
56

7+
!void = !cir.void
68
!s16i = !cir.int<s, 16>
79
!s32i = !cir.int<s, 32>
810
!s64i = !cir.int<s, 64>
@@ -14,6 +16,7 @@
1416
!ty_22Bar22 = !cir.struct<struct "Bar" {!s32i, !s8i} #cir.record.decl.ast>
1517
!ty_22StringStruct22 = !cir.struct<struct "StringStruct" {!cir.array<!s8i x 3>, !cir.array<!s8i x 3>, !cir.array<!s8i x 3>} #cir.record.decl.ast>
1618
!ty_22StringStructPtr22 = !cir.struct<struct "StringStructPtr" {!cir.ptr<!s8i>} #cir.record.decl.ast>
19+
!ty_22anon2E122 = !cir.struct<struct "anon.1" {!cir.ptr<!cir.func<!cir.void (!cir.int<s, 32>)>>} #cir.record.decl.ast>
1720

1821
module {
1922
cir.global external @a = #cir.int<3> : !s32i
@@ -146,4 +149,33 @@ module {
146149
// MLIR: }
147150
cir.global common @comm = #cir.int<0> : !s32i
148151
// MLIR: llvm.mlir.global common @comm(0 : i32) {addr_space = 0 : i32} : i32
149-
}
152+
153+
cir.global "private" internal @Handlers = #cir.const_array<[#cir.const_struct<{#cir.global_view<@myfun> : !cir.ptr<!cir.func<!void (!s32i)>>}> : !ty_22anon2E122]> : !cir.array<!ty_22anon2E122 x 1>
154+
cir.func internal private @myfun(%arg0: !s32i) {
155+
%0 = cir.alloca !s32i, cir.ptr <!s32i>, ["a", init] {alignment = 4 : i64}
156+
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>
157+
cir.return
158+
}
159+
cir.func @foo(%arg0: !s32i, %arg1: !s32i) {
160+
%0 = cir.alloca !s32i, cir.ptr <!s32i>, ["i", init] {alignment = 4 : i64}
161+
%1 = cir.alloca !s32i, cir.ptr <!s32i>, ["flag", init] {alignment = 4 : i64}
162+
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>
163+
cir.store %arg1, %1 : !s32i, cir.ptr <!s32i>
164+
%2 = cir.get_global @Handlers : cir.ptr <!cir.array<!ty_22anon2E122 x 1>>
165+
%3 = cir.load %0 : cir.ptr <!s32i>, !s32i
166+
%4 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr<!cir.array<!ty_22anon2E122 x 1>>), !cir.ptr<!ty_22anon2E122>
167+
%5 = cir.ptr_stride(%4 : !cir.ptr<!ty_22anon2E122>, %3 : !s32i), !cir.ptr<!ty_22anon2E122>
168+
%6 = cir.get_member %5[0] {name = "func"} : !cir.ptr<!ty_22anon2E122> -> !cir.ptr<!cir.ptr<!cir.func<!void (!s32i)>>>
169+
%7 = cir.load %6 : cir.ptr <!cir.ptr<!cir.func<!void (!s32i)>>>, !cir.ptr<!cir.func<!void (!s32i)>>
170+
%8 = cir.load %1 : cir.ptr <!s32i>, !s32i
171+
cir.call %7(%8) : (!cir.ptr<!cir.func<!void (!s32i)>>, !s32i) -> ()
172+
cir.return
173+
}
174+
//MLIR: %[[RES4:.*]] = llvm.mlir.addressof @Handlers : !llvm.ptr
175+
//MLIR: %[[RES5:.*]] = llvm.load {{.*}} : !llvm.ptr -> i32
176+
//MLIR: %[[RES6:.*]] = llvm.getelementptr %[[RES4]][0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.anon.1", (ptr)>
177+
//MLIR: %[[RES7:.*]] = llvm.getelementptr %[[RES6]][%[[RES5]]] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.anon.1", (ptr)>
178+
//MLIR: %[[RES8:.*]] = llvm.getelementptr %[[RES7]][0, 0] : (!llvm.ptr) -> !llvm.ptr, !llvm.struct<"struct.anon.1", (ptr)>
179+
//MLIR: %[[RES9:.*]] = llvm.load %[[RES8]] : !llvm.ptr -> !llvm.ptr
180+
//MLIR: llvm.call %[[RES9]]({{.*}}) : !llvm.ptr, (i32) -> ()
181+
}

0 commit comments

Comments
 (0)