From 37497377a80f86709b7b3934c2aeca0b527617ca Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 22 Jan 2015 02:25:56 +0000 Subject: [PATCH] SEH: Emit the constant filter 1 as a catch-all Minor optimization of code like __try { ... } __except(1) { ... }. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@226766 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGException.cpp | 12 ++++++++++++ test/CodeGen/exceptions-seh.c | 12 +++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 94cfca962d..68764e9260 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -1839,6 +1839,18 @@ void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) { SEHExceptStmt *Except = S.getExceptHandler(); assert(Except); EHCatchScope *CatchScope = EHStack.pushCatch(1); + + // If the filter is known to evaluate to 1, then we can use the clause "catch + // i8* null". + llvm::Constant *C = + CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this); + if (C && C->isOneValue()) { + CatchScope->setCatchAllHandler(0, createBasicBlock("__except")); + return; + } + + // In general, we have to emit an outlined filter function. Use the function + // in place of the RTTI typeinfo global that C++ EH uses. CodeGenFunction FilterCGF(CGM, /*suppressNewContext=*/true); llvm::Function *FilterFunc = FilterCGF.GenerateSEHFilterFunction(*this, *Except); diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c index ebf1cfbb2b..bba5eac36c 100644 --- a/test/CodeGen/exceptions-seh.c +++ b/test/CodeGen/exceptions-seh.c @@ -26,13 +26,11 @@ int safe_div(int numerator, int denominator, int *res) { // // CHECK: [[lpad]] // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) -// CHECK: %[[sel:[^ ]*]] = load i32* -// CHECK: %[[filt_id:[^ ]*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@safe_div@@" to i8*)) -// CHECK: %[[matches:[^ ]*]] = icmp eq i32 %[[sel]], %[[filt_id]] -// CHECK: br i1 %[[matches]], label %[[except_bb:[^ ]*]], label %{{.*}} -// -// CHECK: [[except_bb]] -// CHECK: store i32 -42, i32* %[[success:[^ ]*]] +// CHECK-NEXT: catch i8* null +// CHECK-NOT: br i1 +// CHECK: br label %[[except:[^ ]*]] +// CHECK: [[except]] +// CHECK-NEXT: store i32 -42, i32* %[[success:[^ ]*]] // // CHECK: %[[res:[^ ]*]] = load i32* %[[success]] // CHECK: ret i32 %[[res]] -- 2.40.0