Skip to content

Commit cce6712

Browse files
bruteforceboylanza
authored andcommitted
[CIR][CodeGen] Implement tryMarkNoThrow and update wrong test (llvm#1664)
This PR introduces [`TryMarkNoThrow`](https://github.com/llvm/clangir/blob/6e5fa09550c98f84d017873ed3e5667fd5fd909c/clang/lib/CodeGen/CodeGenFunction.cpp#L1394). [`isInterposable`](https://github.com/llvm/clangir/blob/6e5fa09550c98f84d017873ed3e5667fd5fd909c/clang/lib/CodeGen/CodeGenFunction.cpp#L1397C10-L1397C26) isn't fully implemented and I'm not quite sure we need it? Anyway, I have introduced a missing feature `getSemanticInterposition` relevant for its completion. I have also updated an old test -- [`foo()`](https://github.com/llvm/clangir/blob/6e5fa09550c98f84d017873ed3e5667fd5fd909c/clang/test/CIR/CodeGen/try-catch-dtors.cpp#L313) should be marked as unwind/nothrow. I have compared with the original CodeGen and attached the llvm output for verification. One concern I have is if the cases I have to mimic [`mayThrow`](https://github.com/llvm/clangir/blob/6e5fa09550c98f84d017873ed3e5667fd5fd909c/llvm/lib/IR/Instruction.cpp#L1158) from the OG are enough, please let me know your thoughts.
1 parent 4c8f291 commit cce6712

File tree

7 files changed

+46
-16
lines changed

7 files changed

+46
-16
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,6 @@ struct MissingFeatures {
239239
static bool emitScalarRangeCheck() { return false; }
240240
static bool stmtExprEvaluation() { return false; }
241241
static bool setCallingConv() { return false; }
242-
static bool tryMarkNoThrow() { return false; }
243242
static bool indirectBranch() { return false; }
244243
static bool escapedLocals() { return false; }
245244
static bool deferredReplacements() { return false; }
@@ -251,6 +250,7 @@ struct MissingFeatures {
251250
static bool createLaunderInvariantGroup() { return false; }
252251
static bool hipModuleCtor() { return false; }
253252
static bool checkMacOSXTriple() { return false; }
253+
static bool getSemanticInterposition() { return false; }
254254

255255
// Inline assembly
256256
static bool asmGoto() { return false; }

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ emitCallLikeOp(CIRGenFunction &CGF, mlir::Location callLoc,
381381
callLoc, directFuncOp, CIRCallArgs, callingConv, sideEffect);
382382
}
383383
callOpWithExceptions->setAttr("extra_attrs", extraFnAttrs);
384+
CGF.mayThrow = true;
384385

385386
CGF.callWithExceptionCtx = callOpWithExceptions;
386387
auto *invokeDest = CGF.getInvokeDest(tryOp);

clang/lib/CIR/CodeGen/CIRGenException.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ void CIRGenFunction::emitEHResumeBlock(bool isCleanup,
283283

284284
getBuilder().create<cir::ResumeOp>(loc, mlir::Value{}, mlir::Value{});
285285
getBuilder().restoreInsertionPoint(ip);
286+
mayThrow = true;
286287
}
287288

288289
mlir::Block *CIRGenFunction::getEHResumeBlock(bool isCleanup,

clang/lib/CIR/CodeGen/CIRGenFunction.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,28 @@ static void eraseEmptyAndUnusedBlocks(cir::FuncOp fnOp) {
634634
b->erase();
635635
}
636636

637+
static bool isInterposable(cir::FuncOp fn) {
638+
if (isInterposableLinkage(fn.getLinkage()))
639+
return true;
640+
641+
assert(!cir::MissingFeatures::getSemanticInterposition());
642+
643+
return false;
644+
}
645+
646+
static void tryMarkNoThrow(CIRGenFunction &cgf, cir::FuncOp fn) {
647+
// LLVM treats 'nounwind' on a function as part of the type, so we
648+
// can't do this on functions that can be overwritten.
649+
if (isInterposable(fn) || cgf.mayThrow)
650+
return;
651+
652+
mlir::NamedAttrList extraAttrs{fn.getExtraAttrs().getElements().getValue()};
653+
auto noThrowAttr = cir::NoThrowAttr::get(&cgf.getMLIRContext());
654+
extraAttrs.set(noThrowAttr.getMnemonic(), noThrowAttr);
655+
fn.setExtraAttrsAttr(cir::ExtraFuncAttributesAttr::get(
656+
extraAttrs.getDictionary(&cgf.getMLIRContext())));
657+
}
658+
637659
cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
638660
const CIRGenFunctionInfo &fnInfo) {
639661
assert(fn && "generating code for a null function");
@@ -780,7 +802,7 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
780802

781803
// If we haven't marked the function nothrow through other means, do a quick
782804
// pass now to see if we can.
783-
assert(!cir::MissingFeatures::tryMarkNoThrow());
805+
tryMarkNoThrow(*this, fn);
784806
}
785807

786808
eraseEmptyAndUnusedBlocks(fn);

clang/lib/CIR/CodeGen/CIRGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,10 @@ class CIRGenFunction : public CIRGenTypeCache {
512512
/// the constructor, but could be overwrriten to true if this is a coroutine.
513513
bool ShouldEmitLifetimeMarkers;
514514

515+
/// True if there are any operations in the body of the function that are
516+
/// likely to throw an exception.
517+
bool mayThrow = false;
518+
515519
using DeclMapTy = llvm::DenseMap<const clang::Decl *, Address>;
516520
/// This keeps track of the CIR allocas or globals for local C
517521
/// delcs.

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,7 @@ void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &CGF, bool isNoReturn) {
23042304
auto loc = *CGF.currSrcLoc;
23052305
insertThrowAndSplit(builder, loc, mlir::Value{}, mlir::FlatSymbolRefAttr{},
23062306
mlir::FlatSymbolRefAttr{});
2307+
CGF.mayThrow = true;
23072308
} else {
23082309
llvm_unreachable("NYI");
23092310
}
@@ -2370,6 +2371,8 @@ void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &CGF,
23702371
// Now throw the exception.
23712372
mlir::Location loc = CGF.getLoc(E->getSourceRange());
23722373
insertThrowAndSplit(builder, loc, exceptionPtr, typeInfo.getSymbol(), dtor);
2374+
2375+
CGF.mayThrow = true;
23732376
}
23742377

23752378
mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(

clang/test/CIR/CodeGen/try-catch-dtors.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -324,22 +324,21 @@ void bar() {
324324
// CIR-LABEL: @_Z3barv
325325
// CIR: %[[V0:.*]] = cir.alloca !rec_A, !cir.ptr<!rec_A>, ["a"] {alignment = 1 : i64}
326326
// CIR: %[[V1:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init] {alignment = 4 : i64}
327-
// CIR: %[[V2:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp.try.call.res"] {alignment = 4 : i64}
328-
// CIR: cir.try synthetic cleanup {
329-
// CIR: %[[V4:.*]] = cir.call exception @_Z3foov() : () -> !s32i cleanup {
330-
// CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr<!rec_A>) -> () extra(#fn_attr)
331-
// CIR: cir.yield
332-
// CIR: }
333-
// CIR: cir.store{{.*}} %[[V4]], %[[V2]] : !s32i, !cir.ptr<!s32i>
334-
// CIR: cir.yield
335-
// CIR: } catch [#cir.unwind {
336-
// CIR: cir.resume
337-
// CIR: }]
338-
// CIR: %[[V3:.*]] = cir.load{{.*}} %[[V2]] : !cir.ptr<!s32i>, !s32i
339-
// CIR: cir.store{{.*}} %[[V3]], %[[V1]] : !s32i, !cir.ptr<!s32i>
340-
// CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr<!rec_A>) -> () extra(#fn_attr)
327+
// CIR: %[[V2:.*]] = cir.call @_Z3foov() : () -> !s32i
328+
// CIR: cir.store align(4) %[[V2]], %[[V1]] : !s32i, !cir.ptr<!s32i>
329+
// CIR: cir.call @_ZN1AD2Ev(%[[V0]]) : (!cir.ptr<!rec_A>) -> ()
341330
// CIR: cir.return
342331

332+
// LLVM: ; Function Attrs: noinline nounwind optnone
333+
// LLVM-NEXT: _Z3foo
334+
// LLVM: @_Z3barv()
335+
// LLVM: %[[V1:.*]] = alloca %struct.A, i64 1, align 1
336+
// LLVM: %[[V2:.*]] = alloca i32, i64 1, align 4
337+
// LLVM: %[[V3:.*]] = call i32 @_Z3foov()
338+
// LLVM: store i32 %[[V3]], ptr %[[V2]], align 4
339+
// LLVM: call void @_ZN1AD2Ev(ptr %[[V1]])
340+
// LLVM: ret void
341+
343342
class C {
344343
public:
345344
~C();

0 commit comments

Comments
 (0)