aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2012-11-29 12:23:21 +0800
committerLogan Chien <loganchien@google.com>2012-11-29 12:23:21 +0800
commit01c7fa812144bcee298fbaec5efcdc782a2f1eb1 (patch)
tree9f3c5ef3a8b037f8dfc6446212e2742ab7fa54d7
parente70243fd5213e4acbf894c8e8b7b6b74cad682a7 (diff)
downloadllvm-01c7fa812144bcee298fbaec5efcdc782a2f1eb1.tar.gz
Backport ARM EHABI support.
Although we have some EHABI support since f95e4ad7, however, there is some enhanced commits after we have submit the original CL back to upstream. Thus, we are reverting some part of f95e4ad7, and backport upstream r167633 and r167904. Change-Id: I3976b3a15410078803372b735bdaee27dc84a5e0
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h6
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h19
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h13
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp9
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp12
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp15
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h6
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp70
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.cpp15
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h5
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp24
-rw-r--r--lib/Target/X86/X86TargetObjectFile.cpp8
-rw-r--r--lib/Target/X86/X86TargetObjectFile.h6
-rw-r--r--test/CodeGen/ARM/arm-ttype-target2.ll44
14 files changed, 143 insertions, 109 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 56a87f139a2..0f815f463d2 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -377,10 +377,8 @@ namespace llvm {
/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
- /// EmitReference - Emit a reference to a label with a specified encoding.
- ///
- void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
- void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
+ /// EmitTTypeReference - Emit reference to a ttype global with a specified encoding.
+ void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of
/// its section. This can be done with a special directive if the target
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 9849e92f7de..f1b3065e7c2 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -55,13 +55,12 @@ public:
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const;
- /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference
- /// to the specified global variable from exception handling information.
- ///
+ /// getTTypeGlobalReference - Return an MCExpr to use for a reference to the
+ /// specified type info global variable from exception handling information.
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
@@ -103,12 +102,12 @@ public:
virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
Mangler *) const;
- /// getExprForDwarfGlobalReference - The mach-o version of this method
+ /// getTTypeGlobalReference - The mach-o version of this method
/// defaults to returning a stub reference.
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index d631f58aab7..3d8fc685e7a 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -27,6 +27,7 @@ namespace llvm {
class MCExpr;
class MCSection;
class MCSymbol;
+ class MCSymbolRefExpr;
class MCStreamer;
class GlobalValue;
class TargetMachine;
@@ -107,13 +108,13 @@ public:
return 0;
}
- /// getExprForDwarfGlobalReference - Return an MCExpr to use for a reference
+ /// getTTypeGlobalReference - Return an MCExpr to use for a reference
/// to the specified global variable from exception handling information.
///
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to .cfi_personality.
virtual MCSymbol *
@@ -122,8 +123,8 @@ public:
///
const MCExpr *
- getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
+ MCStreamer &Streamer) const;
virtual const MCSection *
getStaticCtorSection(unsigned Priority = 65535) const {
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 9e2f59e5a1b..2197836c399 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -97,12 +97,3 @@ void ARMException::EndFunction() {
Asm->OutStreamer.EmitFnEnd();
}
-
-void ARMException::EmitTypeInfoReference(const GlobalVariable *GV,
- unsigned TTypeEncoding) {
- if (GV) {
- Asm->OutStreamer.EmitRawText("\t.word\t" + GV->getName() + "(TARGET2)\n");
- } else {
- Asm->OutStreamer.EmitRawText(Twine("\t.word\t0\n"));
- }
-}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 90d511cbab0..a33048df31c 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -119,19 +119,11 @@ unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
}
}
-void AsmPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
+void AsmPrinter::EmitTTypeReference(const GlobalValue *GV, unsigned Encoding)const{
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
const MCExpr *Exp =
- TLOF.getExprForDwarfReference(Sym, Encoding, OutStreamer);
- OutStreamer.EmitAbsValue(Exp, GetSizeOfEncodedValue(Encoding));
-}
-
-void AsmPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
- const TargetLoweringObjectFile &TLOF = getObjFileLowering();
-
- const MCExpr *Exp =
- TLOF.getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, OutStreamer);
+ TLOF.getTTypeGlobalReference(GV, Mang, MMI, Encoding, OutStreamer);
OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0);
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 7d58102f5ba..03ce37ffa5a 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -684,7 +684,11 @@ void DwarfException::EmitExceptionTable() {
const GlobalVariable *GV = *I;
if (VerboseAsm)
Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
- EmitTypeInfoReference(GV, TTypeEncoding);
+ if (GV)
+ Asm->EmitTTypeReference(GV, TTypeEncoding);
+ else
+ Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding),
+ 0);
}
// Emit the Exception Specifications.
@@ -708,15 +712,6 @@ void DwarfException::EmitExceptionTable() {
Asm->EmitAlignment(2);
}
-void DwarfException::EmitTypeInfoReference(const GlobalVariable *GV,
- unsigned TTypeEncoding) {
- if (GV)
- Asm->EmitReference(GV, TTypeEncoding);
- else
- Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding),
- 0);
-}
-
/// EndModule - Emit all exception information that should come after the
/// content.
void DwarfException::EndModule() {
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index f361d3601ea..b5f86ab1b95 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -138,9 +138,6 @@ public:
/// EndFunction - Gather and emit post-function exception information.
virtual void EndFunction();
-
- virtual void EmitTypeInfoReference(const GlobalVariable *GV,
- unsigned TTypeEncoding);
};
class DwarfCFIException : public DwarfException {
@@ -206,9 +203,6 @@ public:
/// EndFunction - Gather and emit post-function exception information.
virtual void EndFunction();
-
- virtual void EmitTypeInfoReference(const GlobalVariable *GV,
- unsigned TTypeEncoding);
};
class Win64Exception : public DwarfException {
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 840d2330c70..4ec8ba59a72 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -87,6 +87,36 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer,
Streamer.EmitSymbolValue(Sym, Size);
}
+const MCExpr *TargetLoweringObjectFileELF::
+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
+
+ if (Encoding & dwarf::DW_EH_PE_indirect) {
+ MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ SmallString<128> Name;
+ Mang->getNameWithPrefix(Name, GV, true);
+ Name += ".DW.stub";
+
+ // Add information about the stub reference to ELFMMI so that the stub
+ // gets emitted by the asmprinter.
+ MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
+ MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
+ if (StubSym.getPointer() == 0) {
+ MCSymbol *Sym = Mang->getSymbol(GV);
+ StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
+ }
+
+ return TargetLoweringObjectFile::
+ getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()),
+ Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
+ }
+
+ return TargetLoweringObjectFile::
+ getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer);
+}
+
static SectionKind
getELFKindForNamedSection(StringRef Name, SectionKind K) {
// N.B.: The defaults used in here are no the same ones used in MC.
@@ -312,35 +342,6 @@ getSectionForConstant(SectionKind Kind) const {
return DataRelROSection;
}
-const MCExpr *TargetLoweringObjectFileELF::
-getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI,
- unsigned Encoding, MCStreamer &Streamer) const {
-
- if (Encoding & dwarf::DW_EH_PE_indirect) {
- MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
-
- SmallString<128> Name;
- Mang->getNameWithPrefix(Name, GV, true);
- Name += ".DW.stub";
-
- // Add information about the stub reference to ELFMMI so that the stub
- // gets emitted by the asmprinter.
- MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
- MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
- if (StubSym.getPointer() == 0) {
- MCSymbol *Sym = Mang->getSymbol(GV);
- StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
- }
-
- return TargetLoweringObjectFile::
- getExprForDwarfReference(SSym, Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
- }
-
- return TargetLoweringObjectFile::
- getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
-}
-
const MCSection *
TargetLoweringObjectFileELF::getStaticCtorSection(unsigned Priority) const {
// The default scheme is .ctor / .dtor, so we have to invert the priority
@@ -601,9 +602,9 @@ shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *Mang) const {
}
const MCExpr *TargetLoweringObjectFileMachO::
-getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const {
+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
// The mach-o version of this method defaults to returning a stub reference.
if (Encoding & DW_EH_PE_indirect) {
@@ -626,11 +627,12 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
}
return TargetLoweringObjectFile::
- getExprForDwarfReference(SSym, Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
+ getTTypeReference(MCSymbolRefExpr::Create(SSym, getContext()),
+ Encoding & ~dwarf::DW_EH_PE_indirect, Streamer);
}
return TargetLoweringObjectFile::
- getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
+ getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer);
}
MCSymbol *TargetLoweringObjectFileMachO::
diff --git a/lib/Target/ARM/ARMTargetObjectFile.cpp b/lib/Target/ARM/ARMTargetObjectFile.cpp
index 3d85ca7d699..047e1948002 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.cpp
+++ b/lib/Target/ARM/ARMTargetObjectFile.cpp
@@ -10,10 +10,12 @@
#include "ARMTargetObjectFile.h"
#include "ARMSubtarget.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ELF.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
using namespace dwarf;
@@ -38,3 +40,14 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx,
0,
SectionKind::getMetadata());
}
+
+const MCExpr *ARMElfTargetObjectFile::
+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
+ assert(Encoding == DW_EH_PE_absptr && "Can handle absptr encoding only");
+
+ return MCSymbolRefExpr::Create(Mang->getSymbol(GV),
+ MCSymbolRefExpr::VK_ARM_TARGET2,
+ getContext());
+}
diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h
index c6a7261439d..1cae67ea7f6 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/lib/Target/ARM/ARMTargetObjectFile.h
@@ -28,6 +28,11 @@ public:
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
+ const MCExpr *
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
+
virtual const MCSection *getAttributesSection() const {
return AttributesSection;
}
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 2570e0d0972..65252a8beca 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -285,35 +285,35 @@ TargetLoweringObjectFile::getSectionForConstant(SectionKind Kind) const {
return DataSection;
}
-/// getExprForDwarfGlobalReference - Return an MCExpr to use for a
+/// getTTypeGlobalReference - Return an MCExpr to use for a
/// reference to the specified global variable from exception
/// handling information.
const MCExpr *TargetLoweringObjectFile::
-getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const {
- const MCSymbol *Sym = Mang->getSymbol(GV);
- return getExprForDwarfReference(Sym, Encoding, Streamer);
+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
+ const MCSymbolRefExpr *Ref =
+ MCSymbolRefExpr::Create(Mang->getSymbol(GV), getContext());
+
+ return getTTypeReference(Ref, Encoding, Streamer);
}
const MCExpr *TargetLoweringObjectFile::
-getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding,
- MCStreamer &Streamer) const {
- const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext());
-
+getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
+ MCStreamer &Streamer) const {
switch (Encoding & 0x70) {
default:
report_fatal_error("We do not support this DWARF encoding yet!");
case dwarf::DW_EH_PE_absptr:
// Do nothing special
- return Res;
+ return Sym;
case dwarf::DW_EH_PE_pcrel: {
// Emit a label to the streamer for the current position. This gives us
// .-foo addressing.
MCSymbol *PCSym = getContext().CreateTempSymbol();
Streamer.EmitLabel(PCSym);
const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, getContext());
- return MCBinaryExpr::CreateSub(Res, PC, getContext());
+ return MCBinaryExpr::CreateSub(Sym, PC, getContext());
}
}
}
diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp
index b8d673facc8..b8b76b0df76 100644
--- a/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/lib/Target/X86/X86TargetObjectFile.cpp
@@ -22,9 +22,9 @@ using namespace llvm;
using namespace dwarf;
const MCExpr *X8664_MachoTargetObjectFile::
-getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const {
+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const {
// On Darwin/X86-64, we can reference dwarf symbols with foo@GOTPCREL+4, which
// is an indirect pc-relative reference.
@@ -37,7 +37,7 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
}
return TargetLoweringObjectFileMachO::
- getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, Streamer);
+ getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer);
}
MCSymbol *X8664_MachoTargetObjectFile::
diff --git a/lib/Target/X86/X86TargetObjectFile.h b/lib/Target/X86/X86TargetObjectFile.h
index 7698b59d69a..4bd5766ae68 100644
--- a/lib/Target/X86/X86TargetObjectFile.h
+++ b/lib/Target/X86/X86TargetObjectFile.h
@@ -21,9 +21,9 @@ namespace llvm {
class X8664_MachoTargetObjectFile : public TargetLoweringObjectFileMachO {
public:
virtual const MCExpr *
- getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
- MachineModuleInfo *MMI, unsigned Encoding,
- MCStreamer &Streamer) const;
+ getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
+ MachineModuleInfo *MMI, unsigned Encoding,
+ MCStreamer &Streamer) const;
// getCFIPersonalitySymbol - The symbol that gets passed to
// .cfi_personality.
diff --git a/test/CodeGen/ARM/arm-ttype-target2.ll b/test/CodeGen/ARM/arm-ttype-target2.ll
new file mode 100644
index 00000000000..8b5087f89c0
--- /dev/null
+++ b/test/CodeGen/ARM/arm-ttype-target2.ll
@@ -0,0 +1,44 @@
+; RUN: llc -mtriple=armv7-none-linux-gnueabi -arm-enable-ehabi -arm-enable-ehabi-descriptors < %s | FileCheck %s
+
+@_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
+@_ZTS3Foo = linkonce_odr constant [5 x i8] c"3Foo\00"
+@_ZTI3Foo = linkonce_odr unnamed_addr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8** @_ZTVN10__cxxabiv117__class_type_infoE, i32 2) to i8*), i8* getelementptr inbounds ([5 x i8]* @_ZTS3Foo, i32 0, i32 0) }
+
+define i32 @main() {
+entry:
+ invoke void @_Z3foov()
+ to label %return unwind label %lpad
+
+lpad: ; preds = %entry
+ %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ catch i8* bitcast ({ i8*, i8* }* @_ZTI3Foo to i8*)
+ %1 = extractvalue { i8*, i32 } %0, 1
+ %2 = tail call i32 @llvm.eh.typeid.for(i8* bitcast ({ i8*, i8* }* @_ZTI3Foo to i8*)) nounwind
+; CHECK: _ZTI3Foo(target2)
+
+ %matches = icmp eq i32 %1, %2
+ br i1 %matches, label %catch, label %eh.resume
+
+catch: ; preds = %lpad
+ %3 = extractvalue { i8*, i32 } %0, 0
+ %4 = tail call i8* @__cxa_begin_catch(i8* %3) nounwind
+ tail call void @__cxa_end_catch()
+ br label %return
+
+return: ; preds = %entry, %catch
+ %retval.0 = phi i32 [ 1, %catch ], [ 0, %entry ]
+ ret i32 %retval.0
+
+eh.resume: ; preds = %lpad
+ resume { i8*, i32 } %0
+}
+
+declare void @_Z3foov()
+
+declare i32 @__gxx_personality_v0(...)
+
+declare i32 @llvm.eh.typeid.for(i8*) nounwind readnone
+
+declare i8* @__cxa_begin_catch(i8*)
+
+declare void @__cxa_end_catch()