[llvm] r253908 - [WinEH] Fix a case where GVN could incorrectly PRE a load into an EH pad.

Andrew Kaylor via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 23 11:51:42 PST 2015


Author: akaylor
Date: Mon Nov 23 13:51:41 2015
New Revision: 253908

URL: http://llvm.org/viewvc/llvm-project?rev=253908&view=rev
Log:
[WinEH] Fix a case where GVN could incorrectly PRE a load into an EH pad.

Differential Revision: http://reviews.llvm.org/D14842


Modified:
    llvm/trunk/lib/Transforms/Scalar/GVN.cpp
    llvm/trunk/test/Transforms/GVN/pre-load.ll

Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=253908&r1=253907&r2=253908&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Mon Nov 23 13:51:41 2015
@@ -1555,6 +1555,16 @@ bool GVN::PerformLoadPRE(LoadInst *LI, A
   for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
        PI != E; ++PI) {
     BasicBlock *Pred = *PI;
+
+    // If any predecessor block is an EH pad that does not allow non-PHI
+    // instructions before the terminator, we can't PRE the load.
+    if (Pred->getTerminator()->isEHPad()) {
+      DEBUG(dbgs()
+            << "COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
+            << Pred->getName() << "': " << *LI << '\n');
+      return false;
+    }
+
     if (IsValueFullyAvailableInBlock(Pred, FullyAvailableBlocks, 0)) {
       continue;
     }

Modified: llvm/trunk/test/Transforms/GVN/pre-load.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GVN/pre-load.ll?rev=253908&r1=253907&r2=253908&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GVN/pre-load.ll (original)
+++ llvm/trunk/test/Transforms/GVN/pre-load.ll Mon Nov 23 13:51:41 2015
@@ -389,3 +389,50 @@ block5:
 ; CHECK: block4:
 ; CHECK-NEXT: phi i32
 }
+
+declare void @f()
+declare void @g(i32)
+declare i32 @__CxxFrameHandler3(...)
+
+; Test that loads aren't PRE'd into EH pads.
+define void @test12(i32* %p) personality i32 (...)* @__CxxFrameHandler3 {
+; CHECK-LABEL: @test12(
+block1:
+  invoke void @f()
+          to label %block2 unwind label %catch
+
+block2:
+  invoke void @f()
+          to label %block3 unwind label %cleanup
+
+block3:
+  ret void
+
+catch:
+  %c = catchpad []
+    to label %catch.dispatch unwind label %catchend
+
+catch.dispatch:
+  catchret %c to label %block2
+
+; CHECK: catchend:
+; CHECK-NOT: load
+; CHECK-NEXT: catchendpad
+catchend:
+  catchendpad unwind label %cleanup2
+
+cleanup:
+  %c1 = cleanuppad []
+  store i32 0, i32* %p
+  cleanupret %c1 unwind label %cleanup2
+
+; CHECK: cleanup2:
+; CHECK-NOT: phi
+; CHECK-NEXT: %c2 = cleanuppad []
+; CHECK-NEXT: %NOTPRE = load i32, i32* %p
+cleanup2:
+  %c2 = cleanuppad []
+  %NOTPRE = load i32, i32* %p
+  call void @g(i32 %NOTPRE)
+  cleanupret %c2 unwind to caller
+}




More information about the llvm-commits mailing list