llvm.org GIT mirror llvm / 09450da
[SEH] Push reloads of the SEH code past phi nodes This in turn would sometimes introduce new cleanupblocks that didn't previously exist. The uses were being introduced by SSA value demotion. We actually want to *promote* uses of EH pointers and selectors, so I added some spcecial casing to avoid demoting such instructions. This is getting overly complicated, but hopefully we'll come along and delete it in the new representation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241950 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
2 changed file(s) with 119 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
615615 // identifyEHBlocks() should have been called before this function.
616616 assert(!NormalBlocks.empty());
617617
618 // Try to avoid demoting EH pointer and selector values. They get in the way
619 // of our pattern matching.
620 SmallPtrSet EHVals;
621 for (BasicBlock &BB : F) {
622 LandingPadInst *LP = BB.getLandingPadInst();
623 if (!LP)
624 continue;
625 EHVals.insert(LP);
626 for (User *U : LP->users()) {
627 auto *EI = dyn_cast(U);
628 if (!EI)
629 continue;
630 EHVals.insert(EI);
631 for (User *U2 : EI->users()) {
632 if (auto *PN = dyn_cast(U2))
633 EHVals.insert(PN);
634 }
635 }
636 }
637
618638 SetVector ArgsToDemote;
619639 SetVector InstrsToDemote;
620640 for (BasicBlock &BB : F) {
640660 continue;
641661 }
642662
663 // Don't demote EH values.
643664 auto *OpI = cast(Op);
665 if (EHVals.count(OpI))
666 continue;
667
644668 BasicBlock *OpBB = OpI->getParent();
645669 // If a value is produced and consumed in the same BB, we don't need to
646670 // demote it.
821845 LPad->replaceAllUsesWith(UndefValue::get(LPad->getType()));
822846
823847 // Rewrite uses of the exception pointer to loads of an alloca.
824 for (Instruction *E : SEHCodeUses) {
848 while (!SEHCodeUses.empty()) {
849 Instruction *E = SEHCodeUses.pop_back_val();
825850 SmallVector Uses;
826851 for (Use &U : E->uses())
827852 Uses.push_back(&U);
829854 auto *I = cast(U->getUser());
830855 if (isa(I))
831856 continue;
832 LoadInst *LI;
833857 if (auto *Phi = dyn_cast(I))
834 LI = new LoadInst(SEHExceptionCodeSlot, "sehcode", false,
835 Phi->getIncomingBlock(*U)->getTerminator());
858 SEHCodeUses.push_back(Phi);
836859 else
837 LI = new LoadInst(SEHExceptionCodeSlot, "sehcode", false, I);
838 U->set(LI);
860 U->set(new LoadInst(SEHExceptionCodeSlot, "sehcode", false, I));
839861 }
840862 E->replaceAllUsesWith(UndefValue::get(E->getType()));
841863 E->eraseFromParent();
0 ; RUN: opt -winehprepare -S < %s | FileCheck %s
1
2 ; WinEHPrepare was crashing during phi demotion.
3
4 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-pc-windows-msvc18.0.0"
6
7 declare i32 @__C_specific_handler(...)
8
9 @str = linkonce_odr unnamed_addr constant [16 x i8] c"caught it! %lx\0A\00", align 1
10
11 declare void @maycrash()
12 declare void @finally(i1 %abnormal)
13 declare i32 @printf(i8* nocapture readonly, ...)
14 declare i32 @llvm.eh.typeid.for(i8*)
15
16 ; Function Attrs: nounwind uwtable
17 define void @doit() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
18 entry:
19 invoke void @maycrash()
20 to label %invoke.cont unwind label %lpad.1
21
22 invoke.cont: ; preds = %entry
23 invoke void @maycrash()
24 to label %__try.cont unwind label %lpad
25
26 lpad: ; preds = %entry
27 %lp0 = landingpad { i8*, i32 }
28 cleanup
29 catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@doit@@" to i8*)
30 %ehptr.0 = extractvalue { i8*, i32 } %lp0, 0
31 %ehsel.0 = extractvalue { i8*, i32 } %lp0, 1
32 call void @finally(i1 true)
33 br label %ehdispatch
34
35 lpad.1: ; preds = %invoke.cont, %lpad
36 %lp1 = landingpad { i8*, i32 }
37 catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@doit@@" to i8*)
38 %ehptr.1 = extractvalue { i8*, i32 } %lp1, 0
39 %ehsel.1 = extractvalue { i8*, i32 } %lp1, 1
40 br label %ehdispatch
41
42 ehdispatch:
43 %ehptr.2 = phi i8* [ %ehptr.0, %lpad ], [ %ehptr.1, %lpad.1 ]
44 %ehsel.2 = phi i32 [ %ehsel.0, %lpad ], [ %ehsel.1, %lpad.1 ]
45 %mysel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@doit@@" to i8*))
46 %matches = icmp eq i32 %ehsel.2, %mysel
47 br i1 %matches, label %__except, label %eh.resume
48
49 __except: ; preds = %lpad, %lpad.1
50 %t4 = ptrtoint i8* %ehptr.2 to i64
51 %t5 = trunc i64 %t4 to i32
52 %call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @str, i64 0, i64 0), i32 %t5)
53 br label %__try.cont
54
55 __try.cont: ; preds = %invoke.cont, %__except
56 call void @finally(i1 false)
57 ret void
58
59 eh.resume:
60 %ehvals0 = insertvalue { i8*, i32 } undef, i8* %ehptr.2, 0
61 %ehvals = insertvalue { i8*, i32 } %ehvals0, i32 %ehsel.2, 1
62 resume { i8*, i32 } %ehvals
63 }
64
65 define internal i32 @"\01?filt$0@0@doit@@"(i8* %exception_pointers, i8* %frame_pointer) #1 {
66 entry:
67 %0 = bitcast i8* %exception_pointers to { i32*, i8* }*
68 %1 = getelementptr inbounds { i32*, i8* }, { i32*, i8* }* %0, i32 0, i32 0
69 %2 = load i32*, i32** %1
70 %3 = load i32, i32* %2
71 %cmp = icmp eq i32 %3, -1073741819
72 %4 = zext i1 %cmp to i32
73 ret i32 %4
74 }
75
76 ; CHECK-LABEL: define void @doit()
77 ; CHECK: %lp0 = landingpad { i8*, i32 }
78 ; CHECK-NEXT: cleanup
79 ; CHECK-NEXT: catch i8*
80 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions({{.*}})
81 ; CHECK-NEXT: indirectbr i8* %{{[^,]*}}, [label %__except]
82 ;
83 ; CHECK: %lp1 = landingpad { i8*, i32 }
84 ; CHECK-NEXT: catch i8*
85 ; CHECK-NEXT: call i8* (...) @llvm.eh.actions({{.*}})
86 ; CHECK-NEXT: indirectbr i8* %{{[^,]*}}, [label %__except]
87 ;
88 ; CHECK: __except:
89 ; CHECK: call i32 @llvm.eh.exceptioncode()
90 ; CHECK: call i32 (i8*, ...) @printf