[llvm] r282967 - [SEH] Emit the parent frame offset label even if there are no funclets
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 30 15:10:13 PDT 2016
Author: rnk
Date: Fri Sep 30 17:10:12 2016
New Revision: 282967
URL: http://llvm.org/viewvc/llvm-project?rev=282967&view=rev
Log:
[SEH] Emit the parent frame offset label even if there are no funclets
This avoids errors about references to undefined local labels from
unreferenced filter functions.
Fixes (sort of) PR30431
Added:
llvm/trunk/test/CodeGen/X86/seh-no-invokes.ll
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=282967&r1=282966&r2=282967&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Fri Sep 30 17:10:12 2016
@@ -72,17 +72,21 @@ void WinException::beginFunction(const M
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
- const Function *Per = nullptr;
- if (F->hasPersonalityFn())
- Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
- bool forceEmitPersonality =
- F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
- F->needsUnwindTableEntry();
+ EHPersonality Per = EHPersonality::Unknown;
+ const Function *PerFn = nullptr;
+ if (F->hasPersonalityFn()) {
+ PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ Per = classifyEHPersonality(PerFn);
+ }
+
+ bool forceEmitPersonality = F->hasPersonalityFn() &&
+ !isNoOpWithoutInvoke(Per) &&
+ F->needsUnwindTableEntry();
shouldEmitPersonality =
forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
- PerEncoding != dwarf::DW_EH_PE_omit && Per);
+ PerEncoding != dwarf::DW_EH_PE_omit && PerFn);
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
shouldEmitLSDA = shouldEmitPersonality &&
@@ -90,7 +94,16 @@ void WinException::beginFunction(const M
// If we're not using CFI, we don't want the CFI or the personality, but we
// might want EH tables if we had EH pads.
- if (!Asm->MAI->usesWindowsCFI() || (!MF->hasWinCFI() && !Per)) {
+ if (!Asm->MAI->usesWindowsCFI() || (!MF->hasWinCFI() && !PerFn)) {
+ if (Per == EHPersonality::MSVC_X86SEH && !hasEHFunclets) {
+ // If this is 32-bit SEH and we don't have any funclets (really invokes),
+ // make sure we emit the parent offset label. Some unreferenced filter
+ // functions may still refer to it.
+ const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
+ StringRef FLinkageName =
+ GlobalValue::getRealLinkageName(MF->getFunction()->getName());
+ emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
+ }
shouldEmitLSDA = hasEHFunclets;
shouldEmitPersonality = false;
return;
@@ -108,7 +121,7 @@ void WinException::endFunction(const Mac
const Function *F = MF->getFunction();
EHPersonality Per = EHPersonality::Unknown;
if (F->hasPersonalityFn())
- Per = classifyEHPersonality(F->getPersonalityFn());
+ Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
// Get rid of any dead landing pads if we're not using funclets. In funclet
// schemes, the landing pad is not actually reachable. It only exists so
@@ -207,9 +220,7 @@ void WinException::beginFunclet(const Ma
TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI);
// Classify the personality routine so that we may reason about it.
- EHPersonality Per = EHPersonality::Unknown;
- if (F->hasPersonalityFn())
- Per = classifyEHPersonality(F->getPersonalityFn());
+ EHPersonality Per = classifyEHPersonality(PerFn);
// Do not emit a .seh_handler directive if it is a C++ cleanup funclet.
if (Per != EHPersonality::MSVC_CXX ||
@@ -227,7 +238,7 @@ void WinException::endFunclet() {
const Function *F = Asm->MF->getFunction();
EHPersonality Per = EHPersonality::Unknown;
if (F->hasPersonalityFn())
- Per = classifyEHPersonality(F->getPersonalityFn());
+ Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
// The .seh_handlerdata directive implicitly switches section, push the
// current section so that we may return to it.
@@ -905,15 +916,24 @@ void WinException::emitEHRegistrationOff
// registration in order to recover the parent frame pointer. Now that we know
// we've code generated the parent, we can emit the label assignment that
// those helpers use to get the offset of the registration node.
+
+ // Compute the parent frame offset. The EHRegNodeFrameIndex will be invalid if
+ // after optimization all the invokes were eliminated. We still need to emit
+ // the parent frame offset label, but it should be garbage and should never be
+ // used.
+ int64_t Offset = 0;
+ int FI = FuncInfo.EHRegNodeFrameIndex;
+ if (FI != INT_MAX) {
+ const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
+ unsigned UnusedReg;
+ Offset = TFI->getFrameIndexReference(*Asm->MF, FI, UnusedReg);
+ }
+
MCContext &Ctx = Asm->OutContext;
MCSymbol *ParentFrameOffset =
Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
- unsigned UnusedReg;
- const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
- int64_t Offset = TFI->getFrameIndexReference(
- *Asm->MF, FuncInfo.EHRegNodeFrameIndex, UnusedReg);
- const MCExpr *MCOffset = MCConstantExpr::create(Offset, Ctx);
- Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset);
+ Asm->OutStreamer->EmitAssignment(ParentFrameOffset,
+ MCConstantExpr::create(Offset, Ctx));
}
/// Emit the language-specific data that _except_handler3 and 4 expect. This is
Added: llvm/trunk/test/CodeGen/X86/seh-no-invokes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/seh-no-invokes.ll?rev=282967&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/seh-no-invokes.ll (added)
+++ llvm/trunk/test/CodeGen/X86/seh-no-invokes.ll Fri Sep 30 17:10:12 2016
@@ -0,0 +1,76 @@
+; RUN: llc < %s | FileCheck %s
+
+; Generated with this C source:
+; static __forceinline void __cpuid() { __asm__(""); }
+; void f() {
+; __try {
+; __cpuid();
+; } __except (1) {
+; }
+; }
+
+; When running clang at -O1, we can end up deleting unreachable SEH catchpads
+; without running GlobalDCE to remove the associated filter. This used to
+; result in references to undefined labels. Now we check that we emit the
+; label. This was PR30431.
+
+; CHECK-LABEL: _f: # @f
+; CHECK: Lf$parent_frame_offset = 0
+; CHECK: retl
+
+; CHECK-LABEL: "?filt$0 at 0@f@@": # @"\01?filt$0 at 0@f@@"
+; CHECK: movl $Lf$parent_frame_offset,
+
+; ModuleID = 't.c'
+source_filename = "t.c"
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i386-pc-windows-msvc19.0.24210"
+
+define void @f() #0 personality i8* bitcast (i32 (...)* @_except_handler3 to i8*) {
+__try.cont:
+ %__exception_code = alloca i32, align 4
+ call void (...) @llvm.localescape(i32* nonnull %__exception_code)
+ call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() #3, !srcloc !1
+ ret void
+}
+
+; Function Attrs: nounwind
+define internal i32 @"\01?filt$0 at 0@f@@"() #1 {
+entry:
+ %0 = tail call i8* @llvm.frameaddress(i32 1)
+ %1 = tail call i8* @llvm.x86.seh.recoverfp(i8* bitcast (void ()* @f to i8*), i8* %0)
+ %2 = tail call i8* @llvm.localrecover(i8* bitcast (void ()* @f to i8*), i8* %1, i32 0)
+ %__exception_code = bitcast i8* %2 to i32*
+ %3 = getelementptr inbounds i8, i8* %0, i32 -20
+ %4 = bitcast i8* %3 to { i32*, i8* }**
+ %5 = load { i32*, i8* }*, { i32*, i8* }** %4, align 4
+ %6 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %5, i32 0, i32 0
+ %7 = load i32*, i32** %6, align 4
+ %8 = load i32, i32* %7, align 4
+ store i32 %8, i32* %__exception_code, align 4
+ ret i32 1
+}
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.frameaddress(i32) #2
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.x86.seh.recoverfp(i8*, i8*) #2
+
+; Function Attrs: nounwind readnone
+declare i8* @llvm.localrecover(i8*, i8*, i32) #2
+
+declare i32 @_except_handler3(...)
+
+; Function Attrs: nounwind
+declare void @llvm.localescape(...) #3
+
+attributes #0 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind readnone }
+attributes #3 = { nounwind }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 4.0.0 (trunk 282900) (llvm/trunk 282903)"}
+!1 = !{i32 48}
More information about the llvm-commits
mailing list