aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-11-22 13:13:16 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-11-22 13:13:16 +0000
commit3b7b209bf86d3e81d61cc195020bd4891467291b (patch)
tree7a2f3a96b8ef654ee5c838936f3013b7cb5b004f /test
parent5745fbce1674b29f4dce6b6e31556c4c1e83dc89 (diff)
downloadexternal_llvm-3b7b209bf86d3e81d61cc195020bd4891467291b.zip
external_llvm-3b7b209bf86d3e81d61cc195020bd4891467291b.tar.gz
external_llvm-3b7b209bf86d3e81d61cc195020bd4891467291b.tar.bz2
Fix a devilish miscompile exposed by block placement. The
updateTerminator code didn't correctly handle EH terminators in one very specific case. AnalyzeBranch would find no terminator instruction, and so the fallback in updateTerminator is to assume fallthrough. This is correct, but the destination of the fallthrough was assumed to be the first successor. This is *almost always* true, but in certain cases the loop transformations will cause the landing pad to be the first successor! Instead of this brittle logic, actually look through the successors for a non-landing-pad accessor, and to assert if more than one is found. This will hopefully fix some (if not all) of the self host miscompiles with block placement. Thanks to Benjamin Kramer for reporting, Nick Lewycky for an initial stab at a reduction, and Duncan for endless advice on EH (which I know nothing about) as well as reviewing the actual fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145062 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CodeGen/X86/block-placement.ll28
1 files changed, 28 insertions, 0 deletions
diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll
index 7361ae4..8a8bf13 100644
--- a/test/CodeGen/X86/block-placement.ll
+++ b/test/CodeGen/X86/block-placement.ll
@@ -475,3 +475,31 @@ exit:
}
!2 = metadata !{metadata !"branch_weights", i32 3, i32 1}
+
+declare i32 @__gxx_personality_v0(...)
+
+define void @test_eh_lpad_successor() {
+; Some times the landing pad ends up as the first successor of an invoke block.
+; When this happens, a strange result used to fall out of updateTerminators: we
+; didn't correctly locate the fallthrough successor, assuming blindly that the
+; first one was the fallthrough successor. As a result, we would add an
+; erroneous jump to the landing pad thinking *that* was the default successor.
+; CHECK: test_eh_lpad_successor
+; CHECK: %entry
+; CHECK-NOT: jmp
+; CHECK: %loop
+
+entry:
+ invoke i32 @f() to label %preheader unwind label %lpad
+
+preheader:
+ br label %loop
+
+lpad:
+ %lpad.val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+ cleanup
+ resume { i8*, i32 } %lpad.val
+
+loop:
+ br label %loop
+}