Skip to content

Commit 94e8d43

Browse files
committed
Address code review comments
1 parent 5715179 commit 94e8d43

File tree

4 files changed

+108
-19
lines changed

4 files changed

+108
-19
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4615,22 +4615,31 @@ def CIR_EhInflightOp : CIR_Op<"eh.inflight_exception"> {
46154615
let description = [{
46164616
`cir.eh.inflight_exception` returns two values:
46174617
- `exception_ptr`: The exception pointer for the inflight exception
4618-
- `type_id`: pointer to the exception object
4619-
This operation is expected to be the first one basic blocks on the
4620-
exception path out of `cir.try_call` operations.
4618+
- `type_id`: the type info index for the exception type
4619+
This operation is expected to be the first operation in the unwind
4620+
destination basic blocks of a `cir.try_call` operation.
46214621

4622-
The `cleanup` attribute indicates that clean up code might run before the
4623-
values produced by this operation are used to gather exception information.
4622+
The `cleanup` attribute indicates that clean up code must be run before the
4623+
values produced by this operation are used to dispatch the exception. This
4624+
cleanup code must be executed even if the exception is not caught.
46244625
This helps CIR to pass down more accurate information for LLVM lowering
46254626
to landingpads.
4627+
4628+
Example:
4629+
4630+
```mlir
4631+
%exception_ptr, %type_id = cir.eh.inflight_exception
4632+
%exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc]
4633+
%exception_ptr, %type_id = cir.eh.inflight_exception cleanup
4634+
``
46264635
}];
46274636

46284637
let arguments = (ins UnitAttr:$cleanup,
4629-
OptionalAttr<FlatSymbolRefArrayAttr>:$sym_type_list);
4638+
OptionalAttr<FlatSymbolRefArrayAttr>:$catch_type_list);
46304639
let results = (outs CIR_VoidPtrType:$exception_ptr, CIR_UInt32:$type_id);
46314640
let assemblyFormat = [{
46324641
(`cleanup` $cleanup^)?
4633-
($sym_type_list^)?
4642+
($catch_type_list^)?
46344643
attr-dict
46354644
}];
46364645
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3082,42 +3082,44 @@ mlir::LogicalResult CIRToLLVMEhInflightOpLowering::matchAndRewrite(
30823082
mlir::Block *entryBlock = &llvmFn.getRegion().front();
30833083
assert(entryBlock->isEntryBlock());
30843084

3085-
mlir::ArrayAttr symListAttr = op.getSymTypeListAttr();
3086-
mlir::SmallVector<mlir::Value, 4> symAddrs;
3085+
mlir::ArrayAttr catchListAttr = op.getCatchTypeListAttr();
3086+
mlir::SmallVector<mlir::Value> catchSymAddrs;
30873087

30883088
auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
30893089
mlir::Location loc = op.getLoc();
30903090

30913091
// %landingpad = landingpad { ptr, i32 }
30923092
// Note that since llvm.landingpad has to be the first operation on the
30933093
// block, any needed value for its operands has to be added somewhere else.
3094-
if (symListAttr) {
3094+
if (catchListAttr) {
30953095
// catch ptr @_ZTIi
30963096
// catch ptr @_ZTIPKc
3097-
for (mlir::Attribute attr : symListAttr) {
3098-
auto symAttr = cast<mlir::FlatSymbolRefAttr>(attr);
3097+
for (mlir::Attribute catchAttr : catchListAttr) {
3098+
auto symAttr = cast<mlir::FlatSymbolRefAttr>(catchAttr);
30993099
// Generate `llvm.mlir.addressof` for each symbol, and place those
31003100
// operations in the LLVM function entry basic block.
31013101
mlir::OpBuilder::InsertionGuard guard(rewriter);
31023102
rewriter.setInsertionPointToStart(entryBlock);
31033103
mlir::Value addrOp = mlir::LLVM::AddressOfOp::create(
31043104
rewriter, loc, llvmPtrTy, symAttr.getValue());
3105-
symAddrs.push_back(addrOp);
3105+
catchSymAddrs.push_back(addrOp);
31063106
}
31073107
} else if (!op.getCleanup()) {
3108-
// catch ptr null
3108+
// We need to emit catch-all only if cleanup is not set, because when we
3109+
// have catch-all handler, there is no case when we set would unwind past
3110+
// the handler
31093111
mlir::OpBuilder::InsertionGuard guard(rewriter);
31103112
rewriter.setInsertionPointToStart(entryBlock);
31113113
mlir::Value nullOp = mlir::LLVM::ZeroOp::create(rewriter, loc, llvmPtrTy);
3112-
symAddrs.push_back(nullOp);
3114+
catchSymAddrs.push_back(nullOp);
31133115
}
31143116

31153117
// %slot = extractvalue { ptr, i32 } %x, 0
31163118
// %selector = extractvalue { ptr, i32 } %x, 1
31173119
mlir::LLVM::LLVMStructType llvmLandingPadStructTy =
31183120
getLLVMLandingPadStructTy(rewriter);
31193121
auto landingPadOp = mlir::LLVM::LandingpadOp::create(
3120-
rewriter, loc, llvmLandingPadStructTy, symAddrs);
3122+
rewriter, loc, llvmLandingPadStructTy, catchSymAddrs);
31213123

31223124
if (op.getCleanup())
31233125
landingPadOp.setCleanup(true);
@@ -3139,7 +3141,7 @@ mlir::LogicalResult CIRToLLVMEhInflightOpLowering::matchAndRewrite(
31393141
auto personalityFnTy =
31403142
mlir::LLVM::LLVMFunctionType::get(rewriter.getI32Type(), {},
31413143
/*isVarArg=*/true);
3142-
// Get or create `__gxx_personality_v0`
3144+
31433145
const StringRef fnName = "__gxx_personality_v0";
31443146
createLLVMFuncOpIfNotExist(rewriter, op, fnName, personalityFnTy);
31453147
llvmFn.setPersonality(fnName);

clang/test/CIR/IR/eh-inflight.cir

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
11
// RUN: cir-opt %s --verify-roundtrip | FileCheck %s
22

3+
!u8i = !cir.int<u, 8>
4+
35
module {
46

5-
cir.func dso_local @function_with_inflight_exception() {
7+
cir.func dso_local @inflight_exception() {
68
%exception_ptr, %type_id = cir.eh.inflight_exception
79
cir.return
810
}
911

10-
// CHECK: cir.func dso_local @function_with_inflight_exception() {
12+
// CHECK: cir.func dso_local @inflight_exception() {
1113
// CHECK: %exception_ptr, %type_id = cir.eh.inflight_exception
1214
// CHECK: cir.return
1315
// CHECK: }
1416

17+
cir.func dso_local @inflight_exception_with_cleanup() {
18+
%exception_ptr, %type_id = cir.eh.inflight_exception cleanup
19+
cir.return
20+
}
21+
22+
// CHECK: cir.func dso_local @inflight_exception_with_cleanup() {
23+
// CHECK: %exception_ptr, %type_id = cir.eh.inflight_exception cleanup
24+
// CHECK: cir.return
25+
// CHECK: }
26+
27+
cir.global "private" constant external @_ZTIi : !cir.ptr<!u8i>
28+
cir.global "private" constant external @_ZTIPKc : !cir.ptr<!u8i>
29+
30+
cir.func dso_local @inflight_exception_with_catch_type_list() {
31+
%exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc]
32+
cir.return
33+
}
34+
35+
// CHECK: cir.func dso_local @inflight_exception_with_catch_type_list() {
36+
// CHECK: %exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc]
37+
// CHECK: cir.return
38+
// CHECK:}
39+
1540
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: cir-opt %s -cir-to-llvm -o %t.cir
2+
3+
!u8i = !cir.int<u, 8>
4+
5+
module {
6+
7+
// CHECK: llvm.func @__gxx_personality_v0(...) -> i32
8+
9+
cir.func @inflight_exception() {
10+
%exception_ptr, %type_id = cir.eh.inflight_exception
11+
cir.return
12+
}
13+
14+
// CHECK: llvm.func @inflight_exception() attributes {personality = @__gxx_personality_v0} {
15+
// CHECK: %[[CONST_0:.*]] = llvm.mlir.zero : !llvm.ptr
16+
// CHECK: %[[LP:.*]] = llvm.landingpad (catch %[[CONST_0]] : !llvm.ptr) : !llvm.struct<(ptr, i32)>
17+
// CHECK: %[[EXCEPTION_PTR:.*]] = llvm.extractvalue %[[LP]][0] : !llvm.struct<(ptr, i32)>
18+
// CHECK: %[[TYPE_ID:.*]] = llvm.extractvalue %[[LP]][1] : !llvm.struct<(ptr, i32)>
19+
// CHECK: llvm.return
20+
// CHECK: }
21+
22+
cir.func @inflight_exception_with_cleanup() {
23+
%exception_ptr, %type_id = cir.eh.inflight_exception cleanup
24+
cir.return
25+
}
26+
27+
// CHECK: llvm.func @inflight_exception_with_cleanup() attributes {personality = @__gxx_personality_v0} {
28+
// CHECK: %[[LP:.*]] = llvm.landingpad cleanup : !llvm.struct<(ptr, i32)>
29+
// CHECK: %[[EXCEPTION_PTR:.*]] = llvm.extractvalue %[[LP]][0] : !llvm.struct<(ptr, i32)>
30+
// CHECK: %[[TYPE_ID:.*]] = llvm.extractvalue %[[LP]][1] : !llvm.struct<(ptr, i32)>
31+
// CHECK: llvm.return
32+
// CHECK: }
33+
34+
35+
cir.global "private" constant external @_ZTIi : !cir.ptr<!u8i>
36+
cir.global "private" constant external @_ZTIPKc : !cir.ptr<!u8i>
37+
38+
cir.func @inflight_exception_with_catch_type_list() {
39+
%exception_ptr, %type_id = cir.eh.inflight_exception [@_ZTIi, @_ZTIPKc]
40+
cir.return
41+
}
42+
43+
// CHECK: llvm.func @inflight_exception_with_catch_type_list() attributes {personality = @__gxx_personality_v0} {
44+
// CHECK: %[[TI_1_ADDR:.*]] = llvm.mlir.addressof @_ZTIPKc : !llvm.ptr
45+
// CHECK: %[[TI_2_ADDR:.*]] = llvm.mlir.addressof @_ZTIi : !llvm.ptr
46+
// CHECK: %[[LP:.*]] = llvm.landingpad (catch %[[TI_2_ADDR]] : !llvm.ptr) (catch %[[TI_1_ADDR]] : !llvm.ptr) : !llvm.struct<(ptr, i32)>
47+
// CHECK: %[[EXCEPTION_PTR:.*]] = llvm.extractvalue %[[LP]][0] : !llvm.struct<(ptr, i32)>
48+
// CHECK: %[[TYPE_ID:.*]] = llvm.extractvalue %[[LP]][1] : !llvm.struct<(ptr, i32)>
49+
// CHECK: llvm.return
50+
// CHECK: }
51+
52+
53+
}

0 commit comments

Comments
 (0)